Saturday, December 18, 2010

Using Zend Controller Plugin to implement login module for RESTful Web Service

When I am designing my RESTful WS. I need to implement a login module to authenticate incoming request. Normally, in a Zend Framework based CMS project, login module is implemented as a login Action in controller. However, what I am making is a RESTful web service. I just do not want to waste CPU cycle to process any request which is not authorized to access my service. Also, RESTful web service has no requirement about MVC. In a RESTful web service, there is no even session, which is used to keep status of http request. RESTful Web service is stateless.

It is not necessary to implement my RESTful web service on the top of Zend Framework as RESTful Web service is just a simple map between CRUD operations and HTTP verbs. But, Zend Framework has handy classes like Zend_Rest_Controller and Zend_Rest_Route. Using these two classes, I can easily to implement RESTful Web service having URI template as http://hostname:port/restService/paraName1/paraValue1/paraName2/paraValue2 . In Zend Framework, there are two design patterns implemented. One is front controller design pattern. The other is MVC design pattern. Since RESTful web service is stateless and it does not need MVC pattern, implementing login module in a controller plugin module will be best seamless solution for RESTful Web service in Zend Framework. Only Zend Framework front controller pattern is involved in the processing of RESTful web service.

I regard my login module as a filter, which is well known concept in Java servlet. For my RESTful Web service, I put this filter in function void Zend_Controller_Plugin_Abstract::routeStartup (Zend_Controller_Request_Abstract $request) . Therefore, the authentication process happens even before the action dispatch will happen. Below is a simple version diagram to show the position of RESTful login module in Zend Framework dispatch process.

Thursday, December 16, 2010

Recover firewall installation on Windows 7 Home Premimum 64bit

Because of some reasons, my laptop's Windows 7 Home Preminum firewall and DHCP client service can not be started with "error 5: access is denied" message. After search, I find many persons have similar problems have to reinstall whole window system. It is really frustrated that I have to reinstall my windows and reconfigure all applications. After searching and try, I finally successfully recovered my Windows 7 system. Here are steps I follow,

1) Open a Command Prompt as administrator and run the following command to check which service failure.

a. netsh advfirewall reset
b. net start mpsdrv
c. net start bfe
d. net start mpssvc
e. regsvr32 firewallapi.dll

2) Following the instruction from Microsoft to solve the access denied error one by one.

http://support.microsoft.com/kb/943996/en-us

3) Running follow command to fix DHCP client service if DHCP still can not start.

net localgroup administrators localservice /add
net localgroup administrators networkservice /add

4) Open windows event viewer check system log and make sure there is nor error message there.

I guess I got this problem because I shutdown my laptop during the process of uninstall citrix VPN client for windows 7 64bit.

Sunday, December 12, 2010

Zend Framework resource plug in and avoid using Zend_Application_Resource_Multidb in wrong way

Personally, I do not think it has significant advantage to use configuration file (application.ini) from Zend Framework because 1) I do not see big difference between PHP script file and plain text configuration file in PHP enviroment. Probably, placing configuration directly in PHP script is better in terms of performance, easy maintenance and flexible. 2) the cost of following design of Zend Framework, for example resource plugin, is that programmer has to be very careful about each components' life cycle in the system. In other words, the programmer has to understand how the thing happens insight.

Here, I have an example. I was given an authentication library as resource plugin for Zend Framework. It asks for multidb resource configuration in application.ini. It has two databases resources. The second one gets the database connection confidential parameters by calling through the first one (default db).

After checking the source code of Zend Framework. We can see that bootstrap will initialize all database adapters from multidb resource specified in application.ini. So, here is the problem. What will happen to the second database connection in multidb when bootstrap tried to initialize it without properly database connection parameters? Fortunately, Zend Framework does not really call php database connection function ( in my case db2_(p)connect) when the DB adapter is initialized. Database connection function call is only called when php script tries to get connection from DB adapter.

However, it is really confusing to specify wrong connection parameters in application.ini as multidb plugin. Then, correcting parameters in some place else. Using multidb as resource plugin might be good practice when multiple database adapters are needed in multiple places in the code and all connection parameters are known. Otherwise, it is neat to create database connection when it is needed.

Simple should be always one of main considerations of software design. Especially, for an interpret language like PHP, this could be more important.

Friday, December 3, 2010

an opened cursor can not survive between two different database connection session

I was shown a DB2 stored procedure design, which has a input parameter called "FIRST". I feel it is odd. After further enquiry, I confirm it is a wrong design.

What they expected is as below, 1) if the "FIRST" parameter is past in, it means it is the first time for calling application to call this stored procedure. 2) Therefore, the stored procedure will run and open the cursor. 3) if the "FIRST" parameter is false, it means it is not the first time for calling application to call this stored procedure. Therefore the stored procedure will "reuse" the cursor opened in the first calling.

This sounds wonderful as they told me they can avoid opening cursor frequently. Then, they can gain performance improve from it. However, I will say this is a bad design if it is not wrong because,

1) an opened cursor obviously consumes resource from DB2 server. DB2 memory cache size is limited. Furthermore, the chance for concurrency access to DB2 will be increased if each opened cursor last too long time.

2) an opened cursor should not be able to survive between two different connection session. This is actually the most risk part of this "FIRST" design because their existing Java Web app use connection pool, which can not promise always giving back same connection to servlet serving same longin customer.

So, as we can foresee, if the Web app use a different database connection to call the stored procedure without "FIRST" parameter, the stored procedure has to deal the calling as the first time call although the developer of Web app think they are "reuse" the opened cursor. In fact, the last opened cursor does not exist now.

The interesting thing is that they do not notice this problem as they configure the initialized available JDBC connection as small as one. So, the Web app is actually always using same JDBC connection although the connection is fetched from the connection pool.

So, this "FIRST" parameter for stored procedure is incorrect. The stored procedure only needs the parameters for telling stored procedure about start row and total number of rows it wants. However, in AS400 DB2 UDB, we only have function "FETCH FIRST". It does not have function like "limit", which MySQL has. However, we can use the DB2's row_num() to implement this as below,

select * from (select col1,  row_number() over() as rownum  from schemaname.tablename)end  where rownum < 10 and rownum > 6 ;