Monday, July 23, 2012

Routing and Service Chaining with WSO2 ESB Part 3

Part 1 > Part 2 > Part 3 

Creating hcfRequest Sequence


Keep in mind that hcfRequest is the receiving sequence of the response from the GeoService service. 


Let's first analyze the response message that is received by the hcfRequest sequence. 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <ns:getZipCodeResponse xmlns:ns="http://geo.wso2">
         <ns:return>32746</ns:return>
      </ns:getZipCodeResponse>
   </soapenv:Body>
</soapenv:Envelope>


The response message will contain the zipcode and will be received by hcfRequest sequence. 

Click on 'Sequences' under Service Bus and you will see the following screen. Click on 'Add Sequence'.



Give the following values as shown below. 



A log mediator is first added as shown below.  




Next a property mediator is added.



The property mediator is added to obtain the zipcode value from the response of the GeoService service.

Name - zipcode
Action - Set
Set Action as - Expression
Type - STRING
Expression - //geo:getZipCodeResponse/geo:return/text()




Add another log mediator to log the value of the zipcode as shown below. 



To construct the body of the message we will now be using the payloadfactory mediator instead of the enrich mediator and you will see that it's much easier to use it.  To add a payloadfactory mediator go to  Transform -> PayloadFactory. 



The payload format should contain the body of the message and for the input parameters enter the order of the parameter is prefixed by the dollar sign. In this case we have only one parameter and it will be $1. If we have a 2nd or 3rd paramater (and so on) we can have them as $2, $3.. $n. 

Let's analyze the format of the request message, so that we can construct it accordingly. 

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:heal="http://healthcare.wso2">
   <soap:Header/>
   <soap:Body>
      <heal:getHCCenters>
         <!--Optional:-->
         <heal:postalCode>?</heal:postalCode>
      </heal:getHCCenters>
   </soap:Body>
</soap:Envelope>


Therefore the payload format should be as follows. 

Payload format - 

<heal:getHCCenters xmlns:heal="http://healthcare.wso2">
   <heal:postalCode>$1</heal:postalCode>
</heal:getHCCenters>

The values for the arguments can be given by adding properties. In this case $1 in the message will be replaced by argument expression provided, which is the zipcode in this case. 

Argument Value/Expression - $ctx:zipcode

You can click on the Help link on the top right of the properties view to get more information about the mediator. 




Add another log mediator. 



Add a send mediator to send this message to the HCFacilityLocator service. 





The properties view should look like as given in the following screen. Browse for the HCFacilityLocatorServiceEP from the configuration registry and for the receiving sequence we need to give hciRequest sequence, which needs to be created. After it is created browse for it and update the sequence. Save the hcfRequest sequence. 

  

* Make sure to go back to the HCCService proxy service and browse for the receiving sequence to hcfRequest and update the proxy service, since we just created hcfRequest. 



Creating hciRequest sequence


hciRequest is the receiving sequence of the response from the HCFacilityLocator service. 

Let's analyze the response message that is received by the hciRequest sequence.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <ns:getHCCentersResponse xmlns:ns="http://healthcare.wso2">
         <ns:return>2583</ns:return>
         <ns:return>5201</ns:return>
         <ns:return>5575</ns:return>
         <ns:return>805</ns:return>
         <ns:return>2285</ns:return>
      </ns:getHCCentersResponse>
   </soapenv:Body>
</soapenv:Envelope>

The response message will contain one or more health care center codes.  We need to send these codes to the HCInformation service, one by one, to receive details about each health care center.  Therefore this message needs to be split and several messages need to be sent to the HCInformation service because it only accepts one health care center code. Let's create hciRequest which will do the splitting and routing. 

Create another sequence and provide the name hciRequest.

Add a log mediator. 



Add the following properties.



Next we have to add an iterate mediator. The reason for this is that when the zipcode was sent to HCFacilityLocatorService, it returns a list of health care center codes. A typical response would be as follows.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <ns:getHCCentersResponse xmlns:ns="http://healthcare.wso2">
         <ns:return>0000</ns:return>
         <ns:return>0001</ns:return>
      </ns:getHCCentersResponse>
   </soapenv:Body>
</soapenv:Envelope>

In this case, there are 2 ns:return elements. For each of those elements, we need to extract the healthcare center code value and perform a send operation because to get the healthcare details for one healthcare center, the healthcare center code should be sent.

The iterate mediator will split the message into a number of different messages (2 messages in this case) derived from the parent message by finding matching elements for the XPath expression specified. New messages will be created for each and every matching element and processed in parallel (default behavior) using either the specified sequence or endpoint.

To add an iterator mediator - Advanced -> Iterate.



When an iterate mediator is added, you will see that a target mediator will be added too. The target mediator can be used to form a new SOAP message from an existing SOAP info-set. For more information on the target mediator, click on the help link that comes in the properties view when the target mediator is selected. 





Click on the iterate mediator and provide the following values:

Iterate ID -  
Sequential Mediation - False
Continue Parent - False
Preserve Payload - True
Iterate Expression* - //hfs:getHCCentersResponse/hfs:return
Attach Path - //hfs:getHCCentersResponse

For more information on the iterate mediator click here.




When you click on the target mediator, you will see the following configurations.




Let's analyze the format of the request message, so that we can construct it accordingly.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:heal="http://healthcare.wso2">
   <soapenv:Header/>
   <soapenv:Body>
      <heal:getHCCenterInfo>
         <!--Optional:-->
         <heal:hcCenterCode>?</heal:hcCenterCode>
      </heal:getHCCenterInfo>
   </soapenv:Body>
</soapenv:Envelope>


Click on the target mediator and add a payloadfactory mediator.




Provide the following information as shown.


Payload format - 

<heal:getHCCenterInfo xmlns:heal="http://healthcare.wso2">
   <heal:hcCenterCode>$1</heal:hcCenterCode>
</heal:getHCCenterInfo>

Argument Expression - //hcc:getHCCentersResponse/hcc:return/text()



Add a log mediator as follows. 



Finally add a send mediator. 



Click on Configuration Registry to point to the HCInformationService endpoint.



Select HCInformationService from the drop down list.



Click on update and save. 



Here's the overview of the sequence we created. Log -> Iterate ->For each iteration create the payload with the healthcare center code and send it to HCInformationService to get the healthcare center details.



* Remember go back to the hcfRequest sequence and browse for the receiving sequence in the send mediator to hciRequest and update hcfRequest sequence, since we just created hciRequest. 


Creating the HCCService Proxy Service (Part 2)


Let's briefly recap what we have completed so far.



  • Created the HCCService proxy service. 
  • Created the in sequence for the proxy service but didn't create the out sequence. 
  • Created the hcfRequest and hciRequest sequences. 
  • Let's create the out sequence for the proxy service now.
Before creating the out sequence, let's check the format of the response messages that HCInformation service sends. Bear in mind that several response messages will be sent.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <ns:getHCCenterInfoResponse xmlns:ns="http://healthcare.wso2">
         <ns:return xsi:type="ax21:HCInfo" xmlns:ax21="http://healthcare.wso2/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ax21:address>2583 South Volusia Ave (17-92), Suite 300</ax21:address>
            <ax21:approxDistance>13.1</ax21:approxDistance>
            <ax21:city>Orange City,  FL</ax21:city>
            <ax21:hcCenterName>Orange City CBOC</ax21:hcCenterName>
            <ax21:phone>386-456-2080 Or 386-456-2082</ax21:phone>
         </ns:return>
      </ns:getHCCenterInfoResponse>
   </soapenv:Body>
</soapenv:Envelope>

Since, several of these messages will be received by the out sequence, the out sequence must aggregate them into one message and sent to the user, because after all the user send his coordinates to receive information about all the healthcare centers in his vicinity. 

We need to send a response such as the following:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <ns:getHCCenterInfoResponse xmlns:ns="http://healthcare.wso2">
         <ns:return xsi:type="ax21:HCInfo" xmlns:ax21="http://healthcare.wso2/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ax21:address>2583 South Volusia Ave (17-92), Suite 300</ax21:address>
            <ax21:approxDistance>13.1</ax21:approxDistance>
            <ax21:city>Orange City,  FL</ax21:city>
            <ax21:hcCenterName>Orange City CBOC</ax21:hcCenterName>
            <ax21:phone>386-456-2080 Or 386-456-2082</ax21:phone>
         </ns:return>
      </ns:getHCCenterInfoResponse>
      <ns:getHCCenterInfoResponse xmlns:ns="http://healthcare.wso2">
         <ns:return xsi:type="ax21:HCInfo" xmlns:ax21="http://healthcare.wso2/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ax21:address>5201 Raymond Street</ax21:address>
            <ax21:approxDistance>14.1</ax21:approxDistance>
            <ax21:city>Orlando,  FL</ax21:city>
            <ax21:hcCenterName>Orlando VA Medical Center</ax21:hcCenterName>
            <ax21:phone>407-629-1599 Or 800-922-7521</ax21:phone>
         </ns:return>
      </ns:getHCCenterInfoResponse>
      <ns:getHCCenterInfoResponse xmlns:ns="http://healthcare.wso2">
         <ns:return xsi:type="ax21:HCInfo" xmlns:ax21="http://healthcare.wso2/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ax21:address>5575 S. Semoran Blvd. #30</ax21:address>
            <ax21:approxDistance>18.3</ax21:approxDistance>
            <ax21:city>Orlando,  FL</ax21:city>
            <ax21:hcCenterName>Orlando Vet Center</ax21:hcCenterName>
            <ax21:phone>407-857-2800</ax21:phone>
         </ns:return>
      </ns:getHCCenterInfoResponse>
      <ns:getHCCenterInfoResponse xmlns:ns="http://healthcare.wso2">
         <ns:return xsi:type="ax21:HCInfo" xmlns:ax21="http://healthcare.wso2/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ax21:address>805 Oakley Seaver Drive</ax21:address>
            <ax21:approxDistance>28.7</ax21:approxDistance>
            <ax21:city>Clermont,  FL</ax21:city>
            <ax21:hcCenterName>Clermont CBOC</ax21:hcCenterName>
            <ax21:phone>352-536-8200 Or 877-469-9037</ax21:phone>
         </ns:return>
      </ns:getHCCenterInfoResponse>
      <ns:getHCCenterInfoResponse xmlns:ns="http://healthcare.wso2">
         <ns:return xsi:type="ax21:HCInfo" xmlns:ax21="http://healthcare.wso2/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ax21:address>2285 North Central Avenue</ax21:address>
            <ax21:approxDistance>31.5</ax21:approxDistance>
            <ax21:city>Kissimmee,  FL</ax21:city>
            <ax21:hcCenterName>Kissimmee CBOC</ax21:hcCenterName>
            <ax21:phone>407-518-5004</ax21:phone>
         </ns:return>
      </ns:getHCCenterInfoResponse>
   </soapenv:Body>
</soapenv:Envelope>


Let's create the out sequence. In the Manage menu, Go to Web Services -> List and click on HCCService. Click Edit under Specific Configuration to edit the proxy service.
Proceed to step 3 of 3 to create the out sequence as shown below. 



Add a log mediator as shown below.



We will now add an aggregate mediator as shown below. Core -> Aggregate. The purpose of adding the aggregate mediator is to aggregate the messages and compose 1 message. An aggregate mediator usually always follows an iterate mediator, as is the case here.  For more information on aggregate mediators, click here.



Add the following properties for the aggregate mediator as shown in the image.


Aggregation Expression -//hcc:getHCCenterInfoResponse

This is an XPath expression specifying based on which elements to aggregate. 

Completion Max-messages -  -1
Completion Min-messages -  -1


These are the maximum and minimum number of messages that can exist in an aggregation. In this case we specify both as -1 because we want all of the messages to be aggregated and will not specify a max or min number. 


On Complete - Anonymous




Click on the aggregate mediator and add a log mediator.



Give the following properties to the log mediator.



Finally, add a send mediator under the aggregate mediator.


In the send mediator we will not specify an endpoint, thereby sending the message back to the original
sender.


We have now completed the creation of the out sequence, so click on Finish.



We have now completed configuring the set up in the WSO2 ESB. Here's the source view of the HCCService proxy service. 


<proxy xmlns="http://ws.apache.org/ns/synapse" name="HCCService" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <property xmlns:heal="http://healthcare.wso2" name="longitude" expression="//heal:getHealthcareCenterInfo/heal:longitude/text()" scope="default" />
         <property xmlns:heal="http://healthcare.wso2" name="latitude" expression="//heal:getHealthcareCenterInfo/heal:latitude/text()" scope="default" />
         <log level="custom">
            <property name="Longitude" expression="$ctx:longitude" />
            <property name="Latitude" expression="$ctx:latitude" />
         </log>
         <enrich>
            <source type="inline" clone="true">
               <geo:getZipCode xmlns:geo="http://geo.wso2">                        
                  <geo:longitude>0</geo:longitude>                        
                  <geo:latitude>0</geo:latitude>                    
               </geo:getZipCode>
            </source>
            <target type="body" />
         </enrich>
         <enrich>
            <source type="property" clone="true" property="longitude" />
            <target xmlns:geo="http://geo.wso2" xpath="//geo:getZipCode/geo:longitude/text()" />
         </enrich>
         <enrich>
            <source type="property" clone="true" property="latitude" />
            <target xmlns:geo="http://geo.wso2" xpath="//geo:getZipCode/geo:latitude/text()" />
         </enrich>
         <log level="full" />
         <send receive="hcfRequest">
            <endpoint key="GeoEP" />
         </send>
      </inSequence>
      <outSequence>
         <log level="full" />
         <aggregate>
            <completeCondition>
               <messageCount min="-1" max="-1" />
            </completeCondition>
            <onComplete xmlns:hcc="http://healthcare.wso2" expression="//hcc:getHCCenterInfoResponse">
               <log level="full" />
               <send />
            </onComplete>
         </aggregate>
      </outSequence>
   </target>
</proxy>

Testing the Scenario

1) Run the WSO2 ESB with the configurations. 
2) Run the WSO2 Application Server instance that hosts the services created. 
3) Run soapUI and create a soapUI project with the WSDL for the HCCService proxy service, which can be found here











12 comments:

  1. Hi, congratulation for your use case.
    I'm trying to follow your guide, but I have some problem in the end. When I query the proxy with soapUi I don't receive any response and in the ESB console appears this error " ERROR - SynapseXPath Evaluation of the XPath expression //heal:getHealthcareCenterInfo/heal:longitude/text() resulted in an error
    org.jaxen.UnresolvableException: Cannot resolve namespace prefix 'heal' "

    Can you help me to solve the problem?
    I'm new in this environment
    Thanks in advance

    Andrea

    ReplyDelete
    Replies
    1. Hi Andrea,

      Sorry about that. I have missed a step. Click on the namespaces icon that appears in the design view when creating properties etc. Then define prefix heal for the given namespace. e,g, - heal - http://healthcare.wso2

      Delete
  2. Hi,

    this is an useful tutorial for understanding the use of the Enrich mediator.
    Many thanks.
    Cheers.

    warxsg

    ReplyDelete
  3. Fantastic. Thanks a lot for the series.

    ReplyDelete
  4. I do not know much English but this super

    ReplyDelete
  5. Hello Dakshitha, fantastic work. It is really good explained but I'm having some problems testing it. Do you know if WebServices are still working? I hope you can help me. When I test I see that AS prints out on the console next message:

    [2013-06-11 10:50:14,729] ERROR {org.apache.axis2.engine.AxisEngine} - The endp
    oint reference (EPR) for the Operation not found is http://localhost:9763/servic
    es/HCFacilityLocatorService and the WSA Action = null. If this EPR was previousl
    y reachable, please contact the server administrator.
    org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not f
    ound is http://localhost:9763/services/HCFacilityLocatorService and the WSA Acti
    on = null. If this EPR was previously reachable, please contact the server admin
    istrator.
    at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPha
    se.java:102)





    Thank you,


    Joan

    ReplyDelete
  6. i recently start working on WSO2 esb. and this is really a awesome tutorial to understand the full flag esb flow.

    ReplyDelete
  7. wow.. great thanks for your tutorial.. that's very helpful for me.. it's clear now how to use xpath in WSO2ESB..

    ReplyDelete
  8. I'm new to wso2 esb and dss. This tutorial relly helps a lot. I have one quey... in my api , i'm getting response from dss which contains all data of students from dss.. now it want to send all the respone back using iterator and agrigate... can you please help and instruct me. Thanks in advance

    ReplyDelete
  9. Great step by step tutorial, very usefuly who just started with WSO2 ESB, Thank You

    ReplyDelete