Tuesday, October 21, 2008

Tips on avoiding common WSF/PHP installation issues.

Here are some useful tips avoid common fit falls in installing WSF/PHP.

1. Often users complain that When the run the sample clients, they see the response

"ERROR, WS Client not Found'.

This is often due not setting the wsf.home entry not being set correctly. Make sure to set wsf.home directory to point to wsf_c  directory if your are on windows or using pecl installation with WSF/C library installed separately.

Another reason for this is not adding the wsf_c/lib directory to PATH environment variable if you are on a windows system.

2.  WSDL Generation and WSDL mode does not work.

This is often due to you not having added the scripts folder found inside the wsfphp distribution to the php.ini's include path entry.

3. Compile WSF/PHP using source gives errors.

This could be due to two issues.

1. First you need to have installed the dev-libraries of PHP, Libxml2 and OpenSSL.

2. Incorrect configure options provided to the configure script.

          Often you do not need to provide any options to the configure script since it is written to work as

./configure, make , make install sequence.

Monday, October 20, 2008

How to use Attachment Caching with WSF/PHP

WSF/PHP 2.0.0 has the support for caching attachments ( writing to a file ). This effectively reduces the amount of memory used when sending and receiving attachments and its specially useful, if your application requires to send or receiving a very large file in the scale of megabytes.

WSF/PHP adds two php.ini entries in order to allow attachment caching.

1. wsf.attachment_cache_dir

2.wsf.enable_attachment_caching

wsf.attachment_cache dir is the location where the received attachments will be saved.

wsf.enable_attachment_caching option enables attachment caching.

By default, attachment caching can be done only for attachments larger than 1 MB.

Lets see a code sample on how to use this. This is a simple php service, which reads a binary file and send it to the client as an  MTOM attachment.

<?php

ini_set("wsf.enable_attachment_caching", 1);
ini_set("wsf.attachment_cache_dir","E:\\");

function sendAttachment($msg)
{
$responsePayloadString = <<<XML
        <ns1:download xmlns:ns1="http://php.axis2.org/samples/mtom">
            <ns1:fileName>test.jpg</ns1:fileName>
                <ns1:image xmlmime:contentType="image/jpeg" xmlns:xmlmime="http://www.w3.org/2004/06/xmlmime">
                    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:myid1"></xop:Include>
                </ns1:image>
        </ns1:download>
XML;
                                       

    $responseMessage = new WSMessage($responsePayloadString,
            array( "attachments" => array("myid1" => "../resources/large_image.jpg"))); 
    return $responseMessage;   
}

$operations = array("download" => "sendAttachment");

$service = new WSService(array("operations" => $operations, "useMTOM" => TRUE));

$service->reply();

?>

Now in above code, I have highlighted the important code pieces.

1. The php ini settings at the top of the code where the attachment_cache_dir is set and attachment caching is enabled.

ini_set("wsf.enable_attachment_caching", 1);
ini_set("wsf.attachment_cache_dir","E:\\");

2. Setting of a fake content id to which the actual attachment is assigned.

href="cid:myid1"

3. Instead of setting binary attachment as an string in the attachment array, we should set the actual path to the file.

array("myid1" => "../resources/large_image.jpg")

Thats all you need to do to get attachment caching working. The same technique can be used for the client as well. It will be consuming lot less amount of memory.

Friday, October 17, 2008

Using Open SSL to manage Your Keys

When it comes to WS-Security, for most of the operations, you will need to have either a certificate, or a key or both. Or you will need to provide a key store. WSF/PHP uses Open SSL library underneath to build WS-Security. Therefore knowing how to work with Open SSL can be really useful.

Lets go through some of the important commands you need to know to effectively get work done using Open SSL.

1. Generating a Certificate using Open SSL.

When generating a certificate, you have to decide whether you want an encrypted key or not. If you select the encrypted key option, your key will be protected by a passphrase.  This adds more security to your key since it will be difficult for some one stealing your key to use it. How ever you will need to provide this passphrase, every time you use the key. A self signed certificate is used to sign other certificates.

Use the command

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem

These options tells openssl to generate key length 1024  bits which is valid for 365 days and put both private key and certificate to a file named mycert.pem.

image

Now you will be prompt to answer a number of questions and then OpenSSL will generate you a self signed certificate.  Now if you open the mycert.pem you will see both the private key and the certificate stored there. If you remove the -nodes option, you will be asked to provide a passphrase.

2. Generating a private key and a matching public key using RSA algorithm.

It is sometimes necessary to generate the private key and public keys separately.

You can generate an RSA public key using the option genrsa.

openssl genrsa -out mykey.pem 2048

This generates a rsa private key with 2048 bits.

Using rsa option, you can get the corresponding public key.

openssl rsa -in mykey.pem -pubout

3. Creating a PKCS12 Keystore and adding keys to it.

openssl pkcs12 -export  -out mycert.pfx -in mycert.pem  -name "My Keystore"

This command generates a PKCS12  key store by exporting the above generated certificate. Here you will be asked for a passphrase as well.

Wednesday, October 15, 2008

How to build PHP from source

It is an interesting thing to build PHP source on a Windows Platform. It is extremely useful to build PHP source with various options specially if you wish to write a php extension. Here are some interesting tips on how you can build PHP source on a windows platform.

First you need to download the following dependencies.

1. You need to have visual studio or windows platform SDK install on you machine in order to have the required compiler and build tools.

2. You need to download the PHP build dependencies.

These include

1. Binary tools - Essential

2. Libxml2   - Optional

3. Iconv Optional

4. Zlib   - Optional

5. Apache or other web server that you intend to build modules.

6. PHP Source  - Essential

7. bindlib-cvs-vc8  - Essential

 

Most of these tools can be downloaded from here.

Once you have downloaded these tools, you are ready to build PHP from source.

First unzip all these tools to a directory. 

img1

Next, open visual studio command prompt and add binary-tools\bin directory to the path.

img2

Now, go to the PHP source extract directory and type,

buildconf.bat

Then run

cscript /nologo configure.js --help

img3

You will see a large number of options as shown above.

Next open the config.nice.bat file located in the php source directory and add necessary configure options for your build

Here are my configuration options

cscript /nologo configure.js  "--with-extra-includes=E:\phpbuild\bindlib-cvs-vc8\include;E:\Apache22\include;E:\phpbuild\iconv-1.9.2.win32\include;E:\phpbuild\libxml2-2.6.30.win32\include;E:\phpbuild\zlib-1.2.3.win32\include"

"--with-extra-libs=E:\phpbuild\iconv-1.9.2.win32\lib;E:\phpbuild\libxml2-2.6.30.win32\lib;E:\phpbuild\zlib-1.2.3.win32\lib;E:\Apache22\lib;E:\phpbuild\bindlib-cvs-vc8\lib"

"--enable-debug"  "--enable-apache2-2handler" %*

 

Here I am using the option --with-extra-includes to specify the include paths of the dependency libraries.  Similarly --with-extra-libs is used to specify the library path.

I use the options --enable-debug to make it a debug build.

Now run config.nice.bat file.

Next you can try nmake on the command line  and it will build the PHP Source.

Friday, September 19, 2008

Integrating PHP CMS Systems with Web Services

There are many PHP CMS Frameworks which provide the capability to easily handle a quality web site which needs daily maintenance. Drupal , Joomla are two such CMS frameworks. These are grate tools for building web sites and managing content. How ever they are functioning in isolation.  When a site grows big, these systems happen to have a lot of valuable data that needs to be integrated with other enterprise systems in order to add business value.

For example consider an enterprise which has build its main web site using one of these tools and has many registered users to this site. Now the enterprise wants to incorporate these users to another application which the enterprise is running, because it wants to provide single sign on capability without having make the users go through another tiresome registration workflow. Also think a scenario where this other system is running on java or .net.

One obvious solution would be to share the database used by the CMS framework for the other application. But such a thing would add many complexities and would require one of the systems to be changed which is not doable in many situations. Now if the other system provides some programmable API or a web services API, then there is an elegant way to solve this integration problem.

With the availability of WSF/PHP  Data Services solution, now you have an easy way to overcome such problems. You can exposed data manipulation operations of the CMS database as web services using WSF/PHP Data Services. Now the two systems can talk to each other using their respective web services and clients, and you have a beautifully integrated solution. 

Thursday, September 18, 2008

Debugging PHP Web Services

One of the difficulties of doing distributed computing, is the difficulty of debugging when things are not going well. It is no exception for Web Services. Since messages are exchanged between services, clients, we have to have some mechanisms  to capture messages, view the soap messages exchanged, some known error messages etc.

Capturing Messages

One of the most well known technique in debugging web services calls is to  some tcp message capture tool to capture the messages exchanged. There are few such good tools for this task.

1. TCPMON tool from apache

             This is a very simple and easy to use tool which has very wide adoption and is quite popular among developers. You can download this tool from apache tcpmon site. 

2. SOAP UI

            This is another popular tool for debugging and developing SOAP based applications. This tool is able to generate request SOAP message for a given WSDL where you fill out the values and send a valid soap request and response. This is a very useful tool to get started with Web Services. You can download soap UI from soapui.org

3.   Ethereal

         This is another tool that is quite useful is capturing and analyzing messages. http://thud.ethereal.com/

Using debugging functions from framework

you can you framework provided functions for debugging. For example WSF/PHP provides two functions getLastRequest() and getLastResponse() on the WSClient class which returns the exchanged request and response messages. Also it provides functions to obtains the returned HTTP headers. Using these, you can also do some debugging.

Logging

Logging is another useful techniques to idenfity possible problems. You can look as the wsf_php_client.log and wsf_php_server.log files and get an idea of what went wrong. If you are not able to trace what's wrong using the logs , you can post your problem with the appropriate log messages to the forum  and get support.

Using Known Error Messages

Another useful technique is to go through the known set of error messages to locate what went wrong. In WSF/PHP, here are some of the error messages you can get.

Monday, September 15, 2008

Implementing Rest Service and Client with WSF/PHP

WSO2 WSF/PHP 2.0.0 has support for HTTP verbs GET,POST,DELETE and PUT in its REST support alone with the ability to support custom URL mappings. Lets have a look at the WSF/PHP REST API and how to implement a simple client and service.

Usually, a REST system is build around CRUD ( Create, Read, Update, Delete ) model.

An HTTP POST Request is a creation of a resource. Similarly a GET request is reading, PUT request is updating and DELETE request is deleting.

You can find details of a design of a complex REST system here.

Implementing a PHP Web Service that can expose its operations as REST operations.

For exposing operations as REST operations, WSService constructor provides the option RESTMapping to specify each operation with its corresponding HTTP method and Custom URL that is mapped to the operation.

Lets consider an example.  Consider we have an operations createUserAccount, updateUserAccount, deleteUserAccount, and readUserAccount as the operations of a simple service called ManageUserAccounts.php

Then out operations map would be like

   1: $operations = array("createUserAccount" => "createAccount",


   2:                "updateUserAccount"=>"updateAccount",


   3:                 "deleteUserAccount"=>"deleteAccount",


   4:             "readUserAccount"=>"getAccount");




Here, the actual php functions implementing the business logic are  createAccount, updateAccount, deleteAccount and getAccount.



Now we can map these operations to an HTTP method and a custom URL, so that we can execute these same operations without having to use SOAP. 





   1: $restmap = array ("createUserAccount"=> array("HTTPMethod"=>"POST","RESTLocation"=> "users"),


   2:           "updateUserAccount"=> array("HTTPMethod"=>"PUT","RESTLocation"=> "users"),


   3:           "deleteUserAccount"=> array("HTTPMethod"=>"DELETE","RESTLocation"=> "users"),


   4:           "readUserAccount"=> array("HTTPMethod"=>"GET","RESTLocation"=> "users"));




Note how HTTPMethod is used to specify the HTTP Method that will be used to invoke each operation. For example, we will be using POST method to  invoke "createUserAccount" operation. 



RESTLocation option is used to specify a portion of a URL which will makeup the final URL of the operation. For example, if our service URL  is "http://localhost/samples/ManageUserAcconts.php" then, since we have set "users" as our RESTLocation, the final URL that will make the endpoint would be "http://localhost/samples/ManageUserAcconts.php/users". Note how I have used the same RESTLocation for all four operations. WSF/PHP is able to identify the correct operation using the HTTPMethod when the URL is the same.



Implementing the client



WSClient class which is the Client API in WSF/PHP API enables you to make use of  HTTP verbs POST,GET,DELETE and PUT when making a REST style operation invocation. 



First you need to know the REST endpoint where the resource is located. Consider we are invoking the "readUserAccount'' function defined in above service. Then our endpoint URL is  "http://localhost/samples/ManageUserAcconts.php/users" and HTTPMethod is GET. You can do this request using WSClient as well as using the Web Browser.





   1:     $client = new WSClient( array("to" => "http://localhost/samples/ManageUserAccounts.php/users",


   2:                                   "useSOAP" => FALSE,


   3:                                   "HTTPMethod" => "GET"));


   4:  


   5:     /** Request Payload String is the XML String send as argument to the operation, 


   6:         In this case, it will be send in query string */


   7:                 


   8:     $responseMessage = $client->request($requestPayloadString);




Similarly you can invoke other operations as well.  I will discuss more details in another blog post.