Monday, October 27, 2008

Introduction to Reliable Messaging with WSF/PHP

 

With WSF/PHP you can add reliability to your web services integrations . Due to the  nature of PHP, WSF/PHP supports only single channel reliable messaging. Single channel means you are using the same channel to transmit both the request and response.

When reliable messaging is used, in addition to the actual message being transmitted , there will be handshake interactions between the client and the service to make sure that the sent message is actually delivered to the service. In addition the , reliable messaging middleware make sure that if the receiver endpoint down, it will keep polling till the message is delivered etc.

Let see how you can implement a simple reliable messaging client using WSF/PHP.

These are the requirements.

1. You service endpoint should be able to handle single channel reliable messaging.

2.Then you need to enable addressing.

In RM, the communication happens using a sequence. The initial handshake is to build this sequence, and with a sequence , one or more application messages is transmitted. Once the messaging transmission is complete, the sequence is terminated.

So the messages exchanged in a single channel scenario is as follows. I am using the actual xml messages exchanged in the echo_client_rm.php sample that comes with WSF/PHP release here.

1. Client sending the CreateSequence Message to the service.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To>http://localhost/samples/reliable/echo_service_rm.php</wsa:To>
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</wsa:Action>
      <wsa:ReplyTo>
         <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
      </wsa:ReplyTo>
      <wsa:MessageID>urn:uuid:6dbfe9a0-304f-415e-91d1-49d2993bcf56</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <wsrm:CreateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
         <wsrm:AcksTo xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
            <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
         </wsrm:AcksTo>
         <wsrm:Offer xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
            <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
         </wsrm:Offer>
      </wsrm:CreateSequence>
   </soapenv:Body></soapenv:Envelope>

2. Service responding with a CreateSequenceResponse message.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</wsa:Action>
      <wsa:From>
         <wsa:Address>http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
      </wsa:From>
      <wsa:MessageID>urn:uuid:48020317-4e90-4b79-97ae-2fa9b78c544b</wsa:MessageID>
      <wsa:RelatesTo wsa:RelationshipType="http://www.w3.org/2005/08/addressing/reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:6dbfe9a0-304f-415e-91d1-49d2993bcf56</wsa:RelatesTo>
   </soapenv:Header>
   <soapenv:Body>
      <wsrm:CreateSequenceResponse xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
         <wsrm:Identifier>8883a8b9-9f6a-4e40-b78a-872a2708a4b3</wsrm:Identifier>
         <wsrm:Accept xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
            <wsrm:AcksTo xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
               <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
            </wsrm:AcksTo>
         </wsrm:Accept>
      </wsrm:CreateSequenceResponse>
   </soapenv:Body></soapenv:Envelope>

3. Client sending the sequence Message

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsrm:Sequence soapenv:mustUnderstand="1" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>8883a8b9-9f6a-4e40-b78a-872a2708a4b3</wsrm:Identifier>
         <wsrm:MessageNumber xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">1</wsrm:MessageNumber>
         <wsrm:LastMessage xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
      </wsrm:Sequence>
      <wsa:To>http://localhost/samples/reliable/echo_service_rm.php</wsa:To>
      <wsa:Action>http://wso2.org/wsfphp/samples/echoString</wsa:Action>
      <wsa:MessageID>urn:uuid:8e275ba1-b34b-49c1-92fa-ce86782ff803</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples">       
         <text>Hello World!</text>   
      </ns1:echoString>
   </soapenv:Body></soapenv:Envelope>

4. Service Responding with a SequenceAcknowledgement message. Since this is an echo service, in addition to sending the acknowledgement, the service also initiate a sequence here and send the application message back to the client.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsrm:Sequence soapenv:mustUnderstand="1" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
         <wsrm:MessageNumber xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">1</wsrm:MessageNumber>
         <wsrm:LastMessage xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
      </wsrm:Sequence>
      <wsrm:SequenceAcknowledgement soapenv:mustUnderstand="0" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>8883a8b9-9f6a-4e40-b78a-872a2708a4b3</wsrm:Identifier>
         <wsrm:AcknowledgementRange Lower="1" Upper="1"/>
      </wsrm:SequenceAcknowledgement>
      <wsa:Action>http://wso2.org/wsfphp/samples/echoString</wsa:Action>
      <wsa:ReplyTo>
         <wsa:Address>http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
      </wsa:ReplyTo>
      <wsa:From>
         <wsa:Address>http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
      </wsa:From>
      <wsa:MessageID>urn:uuid:307e881d-8ac7-4cb4-8acf-0eb04831707f</wsa:MessageID>
      <wsa:RelatesTo wsa:RelationshipType="http://www.w3.org/2005/08/addressing/reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:8e275ba1-b34b-49c1-92fa-ce86782ff803</wsa:RelatesTo>
   </soapenv:Header>
   <soapenv:Body>
      <ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples">       
         <text>Hello World!</text>   
      </ns1:echoString>
   </soapenv:Body></soapenv:Envelope>

5. Client send the SequenceAcknowledgement message to the service.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsrm:SequenceAcknowledgement soapenv:mustUnderstand="0" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
         <wsrm:AcknowledgementRange Lower="1" Upper="1"/>
      </wsrm:SequenceAcknowledgement>
      <wsa:To>http://localhost/samples/reliable/echo_service_rm.php</wsa:To>
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/SequenceAcknowledgement</wsa:Action>
      <wsa:MessageID>urn:uuid:3b2b7a50-f962-4027-b240-5eea57142df1</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body/></soapenv:Envelope>

 

6. Now the service sends back a TerminateSequence Message.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</wsa:Action>
      <wsa:MessageID>urn:uuid:6e8178c6-a566-4010-a77e-d05af67ad21a</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <wsrm:TerminateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
         <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
      </wsrm:TerminateSequence>
   </soapenv:Body></soapenv:Envelope>

Similarly the client and service exchanges TermianteSequenceResponse messages as well.

I am sure, now you have some understanding on what actually happens when you try to send a soap message reliably from  one endpoint to another. In my next blog post, we will discuss how to configure WSF/PHP to implement reliable clients and services.

Introduction to Reliable Messaging with WSF/PHP

 

With WSF/PHP you can add reliability to your web services integrations . Due to the  nature of php, WSF/PHP supports only single channel reliable messaging. Single channel means you are using the same channel to transmit both the request and response.

So what is the nature of a reliable messing interaction ?

When reliable messaging is used, in addition to the actually message being transmitted , there will be handshake interactions between the client and the service to make sure that the send message is actually delivered to the service. In addition the , reliable messaging middleware handles make sure that if the receiver endpoint down, it will keep polling till the message is delivered etc.

Let see how you can implement a simple reliable messaging client using WSF/PHP.

These are the requirements.

1. You service endpoint should be able to handle single channel reliable messaging.

2.Then you need to enable addressing.

In RM, the communication happens using a sequence. The initial handshake is to build this sequence, and with a sequence , one or more application messages is transmitted. Once the messaging transmission is complete, the sequence is terminated.

So the messages exchanged in a single channel scenario is as follows. I am using the actually xml messages exchanged in the echo_client_rm.php sample that comes with WSF/PHP release here.

1. Client sending the CreateSequence Message to the service.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To>http://localhost/samples/reliable/echo_service_rm.php</wsa:To>
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</wsa:Action>
      <wsa:ReplyTo>
         <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
      </wsa:ReplyTo>
      <wsa:MessageID>urn:uuid:6dbfe9a0-304f-415e-91d1-49d2993bcf56</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <wsrm:CreateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
         <wsrm:AcksTo xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
            <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
         </wsrm:AcksTo>
         <wsrm:Offer xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
            <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
         </wsrm:Offer>
      </wsrm:CreateSequence>
   </soapenv:Body></soapenv:Envelope>

2. Service responding with a CreateSequenceResponse message.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</wsa:Action>
      <wsa:From>
         <wsa:Address>http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
      </wsa:From>
      <wsa:MessageID>urn:uuid:48020317-4e90-4b79-97ae-2fa9b78c544b</wsa:MessageID>
      <wsa:RelatesTo wsa:RelationshipType="http://www.w3.org/2005/08/addressing/reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:6dbfe9a0-304f-415e-91d1-49d2993bcf56</wsa:RelatesTo>
   </soapenv:Header>
   <soapenv:Body>
      <wsrm:CreateSequenceResponse xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
         <wsrm:Identifier>8883a8b9-9f6a-4e40-b78a-872a2708a4b3</wsrm:Identifier>
         <wsrm:Accept xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
            <wsrm:AcksTo xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
               <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
            </wsrm:AcksTo>
         </wsrm:Accept>
      </wsrm:CreateSequenceResponse>
   </soapenv:Body></soapenv:Envelope>

3. Client sending the sequence Message

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsrm:Sequence soapenv:mustUnderstand="1" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>8883a8b9-9f6a-4e40-b78a-872a2708a4b3</wsrm:Identifier>
         <wsrm:MessageNumber xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">1</wsrm:MessageNumber>
         <wsrm:LastMessage xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
      </wsrm:Sequence>
      <wsa:To>http://localhost/samples/reliable/echo_service_rm.php</wsa:To>
      <wsa:Action>http://wso2.org/wsfphp/samples/echoString</wsa:Action>
      <wsa:MessageID>urn:uuid:8e275ba1-b34b-49c1-92fa-ce86782ff803</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples">       
         <text>Hello World!</text>   
      </ns1:echoString>
   </soapenv:Body></soapenv:Envelope>

4. Service Responding with a SequenceAcknowledgement message. Since this is an echo service, in addition to sending the acknowledgement, the service also initiate a sequence here and send the application message back to the client.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsrm:Sequence soapenv:mustUnderstand="1" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
         <wsrm:MessageNumber xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">1</wsrm:MessageNumber>
         <wsrm:LastMessage xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"/>
      </wsrm:Sequence>
      <wsrm:SequenceAcknowledgement soapenv:mustUnderstand="0" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>8883a8b9-9f6a-4e40-b78a-872a2708a4b3</wsrm:Identifier>
         <wsrm:AcknowledgementRange Lower="1" Upper="1"/>
      </wsrm:SequenceAcknowledgement>
      <wsa:Action>http://wso2.org/wsfphp/samples/echoString</wsa:Action>
      <wsa:ReplyTo>
         <wsa:Address>http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
      </wsa:ReplyTo>
      <wsa:From>
         <wsa:Address>http://localhost/samples/reliable/echo_service_rm.php</wsa:Address>
      </wsa:From>
      <wsa:MessageID>urn:uuid:307e881d-8ac7-4cb4-8acf-0eb04831707f</wsa:MessageID>
      <wsa:RelatesTo wsa:RelationshipType="http://www.w3.org/2005/08/addressing/reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:8e275ba1-b34b-49c1-92fa-ce86782ff803</wsa:RelatesTo>
   </soapenv:Header>
   <soapenv:Body>
      <ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples">       
         <text>Hello World!</text>   
      </ns1:echoString>
   </soapenv:Body></soapenv:Envelope>

5. Client send the SequenceAcknowledgement message to the service.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsrm:SequenceAcknowledgement soapenv:mustUnderstand="0" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
         <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
         <wsrm:AcknowledgementRange Lower="1" Upper="1"/>
      </wsrm:SequenceAcknowledgement>
      <wsa:To>http://localhost/samples/reliable/echo_service_rm.php</wsa:To>
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/SequenceAcknowledgement</wsa:Action>
      <wsa:MessageID>urn:uuid:3b2b7a50-f962-4027-b240-5eea57142df1</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body/></soapenv:Envelope>

 

6. Now the service sends back a TerminateSequence Message.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence</wsa:Action>
      <wsa:MessageID>urn:uuid:6e8178c6-a566-4010-a77e-d05af67ad21a</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <wsrm:TerminateSequence xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">
         <wsrm:Identifier>df2ceab0-b04f-428a-bb94-0cfdcb0a524b</wsrm:Identifier>
      </wsrm:TerminateSequence>
   </soapenv:Body></soapenv:Envelope>

Similarly the client and service exchanges TermianteSequenceResponse messages as well.

I am sure, now you have some understanding on what acctually happens when you try to send a soap message reliably from  one endpoint to another. In my next blog post, we will discuss how to configure WSF/PHP to implement reliable clients and services.

Thursday, October 23, 2008

How to learn the SOAP version by looking at a soap message

I have seen number of questions on the forums on issues related to this. So here are some tips on getting to know spec versions by looking at a soap message with http headers.

Here is an example SOAP1.1 one message.

POST /samples/echo_service.php HTTP/1.1
User-Agent: Axis2C/1.5.0
SOAPAction: ""
Content-Length: 242
Content-Type: text/xml;charset=UTF-8
Host: 127.0.0.1:8080

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples">
         <text>Hello World!</text>
      </ns1:echoString>
   </soapenv:Body></soapenv:Envelope>

 

I have marked highlighted the important points.

In SOAP1.1

1.  Content-Type will be "text/xml".

2. SOAPAction is a separate HTTP Header

3. SOAP envelope namespace uri is  "http://schemas.xmlsoap.org/soap/envelope/"

Here is a SOAP 1.2 message.

POST /samples/echo_service.php HTTP/1.1
User-Agent: Axis2C/1.5.0
Content-Length: 240
Content-Type: application/soap+xml;charset=UTF-8;action="urn:echoString"
Host: 127.0.0.1:8080

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Header/>
   <soapenv:Body>
      <ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples">
         <text>Hello World!</text>
      </ns1:echoString>
   </soapenv:Body></soapenv:Envelope>

In SOAP 1.2

1. Content-Type header is "application/soap+xml"

2. SOAP envelope namespace uri is "http://www.w3.org/2003/05/soap-envelope".

3. soap action header will go in the Content-type header as 'action'

Depending on you requirement, you can switch between between soap versions by passing the option "useSOAP"=>1.1 or "useSOAP"=>1.2.

For a service in WSF/PHP, the soap version does not matter since the framework is capable of handling either type.

Wednesday, October 22, 2008

How to Get WS-Security working without WS-Addressing in WSF/PHP

Usually, most security scenarios use WS-Addressing. But there are scenarios that uses security without WS-Addressing. Due to configuration  file settings, WSF/PHP works with WS-Security only when WS-Addressing is also used. However, by doing some simple changes to a couple of Xml files, you can get WSF/PHP to support some security scenario's that does not use WS-Addressing.

Here is what you need to do.

1. Step One.

Open the axis2.xml file found in was_c directory. In it,  change in inflow by adding another phase named Security as follows.

<phaseOrder type="inflow"> - <!-- System pre defined phases       -->

<phase name="Transport" />

<phase name="PreDispatch" />

<phase name="Dispatch" />

<phase name="PostDispatch" />

<!-- End system pre defined phases       -->

<!-- After PostDispatch phase, module or service author can add any phase as required  -->

<!-- User defined phases could be added here -->

<phase name="Security" />

<phase name="Rahas" />

<phase name="RMPhase" />

</phaseOrder>

I have highlighted the line added in red.

2. Step two

Open the module.xml file found in wsf_c/modules/rampart/ directory and change the inflow elements phase name attribute from "PreDispatch" to "Security" as follows.

<inflow>
       <handler name="RampartInHandler" class="mod_rampart">
           <order phase="Security"/>
       </handler>
   </inflow>

Again, I have highlighted the change.

That's all you need to do to get WS-Security to work without using WS-Addressing.

Note that,for this to work, you will have to have either SOAPAction or an element that matches the operation name in Soap Body. Of course there are some WS-Security scenarios that cannot work without WS-Addressing.

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.