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 ;

Saturday, November 20, 2010

Do we need database constraints?

I noticed that the DB2 system belong to one project I am working on does not have any constraints set up. One of my colleagues thought it is too bad that the database does not have constraints like foreign key etc. Do we need database constraints in our system excepts the primary key, and index constraints? Well, I think there is different answers for different people who plays different roles in a software development life cycle.

According to my understanding, the constraints in relational database is constraints set up by Database Designer for Application Developer. Database designer set up the foreign key constraints, null constraints, check constraints etc. Then, developer must follow the design to avoid break constraints.

Properly setting up constraints will be helpful if developer want to use some OR mapping tools to automatically generating database abstract layer. Or, it is useful if the application will depends on RDBMS to cascade delete records. However, I do agree that it could be harmless to remove constraints like foreign key in the product environment if the application takes care of natural key very well to avoid having orphan records. I think it could pay us some performance increasing and computer resource usage decreasing as return. Probably this is the reason for MySQL did not implement foreign key constraints when it is first invented and it still become widely used?

Wednesday, November 17, 2010

Do we need WSDL to describe a RESTful Web service?

Someone shared an article written by IBM engineer (link). They want to use WSDL2.0 to describe the RESTful Web Service. I do not think it is necessary to use WSDL2.0 to describe RESTful service although WSDL2.0 can do that. At least, it is too early to apply this idea into real project before it is widely adopted in industry and code generating tool is given.

First of all, one of major reason for us to use RESTful is that RESTful is simpler than SOAP. In other words, RESTful is more about expose resource through Web server. SOAP based WS serves more as RPC. RESTful and SOAP have different design styles and they focus on different application domain. RESTful is mainly used to execute CRUD methods over HTTP with verb POST, GET, PUT, DELETE respectively. So, RESTful did not use WSDL to describe its service from the begin.

Secondly, there is no handy tool like WSDL2Java or WSDL2PHP for converting RESTful WSDL to be a computing code. Axis2 probably convert RESTful request into WSDL internally before it will further process the request. But, this happens internally.

Thirdly, since RESTful is simple. We can mainly use totally four diagrams to describe a RESTful service. Since we can make a human reading friendly document, why do we need to "go back" to WSDL, which is not fully understood by many programmer. Actually, SOAP WS programmer can still code before he fully understands the WSDL as he has handy tools to help him. We can probably call WSDL as machine reading language. Below is a simple diagram example to describe a RESTful GET method to a resource.


Therefore, I do not think it is good idea to describe RESTful WS in WSDL as WSDL is a kind of machine reading language. We do not need WSDL for RESTful before we get code generating tool for converting WSDL2.0 to to real code and code to WSDL2.0.

Also, it will misguide if designer treat RESTful as a RPC. For my opinion, a designer can treat RESTful WS as static Web content from a Web server. SOAP (WSDL) based Web service services as RPC more. Therefore, a designer can see whether he can model the application as a resource or not as a start point to think about using RESTful or SOAP or other RPC protocols. So, not to think RESTful WS as a RPC will definitely help Web Service designer to keep in right rack.

Tuesday, November 9, 2010

creating RESTful service with Zend_Rest_Route and Zend_Rest_Controller

After trying different ways to make RESTful WS in Zend Framework, I am aware that I can simply use Zend_Rest_Route and ZendRest_Controller to make "standard" RESTful WS in PHP. Especially, Zend_Rest_Route supports RESTful URI pattern like /parameterName/parameterValue/.... This is different from what I read from forums. I am using Zend Framework 1.10 in Zend Server 5.0.1 running on IBM i. Zend_Rest_Server is really not good choice to make RESTful service. Zend_Rest_Server needs to be further improved to meet the requirement of "standard" RESTful.

I tried Zend_Controller_Router_Route to implemented RESTful URI pattern. But, it is easier to use Zend_Rest_Route and Zend_Rest_Controller. Actually, Zend_Rest_Controller does nothing but defines several abstract methods, which map to relevant HTTP methods. But, our RESTful controller must extend from it. Below is the sample codes. In my environment, I can access it with this URL: http://localhost/jiaRESTfulWS/public/index/product/fish/number/100/

BootStrap class
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
 //adding this function in Bootstrap class to initilize Zend_Rest_Route.
 protected function _initRestRoute() {
  //getting an instance of zend front controller.
  $frontController = Zend_Controller_Front::getInstance ();
  //initializing a Zend_Rest_Route
  $restRoute = new Zend_Rest_Route ( $frontController );
  //let all actions to use Zend_Rest_Route.
  $frontController->getRouter ()->addRoute ( 'default', $restRoute );
 }
 
}

IndexController.php
class IndexController extends Zend_Rest_Controller
{
 
 public function init() {
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true ); 
 }
 
 /**
  * The index action handles index/list requests; it should respond with a
  * list of the requested resources.
  */
 public function indexAction() {
  //HTTP code 500 might not good choice here.
  $this->getResponse ()->setHttpResponseCode ( 500 );
  $this->getResponse ()->appendBody ( "no list/index allowed" );
  
 } 
 
 /**
  * The get action handles GET requests and receives an 'id' parameter; it
  * should respond with the server resource state of the resource identified
  * by the 'id' value.
  */
 public function getAction() {  
  
  //I will return result in XML format.
  $this->getResponse ()->setHeader ( 'Content-Type', 'text/xml' );
  
  //Note: the Request object here is not HttpRequest. It is Zend controller request. This is the key!
  if ($this->getRequest ()->getParam ( "product" ) != NULL and $this->getRequest ()->getParam ( "number") != NULL ) {   
   //Initializing a dummy object for return. 
   $return = new Jia_Return ();
   $return->setProducts ( $this->getRequest ()->getParam ( "product" ) );
   $return->setQuantity ( $this->getRequest ()->getParam ( "number" ) );
   //We prevent the product has been found.
   //So, we set HTTP code 200 here.  
   $this->getResponse ()->setHttpResponseCode ( 200 );
  }    
   else {
    $return= new Jia_ErrorCode('no parameters!');
    //prevent the product is not found.
    $this->getResponse ()->setHttpResponseCode ( 200 );
   }
  
  print $this->_handleStruct( $return );
 
 }
 
 /**
  * The post action handles POST requests; it should accept and digest a
  * POSTed resource representation and persist the resource state.
  */
 public function postAction() {
  
 }
 
 /**
  * The put action handles PUT requests and receives an 'id' parameter; it
  * should update the server resource state of the resource identified by
  * the 'id' value.
  */
 public function putAction() {
 
 }
 
 /**
  * The delete action handles DELETE requests and receives an 'id'
  * parameter; it should update the server resource state of the resource
  * identified by the 'id' value.
  */
 public function deleteAction() {
 
 }
 
  
 /**
  * Handle an array or object result
  *
  * @param array|object $struct Result Value
  * @return string XML Response
  */
 protected function _handleStruct($struct) {

  $dom = new DOMDocument ( '1.0', 'UTF-8' );
  
  $root = $dom->createElement ( "Jia" );
  $method = $root;
  
  $root->setAttribute ( 'generator', 'Yiyu Blog' );
  $root->setAttribute ( 'version', '1.0' );
  $dom->appendChild ( $root );
  
  $this->_structValue ( $struct, $dom, $method );
  
  $struct = ( array ) $struct;
  if (! isset ( $struct ['status'] )) {
   $status = $dom->createElement ( 'status', 'success' );
   $method->appendChild ( $status );
  }
  return $dom->saveXML ();
 }
 
 /**
  * Recursively iterate through a struct
  *
  * Recursively iterates through an associative array or object's properties
  * to build XML response.
  *
  * @param mixed $struct
  * @param DOMDocument $dom
  * @param DOMElement $parent
  * @return void
  */
 protected function _structValue($struct, DOMDocument $dom, DOMElement $parent) {
  $struct = ( array ) $struct;
  
  foreach ( $struct as $key => $value ) {
   if ($value === false) {
    $value = 0;
   } elseif ($value === true) {
    $value = 1;
   }
   
   if (ctype_digit ( ( string ) $key )) {
    $key = 'key_' . $key;
   }
   
   if (is_array ( $value ) || is_object ( $value )) {
    $element = $dom->createElement ( $key );
    $this->_structValue ( $value, $dom, $element );
   } else {
    $element = $dom->createElement ( $key );
    $element->appendChild ( $dom->createTextNode ( $value ) );
   }
   
   $parent->appendChild ( $element );
  }
 }
 
}
Return.php
/**
 * A dummy class as return objec.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_Return {
 
 /**
  * 
  * @var unknown_type
  */
 public $products;
 public $quantity;
 /**
  * @return the $products
  */
 public function getProducts() {
  return $this->products;
 }

 /**
  * @param $products the $products to set
  */
 public function setProducts($products) {
  $this->products = $products;
 }
 /**
  * @return the $quantity
  */
 public function getQuantity() {
  return $this->quantity;
 }

 /**
  * @param $quantity the $quantity to set
  */
 public function setQuantity($quantity) {
  $this->quantity = $quantity;
 }
 
}

ErrorCode.php
/**
 * An dummy error code class.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_ErrorCode { 
 
 public $errorCode;
 
 function __construct($errMsg){
  $this->errorCode = $errMsg;
 }  

}

ZendStudio 7.2 project file can be downloaded from here.

Friday, November 5, 2010

A simple tutorial about creating Zend_Rest_Server based RESTful service.

It seems that RESTful WS is attracting more people to consider as RPC solution. Compared with SOAP based Web Service, RESTful has its advantage and disadvantage. RESTful WS is declared to be more scalability as it exactly maps HTTP methods  POST, GET, PUT, DELETE as a CRUD (Create, Request, Update, Delete) operations. So, if we design our RESTful WS as stateless, it could be more scalable in a cluster farm. It can get benefit from Cache mechanism of HTTP (limited to HTTP GET method configuration on proxy server in most time). However, it could be problem or ask for cost if we do not want the result to be cached. Furthermore, we can not always assume client Web browser has cache enabled. So, RESTful is not always right choice. Especially, it is not good choice when we develop an enterprise application which ask for complex data structure delivered between sub systems and it does not have extremely large volume of the concurrent accessing.

I will compose another post to describe my comparison about SOAP WS and RESTful WS and JSON-RPC. Here, I will show a simple demo about how to create Zend_Rest_Server based RESTful WS in Zend Studio. Zend_Rest_Server is not perfect. For instances, it can not work together with Zend_Action_Router_Route. It also asked for calling function by put "method=functionName" in requesting URL after the "?". This make some guys think it is not RESTful WS as some person said it is not good design. But, I think it is not wrong design at least.  Below is source for simple ZF based RESTful WS.
  1. Create a new ZF project in Zend Studio and name it as jiaRESTfulWS.
  2. Add autoloaderNamespaces[] = "Jia_" in application.ini to allow Zend Autoloader load Jia_* classes.
  3. Creating a action class DummyController under directory /application/controllers. 
  4. creating a function restAction() in DummyController .
  5. Creating a Jia_Hello class with sayHello($name) function under /library/Jia directory.
It is done. You need to pay attention on how to specify web service URI in the code if you use different project name and function names. Or, you might want to add alias in your apache httpd configuration file to simplify the URL. On my machine, this demo RESTful WS can be accessed with following URL: http://localhost/jiaRESTfulWS/public/index.php/Dummy/rest?method=sayHello&name=jia . See key source code as below,

Jia_Hello class
/**
 * This class contains function which will be used by Web service caller.
 * All business logics will be implented or called in these functions.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_Hello {

 /**
  * 
  * @param string $name
  * @return string
  * 
  */
 public function sayHello($name){
  return "hello ".$name;
 }
}


DummyController class
/**
 * This class includes one function restAction(), wich has Zend_Rest_Server initialized.
 * However, you can only use URI with "?" like this "/rest?method=sayHello&name=jia". You 
 * can not have URI like "/rest/name/jia"
 * 
 * @author yiyu
 *
 */
class DummyController extends Zend_Controller_Action
{
 /**
  *  action named as rest.
  */
 public function restAction() {
  
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initialize REST server
  $server = new Zend_Rest_Server();
  // set REST service class
  $server->setClass ( 'Jia_Hello' ); 
    
  // handle request
  $server->handle ();
 
 }
 
}

Zend Studio 7.2 project file can be downloaded here. Also, I do not recommend to use Zend_Rest_Server for developing RESTful WS as I think it is old and uncompleted class. Zend_Rest_Route should be a better choice to make RESTful Web Service in PHP. Here is a simple tutorial about how to use Zend_Rest_Route and Zend_Rest_Controller to create RESTful Web Service. Creating RESTful service with Zend_Rest_Route and Zend_Rest_Controller

Wednesday, November 3, 2010

upgrade Fedora 13 to Fedora 14

I have been waiting for Fedora 14 for months as Fedora 13 has screen flickers (see bug report here) on my notebook. Fedora 14 was released yesterday. I luckily upgrade my notebook from Fedora 13 to Fedora 14 without problem. I just followed the instruction from Fedora forum. I will list the command here,

1) type su to be a root user.
2) run command yum update rpm
3) run command yum -y update to make sure upgrading Fedora 13 to the latest version. If new Fedora 13 kernel is installed at this step, reboot is required.
4) run command yum clean all
5) run command yum -install preupgrade
6) run command preupgrade-cli and find the valid entry
7) run command preupgrade-cli "Fedora 14 (Laughlin)"
8) answered yes during the upgrading and waited patiently.

The only problem I got is that preupgrade GUI does not work. It shows the windows. But, I can not make selection in its drop down box. So, I use preupgrade-cli and it works. I installed both GNOME and KDE in my Fedora 13. preupgrade-cli upgraded my desktop environment too. Btw, I think we need to leave enough spare space on hard drive for upgrading as I saw somebody complain the upgrade command does not work and the error message shows the enough hard drive space.

Saturday, October 30, 2010

A discussion about asynchronous programming in PHP and further

I read an article about asynchronous programming in PHP. It declares that lacking asynchronous programming is not limitation from PHP language. However, I think this is obviously the limitation of PHP.

Lacking of multi-thread features is the source of the limitation. PHP programmers have argued that they can use named pipe, node.js, libevent, Curl, Zend_Job, and other process control extensions to implement asynchronous functions in PHP. However, these methods are not core PHP feature. Therefore, there is no guarantee that these functions can be run on all platforms on which core PHP can run. For example, I wonder whether libevent can run on IBM i platform or not. Zend Server for IBM i supports Zend_Job. But it is not in Zend Server CE, which is free. Also, some extensions like PCNTL seems a solution based on multi process with shared memory. It is a inter-process implementation. Multithreading is a inner process implementation.

This limitation of PHP is because of the way of running PHP script too. PHP is known that it has less memory leak problem. This is not surprised as each PHP script is loaded into memory only when it need to be executed. After it is executed, it is flushed out of memory. Of course, PHP has no memory leak as it has no memory at all.This is because PHP inherits from perl as CGI programming language. Somebody will argue that PHP actually has optimizers and extensions like memcache. These make PHP looks like have some memory. However, optimizer is for caching operation code. memcache is for caching some data as a persistent storage. They can not make PHP to have real memory.

Since PHP has no memory, core PHP has no function like PipedInputStream, PipedOutputStream, and multi thread etc. As I presented in an old post, its static modifier means different life scope than other languages do. So, lacking of asynchronous programming feature is the limitation from PHP itself. It is confusing to discuss PHP lacks asynchronous feature and deny it is limitation from PHP language itself.

Also, in servlet world, people has been interested in changing "request per thread" architecture because of the challenge from multiplied Ajax calling from browser side. Leading by Jetty, both Jetty and Tomcat 7.0 has implemented asynchronous servlet API already. I will deeply investigate whether PHP is facing same challenge or not. Or, with Fastcgi, PHP does not need to worry about this at all.

Thursday, October 28, 2010

tutorial about setting up multiple breakpoints for different PHP script files in Zend Studio

After trying Zend Studio 7.2 and 8.0 Beta, I have to say that Zend Studio manual does not fully describe its features. Especially, I can not find info about how to properly set up multiple breakpoints in its manual .

What happened is, after initializing a ZF project with default settings in ZS, I find that I can only make debugging break point in the first PHP script, which is /public/index.php . Zend Debugger ignores other breakpoints set in other PHP scripts, where those complex logical are implemented. After studying, I find that we need to change the default debug configurations to make multiple breakpoints to work. The steps are as below,

1) right click your project in PHP Explorer window and select Properties for properties window.
2) Select  "PHP Include Path" --> "Libraries"
3) Remove the default libraries of Zend Framework, which belong to Zend Studio.
4) Add the Zend Framework directory under your local Zend server directory as library. Now you can see the screen like below,
5) Click menu "Run" --> "Debug Configurations..." . select or create your debug configuration settings.
6) Click "Configure..." button under the "server" tab for edit server window.
7) Click "path mapping" tab and create a path mapping entry, which has exactly same path for "server path" and "local path". You will see screen as below,
8) Click "Advanced" tab on "Debug Configurations" window and select radio button "Local copy if available. Otherwise, the server".

Now, you can see that Zend Debugger can stop at breakpoints in PHP scripts other than the first page scripts.

For better understand the debugger in Zend Studio, here is one link: click.

Monday, October 25, 2010

failure on passing SQL statement as parameters into stored procedure and the way to walk around

Recently, I got code 3 error message when I tried to call a stored procedure on IBM i DB2 through System i Navigator. The purpose of this stored procedure is to perform a series queries that are passed in as the input parameter under a predefined schema.  Below is the way to call the stored procedure,
call myStoredProcedure('update dummyTbl set columnA = 1 where columnB = ''Jia''  ')

The error message says that

Message: [SQL7008] dummyTbl in schemaA not valid for 
operation. Cause . . . . . :   The reason code is 3.  
Reason codes are: 
1 -- dummyTbl has no members. 
2 -- dummyTbl has been saved with storage free. 
3 -- dummyTbl not journaled, no authority to the 
journal, or the journal state is *STANDBY.  Files 
with an RI constraint action of CASCADE, SET NULL, 
or SET DEFAULT must be journaled to the same journal. 
The interesting thing is that I get error free when I run the same SQL query in System i Navigator. 

After doing research, I found that, on IBM i DB2, a table is journaled by default if it is created with SQL statement in i Navigator. On the other hand, the table is not journaled by default when it is created under green screen. And the walking around is adding the following statement in the stored procedure before executing the input string that is actually sql statement,
SET TRANSACTION ISOLATION LEVEL NO COMMIT

This could only be temporary walking around solution. To be serious, it is better to review tables setting about journaling and isolation level. However, for an existing complex database system, this walking around might be a good choice too.

Friday, October 22, 2010

Role Based Access Control (RBAC) and Single Sign On (SSO) and Role vs Group

I attended a meeting to discuss about Single Sign On. After listening to their discussion for a while, I noticed a problem of the discussion. It sounds like they intended to implemented Role Based Access Control in the Single Sign On system. However, the problem is that they mixed RBAC and SSO during the discussion. So, I gave out my suggestion that they can put RBAC and SSO into separate discussion at this early stage.

The relationship between RBAC and SSO should be like this,
  1. When we start discussing about design of RBAC and SSO, we should discuss RBAC first. After RBAC is clearly defined. It wont be difficult to implemented it in SSO system.
  2. When we start discussing about SSO implementation, we need to oversee the whole system as a SSO system and think about how RBAC will be implemented in SSO system.
So, we will have a clear and efficient discussion when we have a clear concept about relationship between SSO and RBAC.

Another cause for them to be confused during design is that they mixed concepts about Group and Roles.  There are tons of discussion about difference Group and Roles according to general accepted definitions. Designer will be confused if he mix group and role. For this case, I noticed that they tried to define roles in ActiveDirectory as a hierarchy structure. With this starting point, they were lead to have messy concepts and can not get out of it. However, they immediately have a clear view after I told them that they can think about moving those "group" in AD into a DB2 table as Roles first. Then, they can think about how to implemented their RBAC system. Then, they can move back those roles into AD and only use AD as persistent storage if they really want to do so.

Tuesday, October 19, 2010

Web Service authentication and Http session and Web Service session

I was presented a web service client written with Zend_Soap_Client. It seems that the Web Service runs as Single Sign On service. But, it is a specific SSO invented internally. However, this WS is not protected by even simple authentication processing. When I raised this concern, I was asked "how to pass user name and password to Web Service server?". Well, I think this questions need to be divided into two parts to be answered,
  1. How to authenticate client when it access a Web Service?
  2. Is the Web Service stateful or stateless? 
Regarding the first question, authentication can happen in two different places. The first place is the WSS tag, which is in SOAP message header. The second is the HTTP authentication, which happens outside (front of) Web Service. So, it depends Web Service provider and Web Service consumer to decide where they will put the authentication info to protect the Web Service.

About the second question, I will say Web Service can be both stateful and stateless. Enabling session management in Web service will obviously increase the memory footprint. On the other hand, a stateless Web Service will require less memory. It depends on what kind of Web service it is.

I know it is wired for a programmer to input user name and password or certification file every time when it need to call each function supplied by a same Web service. I think we have to balance among computing time, memory footprint, and easy implementation. Then, we can choose whether we need a stateless WS or stateful WS. Both Axis2 and .Net Web Service can support stateful Web Service.

Thursday, October 14, 2010

Zend_Soap_Client and PHP http client do not share same native code

I was told by a senior PHP consultant that he can not successfully make Zend_Soap_Client call over the SSL. He runs his code on Zend Server running on i Series. Then, I told him that, if I were him, I will try to write a normal HTTP client to access the WSDL file over SSL first. The reason for me to approach in this way because,

  • SOAP is built on the top HTTP. So, SSL should not be business of SOAP. In other words, SOAP client shall rely on the HTTP client implement.
  • I THOUGHT that Zend_Soap_Client uses same native code as PHP http client.

However, I was wrong. He tested and found that he was able to do file_get_contents and retrieve https:// content from the server. Then, I started to trace the source code of Zend_Soap_Client. I found,
  1. Zend_Soap_Client is a wrapper around PHP SOAP extension.
  2. PHP SOAP is a thin layer. It quickly goes to native code at file called soap.php.
  3. Native c code of soap.php has its own logical to deal with proxy and SSL. Click Here to see C source code.
So, I was wrong. I can not regard that Zend_Soap_Client can support SSL just because PHP Http client can support SSL. They probably uses different version of native http client code. From this discussion, I get deeper understanding about architecture of PHP. I will probably write a article to compare Java and PHP.

BTW, PHP 5.3 version of Zend Server 5.0.2 on iSeries does not support Zend_Soap_Client to access web service over the SSL. However, Zend_Soap_Client work with SSL when the Zend Server was rolled back to version 5.0.1 . Zend_Soap_Client coming with Zend server 5.0.4 can be used to access Web service over one-way SSL. I have not tried mutual SSL with Zend_Soap_Client yet. But, it sounds not easy.

Also, to test Zend_Soap_Client access over one-way SSL can be as simple as below,

try {
 $soap_url = 'https://your.host/webservice?wsdl'; 
 
 $soap_client = new SoapClient ( $soap_url);
 
 var_dump ( $soap_client -> __getFunctions () );
 
} catch ( Exception $e ) {
 print_r ( $e );
 exit ();
}

Friday, October 8, 2010

A simple tutorial about creating Zend Framework SOAP Web service server in Zend Studio 7.2

I was studying how to create Web Service in PHP recently. I used Axis1.0, Axis2.0 to create Web service before. I used NuSoap to make a web service to call Sync4J admin service too. I like Axis' wsdl2java and java2wsdl tool set very much. In PHP, there is similar tool too. However, this time, I decide to implemented Web service under Zend Framework. After trying, I found it is quiet easy to create a simple Web service in ZF although I found that Zend_Soap_Server is not sophisticated enough to make solution for Enterprise application. For example, it does not have build in support for WS security head. It is actually a wrapper around PHP Soap extension. You can find discussion from Zend wiki by click here.

I will show steps of creating ZF based Web Service in Zend studio as below. Also, I put download link of whole ZS project at the end. We can create this simple demo project as below,
  1. Create a new ZF project in Zend Studio and name it as jiaWS.
  2. Add autoloaderNamespaces[] = "Jia_" in application.ini to allow Zend Autoloader load Jia_* classes.
  3. Creating a action class DummyController under directory /application/controllers. 
  4. creating a function soapAction() in DummyController .
  5. creating a function wsdlAction() in DummyController. 
  6. Creating a Jia_Hello class with sayHello() function under /library/Jia directory.
  7. Creating a Jia_DummyException class under /library/Jia directory for Soap fault processing.
It is done! You need to pay attention on how to specify web service URI in the code if you use different project name and function names. See key source code as below,

Jia_Hello class.
/**
 * This class contains function which will be used by Web service caller.
 * All business logics will be implented or called in these functions.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_Hello {

 /**
  * This function simply return a String when it is called.
  * Note :  the PHPDoc style comment below is very 
  * important as Zend_Soap_AutoDiscover use it to generate WSDL. 
  * 
  * @return string
  */
 public function sayHello(){
  return "hello";
 }
}

DummyController calss
/**
 * This class includes two functions. soapAction() is point called by
 * Web service client. wsdlAction() generates WSDL when it is called.
 * 
 * @author yiyu
 *
 */
class DummyController extends Zend_Controller_Action
{
 /**
  * SOAP action named as soap.
  */
 public function soapAction() {
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initialize server and set URI
  $server = new Zend_Soap_Server('http://localhost/jiaWS/public/index.php/dummy/wsdl');
  
  // set SOAP service class
  $server->setClass ( 'Jia_Hello' );
  
  // register exceptions for generating SOAP faults
  $server->registerFaultException ( array ('Jia_DummyException' ) );
  
  // handle request
  $server->handle ();
 
 }
 /**
  * function to generate WSDL.
  */
 public function wsdlAction() {
  
  //You can add Zend_Auth code here if you do not want 
  //everybody can access the WSDL file.
 
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initilizing zend autodiscover object.
  $wsdl = new Zend_Soap_AutoDiscover ();
  
  // register SOAP service class
  $wsdl->setClass ( 'Jia_Hello' );
  
  // set a SOAP action URI. here, SOAP action is 'soap' as defined above.
  $wsdl->setUri ( 'http://localhost/jiaWS/public/index.php/dummy/soap' );
  
  // handle request
  $wsdl->handle ();
 }

}


DummyClient.php
//This code is not a ZF MVC based
//So, we need to load Zend libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass ( 'Zend_Soap_Client' );

//setting options past into Zend_Soap_Client.
$options = array ('location' => 'http://localhost/jiaWS/public/index.php/dummy/soap', 'uri' => 'http://localhost/jiaWS/public/index.php/dummy/wsdl' );

try {
 //Initilizing client object
 $client = new Zend_Soap_Client ( null, $options );
 //calling the Web service function.  
 $result = $client->sayHello ();
 print_r ( $result );
} catch ( SoapFault $exp ) { //catching exception and print out.
 die ( 'ERROR: [' . $exp->faultcode . '] ' . $exp->faultstring );
} catch ( Exception $exp2 ) {
 die ( 'ERROR: ' . $exp2->getMessage () );
}

Source code as Zend Studio project can be downloaded click here

You can find a simple RESTful Web Service demo on my another post, creating RESTful service with Zend_Rest_Route and Zend_Rest_Controller.

Thursday, October 7, 2010

Zend_Soap does not have build-in support for WSS headers.

I am disappointed to find that Zend_Soap_Client does not support WSS tag. When I talked to some PHP programmers, I found that they only talk about HTTP authentication. It is true that we can protect our Web Service by putting HTTP authentication at the front of the Web service. We can further adding SSL on WS. But, all of these methods are belong to HTTP layer. In fact, Web Service standard defines security head tags for authentication and encryption purpose.

It will be disadvantage of ZF not to support WSS tags especially when other languages have supported it. In Java world, we have Axis2 and WSS4J. There are some extensions in PHP to support WSS. But I wish Zend will put WSS support in Zend_Soap soon. Otherwise, there will be doubt when we will apply Zend_Soap in enterprise application solution. I put my message in zend wiki. click here.

Wednesday, October 6, 2010

Be sure to check httpd "AllowOverride" setting for your Zend Framework app

Yesterday, I installed Zend Server CE ver 5.0.3 Windows x86 on my machine. Then, I used Zend Studio 7.2 to create a default ZF project. However, I find that I always got 404 error that means page is not found.

How can it be? Zend Studio actually put whole project files under Apache httpd's htdocs folder already. First thing I suspect is that I dont have .htaccess  file defined or it defines wrong rules? Then, I spend time on finding .htaccess file and checking its rules definition. However, it seems there is nothing wrong but my ZF application can not run!

Finally, I go to Apache httpd configuration folder and open the httpd.conf file and zend.conf file. Here, I found the problem. And it is so trivial and I feel I am stupid that I wasted time on checking .htaccess files. Zend server sets its apache httpd configuration with "AllowOverride None". Therefore, those .htaccess file I keep on checking is totally ignored by httpd! I changed it to be "AllowOverride All" and my ZF application works immediately. This is not a safe configuration. However, it is just a local web server for developing purpose. It is Ok.

I do not know whether this could be called as Zend Server's bug or not. Zend Server or Zend Studio should modify this setting for developers if they declare themselves as seamless integrated development environment for ZF developers. However, it is really not difficult for developers to correct this setting if they keep in mind of this. After getting this lesson, I think I will always remember to check this setting after I freshly install a Zend Server. 

If interested, official site to describe Apache httpd "AllowOverride" configuration is here .

Tuesday, September 28, 2010

static variable in PHP vs static variable in Java

PHP is evolving to be a Object Oriented language. As a java programmer and PHP programmer, I like to compare PHP with Java. In this post, I am going to write down my comparison about "static" modifier in PHP and Java.

PHP and Java as they have different architecture for running time environment. I feel it is necessary point out the difference between PHP static and Java static. We can investigate this from two different aspects at least: static variable scope and static variable access.

Firstly, let's see the difference about static variable scope. For Java, a static variable will survive throughout the whole life when JVM is running or when class is unloaded using some techniques. That means, once the static variable is used, it will exist in memory as long as the java application is running. And, there is only one copy of static variable in memory (in one Java class loader's scope in a JVM process). For PHP, the thing is different as PHP has no memory. That means all PHP code will be flushed out after php scripts (including all included and required php script files). So, the variables, which is even declared as "static" or "Global", will be destroyed . A PHP variable can not survive through two different script executions. Other thing we need to pay attention to is that programmer is not supposed to assign a reference to a static variable.

Secondly, let's see some difference about how to access static variables in PHP and Java.  Both Java and PHP has concepts about "class"  and "instance of class" now. A "className" is used as class in code. A "new className()" is used as instance (object) of class in code. But, I noticed a difference of calling static member in class between PHP and Java. In Java, a static variable can be referred through a instance of class though it is not encouraged. In PHP, it is not allowed to do so according to my test. Below are code snippet,

 Java code
/**
 *
 * @author Yiyu Jia
 */
public class Main {

    public static String dummy = "dummy";

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Main foo = new Main();
        //I can access the static variable through class instance
        //although this is not encouraged.
        System.out.println(foo.dummy); 
    }

}

 PHP code
class DummyClass
{
    static $jia = 'yiyu';

    function testStatic()
    {
     print(self::$jia);
     echo $this->jia; //error. Not allowed in PHP.
    }
}

Java and PHP has totally different run time environment architecture. I am going to find a good way to present the difference later.

For deeper understand about PHP static modifier, below URLs are very helpful,

1)Static keyword: http://php.net/manual/en/language.oop5.static.php


2)Variable scope: http://php.net/manual/en/language.variables.scope.php


3)Something important after PHP became a OOP: http://www.php.net/manual/en/language.references.return.php

Wednesday, September 22, 2010

simulating Cube function by using Group By in MySQL

Some commercial RDBMS like DB2 has function "cube". However, MySQL (5.1.48 on my machine) does not support cube yet. It supports rollup function. but I need cube function. So, I use a group of "group by" to simulate the cube function. It might not be the best solution. But, it should be much better than making thousands queries to calculate sum values. There are two steps in this simulating,

1) listing out all possible combination of column names. The total number of group by strings will be 2^n where n = the # of columns (dimension number).

2) run each sql select query with group by clause to get sum values, which we are interested.

Monday, September 6, 2010

Convert DBLP(XML format) to a relational DB (MySQL)

I need a data set on which my new algorithm can be tested. I am posting here the small work of converting DBLP (in XML format) into MySQL.

Data source, http://www.informatik.uni-trier.de/~ley/db/ . I downloaded its XML format file, which contain information about thousands of articles.

Target data storage, A simple database designed for MySQL. Below is the SQLs for creating table.

CREATE TABLE `DBLP`.`articles` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT  PRIMARY KEY ,
`title` VARCHAR( 250 ) NOT NULL ,
`bookTitle` VARCHAR( 150 )  NOT NULL ,
`pages` CHAR( 13 ) ,
`year` CHAR( 4 ) NOT NULL ,
`mdate`  CHAR( 10 ) NOT NULL ,
UNIQUE (
`title`
)
) ENGINE = MYISAM  ;



CREATE TABLE `DBLP`.`authors` (
`id` BIGINT UNSIGNED NOT NULL  AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 50 ) NOT NULL
UNIQUE (
`name`
)
) ENGINE =  MYISAM ;

CREATE TABLE `DBLP`.`linkTbl` (
`article_id` BIGINT  UNSIGNED NOT NULL ,
`author_id` BIGINT UNSIGNED NOT NULL ,
`position`  TINYINT UNSIGNED NOT NULL ,
INDEX ( `article_id` , `author_id` )
) ENGINE  = MYISAM ;
Then, I made a java program to access the XML file and insert each article info into new created RDBMS tables.

Java code is using xerces SAX parser to read and parse the XML file. We use SAX parser not DOM parser because the XML has very large file size. It is over 700M on the disc.

Java code is small. But it is too long to be post here. So, I am only put important SQL query in Java code here.

String articleInsertSql = "INSERT INTO `articles` (`id` ,`title` ,`bookTitle` ,`pages` ,`year` ,`mdate`)"
+ " VALUES (NULL , ?, ?, ?, ?, ?)"
+ " ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)";

String articles_lastId = "set @articleId=LAST_INSERT_ID()";

String  authorReplaceSql = "INSERT INTO `authors` (`id` ,`name`)"
+ " VALUES (NULL , ?)"
+ " ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)";

String authors_lastId = "set @authorId=LAST_INSERT_ID()";

String lookTableInsertSql = "INSERT INTO `linkTbl` (`article_id` ,`author_id` ,`position`)"
+ " VALUES (@articleId, @authorId, ?)";


Here, string articleInsertSql , articles_lastId, authorReplaceSql, authors_lastId, lookTableInsertSql are executed in PreparedStatement sequentially. Here, " ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)" can be highlighted because it let following "set @articleId=LAST_INSERT_ID()" or "set @authorId=LAST_INSERT_ID()" to assign right ID values to @articleId or @authorId .

Friday, August 13, 2010

setup simple configured SVN with httpd on Fedora 13

To write down the step of configuring my system, I am writing this post as memo.

1) install httpd and SVN
# yum install httpd subversion

2) install mod_dav_svn
# yum install httpd mod_dav_svn

3) create subversion repository
# svnadmin create /home/svn-repos/ubianalysis

4) running following command to allow apache account to access the repository directory
# chown -R apache.apache /home/svn-repos/ubianalysis

5) running the following command to update Selinux context. If command does not work, I use Selinux GUI admin tool to add this. Actually, I added this via SeLinux admin tool found in Administration menu.
# chcon -R -t httpd_sys_content_rw_t /home/svn-repos/ubianalysis

6) go to directory /etc/httpd/conf.d and add following content in subversion.conf

<Location /svn-repos >
DAV svn
SVNParentPath /home/svn-repo/
# Require SSL connection for password protection.
# SSLRequireSSL

AuthType Basic
AuthName "Authorization Realm"
AuthUserFile /etc/httpd/passwd/passwords
Require valid-user
</Location>

7) create password file for httpd since I use Basic authType as shown on above.
#htpasswd -c /etc/httpd/passwd/passwords user1
#htpasswd /etc/httpd/passwd/passwords user2

8) testing the job
#service httpd restart

using web browser to access URL http://localhost//svn-repos/ubianalysis

Wednesday, August 4, 2010

Using user defined variable to simulate DB2 RANK function failure in MySQL server

I recently tried to simulate RANK function from DB2 by using user defined variable. It is very nature for developer to think about using MySQL user defined variable as counter to simulate RANK function. However, it is not successful. I got random rank number in the result set. Below is the sample SQL code.
SET @jia = NULL ;
SELECT id, sum( sales ) AS sales, count( * ) AS sig, @jia := IFNULL( @jia , 0 ) +1 AS rank
FROM brandpromo
GROUP BY id
ORDER BY sales DESC
LIMIT 100 ;
I was only aware that the user defined variable is only connection session scope alive. I did not know that it is dangerous to use user defined variables together with GROUP BY and ORDER BY clause. So, DO NOT use user defined variable together with GROP BY and ORDER BY in MySQL server. At least, be careful when you want to use it in that way.

Actually, I found a blog post that talks about this topic in detail. For more info, we can read this.

Sunday, July 18, 2010

A simple tutorial about coding multi thread code with Java cocurrency API.

I was asked to help on writing a multi-thread code recently. I think it is piece of cake as I wrote multi-thread code before. I do not want to write a thread pool from the scratch. So, obviously, the first place I will go is apache common library. However, I saw the below description on its web site,
Please note that one of the reasons this component is still in the sandbox and has never had a 1.0 release is Doug Lea's excellent util.concurrent library. That library works with many JDKs, is full-featured, well-documented, and well-tested. That library is also a standard part of the JDK starting with JDK 1.5, as the java.util.concurrent library: it is specified in the JSR 166 standard. 
So, common thread pool is dead although it will not say that in this way? I think I had been dead too as I, as a Java programmer since 1996, do not know how to use thread pool from JDK1.5. So, to save myself, I learned JDK thread pool and make a simple tutorial here.

In this simple demo project, I make five classes, ThreadpoolDemo is the main class. DummyTaskExcutor is worker thread. And TaskFinishedEvent and TaskFinishedEventListener are helper classes to inform ThreadpoolDemo that one DummyTaskExcutor object finished the task running already. Below is the source code.

TaskFinishedEvent.java
package jia.blog;

import java.util.EventObject;

/**
 * A very simple event class, which is used to notify main class that
 * this task has been finished.
 * 
 * @author yiyu.jia
 */
public class TaskFinishedEvent extends EventObject{

    public TaskFinishedEvent(Object source) {
        super(source);
    }
}

TaskFinishedEventListener.java
package jia.blog;

import java.util.EventListener;
/**
 * This is a listener interface definition.
 * @author yiyu.jia
 */
public interface TaskFinishedEventListener extends EventListener{

    public void taskFinishedEventOccured(TaskFinishedEvent evt);

}

ThreadpoolDemo.java
package jia.blog;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author Yiyu Jia
 */
public class ThreadpoolDemo implements TaskFinishedEventListener{

    //total number of core thread
    private int coreThreadNum = 5;
    //a counter for finished tasks (thread).
    private static int finishedTasks = 0;
    //a static object for synchronizing block of code.
    private static final Object syncObj = new Object();
    //This is the thread pool object.
    private static ThreadPoolExecutor exec;


    public void runTasks(){

        //Creating a blocking queue for holding runnalbe tasks with
        //maximum capacity of holding coreThreadNum*2. We know we will only
        //have 5 dummy thread task in this simple demo. I assign it as coreThreadNum*2
        // to highlight the difference only.
        BlockingQueue q = new ArrayBlockingQueue(coreThreadNum*2);

        //Creating a thread pool which will always have coreThreadNum live thread and
        //coreThreadNum*2 thread in maximum. If a thread is idle for longer than 1 second and
        //the total number of thread in pool is larger than coreThreadNum, the thread will be killed.
        exec = new ThreadPoolExecutor(coreThreadNum, coreThreadNum*2, 1, TimeUnit.SECONDS, q);

        //Now, let's feed the thread pool runnable tasks and excute them all.
        //One I want to highlight here is that we do not need to setup a endless loop
        //in the main class to keep whole application not to exit now as we are using
        //ThreadPoolExecutor.
        for (int i = 0; i < coreThreadNum; i++) {
            DummyTaskExcutor tempExt = new DummyTaskExcutor();
            tempExt.addTaskFinishedEventListener(this);
            exec.execute(tempExt);
        }

        //lets start a monitor thread and have fun.
        //We can expan the capability of this thread.
        MonitorThread monitor = new MonitorThread(this);
        monitor.setDaemon(true); //set monitor thread as a Daemon thread.
        monitor.start();
    }

    /**
     * supply running time information.
     * @return String
     */
    public String getInfo(){
        String info = "There are currently " + exec.getPoolSize() + " in pool and "
                + exec.getCompletedTaskCount() + " has been finished.";
        return info;
    }

    public void taskFinishedEventOccured(TaskFinishedEvent evt) {
        // I prefer to use this counter to determine whether all
        // task is completed or not.
        synchronized (syncObj) { 
            finishedTasks++;
        }
        if (finishedTasks >= coreThreadNum) {
            exec.shutdownNow();//I just shut it down immediately.
        }
    }

    static public void main(String argv[]) {

        ThreadpoolDemo demo = new ThreadpoolDemo();
        try {
            demo.runTasks();
        } catch (Exception e) {
        }
    }
}


DummyTaskExcutor.java
package jia.blog;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A dummy thread.
 * 
 * @author Yiyu Jia
 */
public class DummyTaskExcutor implements Runnable{

    public void run() {
        try {
            for (int i = 0; i < 3; i++) {
                
                System.out.println("I am lazy object No." + this.hashCode()); //use object hashcode to identify each thread object.
                Thread.sleep(doRawRandomNumber()); //sleep in random time between 0.5 second and 10 second.
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(DummyTaskExcutor.class.getName()).log(Level.SEVERE, null, ex);
        }
        TaskFinishedEvent evt = new TaskFinishedEvent(this); //I will replace this with other thread info later.
        fireTaskFinishedEvent(evt);

    }

    /**
     * a function generating random number in given range.
     * @return int
     */
    private int doRawRandomNumber() {

        int min = 500;
        int max = 10000;
        return (int) (Math.random() * (max - min + 1)) + min;
    }


        // Create the listener list
    protected javax.swing.event.EventListenerList listenerList = new javax.swing.event.EventListenerList();

    // This methods allows classes to register for TaskFinishedEvents
    public void addTaskFinishedEventListener(TaskFinishedEventListener listener) {
        listenerList.add(TaskFinishedEventListener.class, listener);
    }

    // This methods allows classes to unregister forTaskFinishedEvents
    public void removeTaskFinishedEventListener(TaskFinishedEventListener listener) {
        listenerList.remove(TaskFinishedEventListener.class, listener);
    }

    // This private class is used to fire TaskFinishedEvents
    void fireTaskFinishedEvent(TaskFinishedEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        // Each listener occupies two elements - the first is the listener class
        // and the second is the listener instance
        for (int i = 0; i < listeners.length; i += 2) {
            if (listeners[i] == TaskFinishedEventListener.class) {
                ((TaskFinishedEventListener) listeners[i + 1]).taskFinishedEventOccured(evt);
            }
        }
    }
}

MonitorThread.java
package jia.blog;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * This class works as a daemon thread to get running time info from main class.
 * @author yiyu
 */
public class MonitorThread extends Thread{
    
    ThreadpoolDemo demo; //a pointer to main class object.

    public MonitorThread(ThreadpoolDemo demo) {
        this.demo = demo;
    }

    @Override
    public void run() {
        do{
            try {
                
                Thread.sleep(2000);
                printInfo(demo.getInfo()); //get running time info from main class.

            } catch (InterruptedException ex) {
                Logger.getLogger(MonitorThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }while(true);
    }
    
    private void printInfo(String info){
        System.out.println(info);
    }
} 



Click here to download the netbeans project.

Thursday, May 20, 2010

statistical analysis on Intron/Exon splice sites distribution


After the discovery of nuclear introns in 1970s, Harvard biologist Walter Gilbert, who coined both terms "intron" and "exon" in 1978, raised one more question: "Why are genes in pieces?". Meanwhile, he also hypothesized that eukaryotic genes had been assembled from mini-genes -- today's exons. Most eukaryotic genes have intron/exon structure. Whether the intron/exon structure of eukaryotic genes is the result of the shuffling of exons at an early evolutionary stage, or introns have been inserted into preformed genes during eukaryotic evolution at the late evolutionary stage is the core question of the ongoing debate between "introns-early" and "introns-late" camps. Neo-Darwinists prefer "introns-early" because this hypothesis allows modern genes to be composed from small pieces of "mini-gene". Nobel prize winner Renato Dulbecco says that introns could not have been inserted late, because there are too many similarities among the introns found in species that diverged very long ago. However, recent research work show that modern nuclear introns invaded eukaryotic genes late in evolution after the separation of transcription and translation.

I became to be interested in this research topic very much as it is even about the origin of genes (if we accept the hypothesis of evolution)! It is interesting that I feel research on this is built on hypothesis and hypothesis on hypothesis. However, what science research is eventually started from a hypothesis? It is science. It is very interesting that, as human being, we are so curious to find out origin of us! But, can it be a completion task for us? I really do not know. Therefore, as a conclusion of my research thesis, I find out a Chinese poems written by Su Shi around one thousand years ago. 

             Written on the Wall at West Forest Temple
                                                                 by Su Shi
                  From the side, a whole range; 

                  from the end, a single peak: 
                  Far,near, high, low, no two parts alike. 
                 Why can't I tell the true shape of Lu-shan? 
                 Because I myself am in the mountain.
                                                          Translated by Tr. Burton Watson
 

If you are interested, Click for my thesis about gene evolution  . Here are comments from reviewers (click here).  Here is my defense letter. You will have fun (click here and here). 

Monday, May 10, 2010

Configure auto login on Fedora 13 or Fedora 14

I was tired about typing password on my home notebook every time when I turn it on. Especially, I want to turn it on and leave for doing other things. Then, I do not need to waste time on waiting it to boot up. After doing searching online and trying, the below is the way to enable the auto login for GNOME. And, it is the same if I want enable KDE desktop auto login. It seems wired. But, I think it is reasonable because there is no reason to let KDE not auto login if the GNOME's auto login has been enabled.

To enable auto login in Fedora 13 is simple,
  1.  change account to be su 
  2. open file /etc/gdm/custom.conf in a text editor
  3. change or add below into the file
[daemon]
TimedLoginEnable=true
TimedLogin=yiyu.jia
TimedLoginDelay=0

This works on Fedora 14 as well.

Tuesday, April 20, 2010

combining PBE and XMLEncoder to generate encrypted file.

I have seen that many companies still be comfortable with putting their sensitive information in a plain text configuration file. Now, I use PHP and Zend Framework to develop enterprise application. I saw popular function MD5 and SHA is widely used by PHP programmer to protect sensitive data. It is not enough to protect data like password as message digest is not encryption algorithm. It is used to ensure data integrity.

I find back the configuration file encryption Java code. It is pretty easy to implement Passphase Based Encryption (PBE) in Java. I like to use XMLEncoder and XMLDecoder to write and read configuration file as it make simple code and good OO manner. However, XMLEncoder write Java object in a plain xml file. So, I create my own simple EncryptXMLEncoder and DecryptXMLDecoder to wrap around XMLEncoder and XMLDecoder. With EncryptXMLEncoder and DecryptXMLDecoder, I can write Java object into an encrypted file and read it back to a Java object.

These classes has potential to be expanded to be part of license manager. I will put my license manager design later. Also, I will implemented similar class in PHP later.

DummyDemo.java
package jia.blog.util.cfg;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import jia.blog.util.beans.DecryptedXMLDecoder;
import jia.blog.util.beans.EncryptedXMLEncoder;

/**
 *
 * @author Yiyu Jia
 */
public class DummyDemo {


    static public void main(String argv[]) {
        
        try {
            //I use a simple DB configuration object for demo.
            DBConfiguration db = new DBConfiguration();
            db.setDbDriverName("com.mysql.jdbc.Driver");
            db.setDbURI("jdbc:mysql://localhost:3306/jiaBlog");
            db.setDbUser("yiyu.jia");
            db.setDbPassword("****");
            db.setDbPoolMinSize(1);
            db.setDbPoolMaxSize(5);

            //point out where the configuration file will be saved
            FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir") + File.separator + "cfg" + File.separator + "dbCfg.xml");
            BufferedOutputStream bos = new BufferedOutputStream(fos);

            //initialized an EcnryptedXMLEncoder with pass in passphase and salt string.
            EncryptedXMLEncoder xmlEncoder = new EncryptedXMLEncoder(bos, "a complex password is a passphase", "put some salt for better taste");
            //write the object to file. writing is down!
            xmlEncoder.writeObject(db);

            //point out where the configuration file will be read.
            FileInputStream fis = new FileInputStream(System.getProperty("user.dir") + File.separator + "cfg" + File.separator + "dbCfg.xml");

            //initialized an DecryptedXMLEncoder with pass in passphase string and salt string.
            DecryptedXMLDecoder xmlDecoder = new DecryptedXMLDecoder(fis, "a complex password is a passphase", "put some salt for better taste");
            DBConfiguration dbCfg = (DBConfiguration )xmlDecoder.readObject();

            //let's see whether we get back the configuration correctly. 
            System.out.print(dbCfg.getDbDriverName() + "\n"
                        + dbCfg.getDbUser() + "\n"
                        + dbCfg.getDbPassword());
            
        } catch (IOException ex) {
            Logger.getLogger(DummyDemo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(DummyDemo.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            
        }
    }
}


EncryptedXMLEncoder.java
package jia.blog.util.beans;

import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 *
 * @author Yiyu Jia
 */
public class EncryptedXMLEncoder {

    OutputStream out;
    String passphase, salt;

    public EncryptedXMLEncoder(OutputStream out, String passphase, String salt) {
        this.out = out;
        this.passphase = passphase;
        this.salt = salt;
    }

    public void writeObject(Object o) throws IOException, Exception {

        //I simply use ByteArrayOutputStream here.
        //We can swith to piped stream if the object is really large.
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        XMLEncoder xmlEncoder = new XMLEncoder(baos);
        xmlEncoder.writeObject(o);
        xmlEncoder.close();        
        InputStream is =new ByteArrayInputStream(baos.toByteArray());
        baos.close();        
        Encrypter.encryptOutput(passphase, salt, is, out);

    }
}

DecryptedXMLDecoder.java
package jia.blog.util.beans;

import java.beans.XMLDecoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
 *
 * @author Yiyu Jia
 */
public class DecryptedXMLDecoder {

    InputStream in;
    String passphase, salt;

    public DecryptedXMLDecoder(InputStream in, String passphase, String salt) {
        this.in = in;
        this.passphase = passphase;
        this.salt = salt;
    }

    public Object readObject() throws Exception {

        //I simply use ByteArrayOutputStream here.
        //We can swith to piped stream if the object is really large.
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Encrypter.decryptInput(passphase, salt, in, baos );
        InputStream is =new ByteArrayInputStream(baos.toByteArray());
        XMLDecoder xmlDecoder = new XMLDecoder(is);
        Object o = xmlDecoder.readObject();
        xmlDecoder.close();
        return o;
    }
}


click here for netbean project files.

Saturday, April 10, 2010

HTML DIV tag in ExtJS vs java.awt.Container in Swing.

I have strong feelings that I can compare those pure JavaScript Ajax toolkits, for instance ExtJS, with Java Swing. To compare these stuff from different worlds, the starting point is java.awt.Container and DIV tag in HTML. According to my understanding, java.awt.Container is the root component for all Java Swing widgets. Meanwhile, theoretically, HTML div tag is the root component for all ExtJS widgets. This thoughts can be represented as below figure. 

 Of course, there is no a class called as "DIV" in ExtJS. The root class for all widgets is Ext.Component, which extends from Ext.util.Observable. Observable is the common interface for widgets to publish event.However, Ext.Component does wrap DIV as a canvas, on which we can paste html tag, CSS, figures and all other things we can do on a DOM object.

So, how can this thought be useful? Well, I think the first benefit pump out in my mind is that I will think it is technically feasible to seamlessly use ExtJS with other pure javaScript Ajax libraries like Dojo, in one HTML page. Of course, it might ask for great skill to handle DOM event and JavaScript coding. Also, I guess GWT toolkit creators has similar thoughts to make GWT toolkit? I wish this post will encourage Java Swing programmer to have no fear of learning ExtJS :)

BTW, I do not include Java AWT here because AWT has different architecture with Swing. AWT widgets have their peers from mother OS. So, they are so-called heavyweight components. Meanwhile, Swing widgets are lightweight because all components are "drew" purely by Java.

Edit:
As we can see in ExtJS 4.0 beta release, Sencha changes its class model in ExtJS 4.0. Then introduced a new concept "mixin (mixed in)". Therefore, the Observable class becomes a mixin of Component class. So, now, we can see that ExtJS is more similar as Java Swing. Below is the diagrams linked from ExtJS blog to describe its new class system.

Tuesday, April 6, 2010

We don't need MVC framework on the server side today

I got this thought several years ago when I evaluated Ajax libraries for one project about upgrading an old enterprise application written in PHP and Java. I recalled this because I interviewed with one employer who intends to select Zend Framework now (in 2010). Its implementation of MVC is one of reasons for them to choose Zend Framework. Zend framework could be good candidate for implementing enterprise application. However, I do not think a Rich Internet Application or a Single Page Application needs a MVC framework on the server side today.

Many software vendors talked about Ajax when Ajax was becoming popular. However, many of them talk about their own server side framework, which i personally do not like. I divide those Ajax frameworks into two classes. One is client side pure JavaScript library. The other is Ajax framework running on the server side to generate client side Ajax widget. Personally, I like the pure javascripts libraries for developing Single page enterprise application.

It is not necessary to adopt MVC framework on the server side if we are developing a Single page Web application because we will not generate View on the server side. Supposing we are using ExtJS or Dojo to developing a Single page Web application. All views (widgets) could be written in JavaScript. Browser can either download whole views at one time or dynamically download views on demand. Therefore, why do we still need a MVC framework on the server side? I believe that we only need a front control framework on the server side to supply data (modal) to render views downloaded in browser. With this design, we clearly divide view development and models developing. Also, it is possible to divide developing team into two group. One is good at JavaScript coding and will focus on JavaScript code. The other is good at PHP coding or Java coding and will focus on server side programming. Furthermore, we can avoid mixing HTML, Javascript, and PHP or Java code as much as possible. A designed protocol will link server side and client side applications. JSON could be a good candidate technique to be used for delivering data between browser and server.

Maybe, it could be good idea to implement an Javascript MVC framework in browser?

Saturday, April 3, 2010

Install KDE on Fedora with GNOME

Because of license issue, KDE is not included in Fedora installation CD by default. But, the KDE desktop environment is really attractive. I feel it looks better than GNOME. So, we need to install the KDE. There are different ways described how to do it. I write what I found here in case I need to do this again. Then, I do not need to spend time on searching again. command is simple,

yum -y groupinstall 'KDE' 

Thursday, April 1, 2010

Include Java source code in generated JavaDoc

I wanted to include Java source code directly in generated javaDoc. However, I found that I forgot it. And it is not very quick found after I google it though it should be very simple. Maybe, it is too simple and people is not bothered to document it. So, I am writing a note here in case I will forget it again.

It is really very simple. All I need to do is just put "-linksource" option when I use javadoc tool. In netbeans, it is very easy to generate javadoc by right clicking the project and selecting "Generate Javadoc" menu item. In order to include java source code, we need to add options to project properties as below,
  1. right click your project and select properties.
  2. selecting Documenting under Build node in the pop up window.
  3. adding -linksource in the "Additional Javadoc Options" text field.
See below pic for a clear view.