Monday, July 27, 2015

Array creation in BPEL

Most of the time, the input/requests we get in BPEL responses are not simple one line values. They can be complex xsd files where , data schema are used. In a situation like that, you need to handle the input payload, manipulate the content and present the values in the form of arrays.  So let us consider this example below.



In this example, I'm getting an input from the client/user (which will be a multiple set of string values). I need to get this list of values, loop through them (you can add your additional business logic/conditions here) and finally create an array with that value set.

In the first assign step I will be initializing a counter variable in order to loop the values ,and inside the while loop I'm adding each property to an array(Assign1) and incrementing the counter variable(Assign2).  Let us see how we can add the logic to these steps.

1.  These are my request and response properties. (Which are considered in receiveInput and replyOutput steps accordingly)

  <element name="ArrayCheckRequest">
                <complexType>
                    <sequence>
                        <element name="input" type="string" maxOccurs="unbounded"/>
                    </sequence>
                </complexType>
            </element>

            <element name="ArrayCheckResponse">
                <complexType>
                    <sequence>
                        <element name="result" type="string" maxOccurs="unbounded"/>
                    </sequence>
                </complexType>
            </element>

What you need to remember here is that since I'm expecting a multiple set of values( set of string values in this case) I need to make sure that I allow the input property to have multiple values. This is done by setting the maxOccurs property to unbounded.  I have done the same for my final response as well, since i will be sending out an array.

2. Assign :   In the first assign step property details, I'm initializing a counter variable so that I can loop through the values later. In the second copy element, I'm initializing the result variable of the final response.

<bpel:assign validate="no" name="Assign">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>1</bpel:literal>
                </bpel:from>
                <bpel:to variable="counter"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <tns:ArrayCheckResponse xmlns:tns="http://wso2.org/bps/sample"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <tns:result>tns:result</tns:result>
                        </tns:ArrayCheckResponse>
                    </bpel:literal>
                </bpel:from>
                <bpel:to part="payload" variable="output"></bpel:to>
            </bpel:copy>
        </bpel:assign>
Things to Note: I was wasting lot of time when i first created this sample, because I missed out two points.

*. In xpath, array indexing starts from 1 instead of 0 as our usual understanding in Java. So when initializing a counter variable make sure it starts from 1.
*. Before, I was initializing the result variable within the while loop. Because of this, my final response always included only the last value, as it was getting reinitialized at every loop instance. So make sure that this is done outside and before the while loop.

3. While: Following is the condition of the while loop. Again note, since indexing is happening from 1, you need to add = sign as well. I'm using the xpath function count() to get the total occurrence of the input list.

$counter <= count($input.payload/tns:input)

4.Assign1 : Here we are using an ODE xpath function, which requires Xpath 2.0. So make sure you add xpath Language and expression language definitions as it is done below. Else this ode method will not be recognized.


<bpel:copy>
                        <bpel:from expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"
                            queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0">
                            <![CDATA[ode:insert-as-last-into($output.payload/tns:result, $input.payload/tns:input[round($counter)])]]>
                        </bpel:from>
                        <bpel:to part="payload" variable="output">
                            <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:result]]></bpel:query>
                        </bpel:to>

Also make sure you add the namespace for ode at the top of bpel process definition.

xmlns:ode="http://www.apache.org/ode/type/extension"

5.Assign2 : In this step you need to increment the counter variable like below.

<bpel:assign validate="no" name="Assign2">
                    <bpel:copy>
                        <bpel:from expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                            <![CDATA[$counter + 1]]>
                        </bpel:from>
                        <bpel:to variable="counter"></bpel:to>
                    </bpel:copy>
                </bpel:assign>



Friday, July 24, 2015

Adding a new certificate to WSO2 IS Service Provider creation

When adding a new Service Provider(sp) in wso2 Identity Server, to add your security certificates, there is only a drop down box with existing certificate alias names. So in order to insert a custom certificate to this list, you can go through following.

1.Create a .pem file that has the content of your certificate. It should be in following format.

-----BEGIN CERTIFICATE-----
..Add content of xf09certificate...
-----END CERTIFICATE-----


2. Go to <IS_HOME>/respository/resources/security folder and take a backup of wso2carbon.js.
3. From your terminal, go to above folder location and add below command, which will import your certificate to the keystore. In this example, I'm trying to add sample.pem file with the alias sampleCertificate.

 keytool -import -alias sampleCertificate -file sample.pem -keystore wso2carbon.jks -storepass wso2carbon

3. Once this command is executed, it will ask to Trust the store, enter yes for that question, and you should get a message like below.

'new file added to truststore'

4. Now once you restart IS server, and go to add new Service Provider page, your new file will be listed from it's alias name.


note: If your .pem file is corrupted/ invalid you will get errors at step 3 so make sure your certificate is valid.


Wednesday, July 15, 2015

WSO2 BPS Cluster Guide

Following is a very detailed and easy to understand guide on BPS clustering which also includes information on best practices of BPS cluster deployment.


http://nandikajayawardana.blogspot.com/2014/02/how-to-cluster-wso2-bps-320.html

Tuesday, July 7, 2015

Configuring timeouts with WSO2 ESB

When dealing with proxies/sequences built in wso2 ESB, a common case is if the BE service is not responding for a long time time outs occurs.  So you may need to show some reasonable error logs to a customer on such timeouts.  What you can do is configure a timeout and add an onError fault sequence to be executed.

Let us look at following sample.

         <endpoint>
            <address uri="http://localhost:9000/services/SimpleStockQuoteService">
               <timeout>
                  <duration>10000</duration>
                  <responseAction>fault</responseAction>
               </timeout>
               <suspendOnFailure>
                  <errorCodes>-1</errorCodes>
                  <initialDuration>0</initialDuration>
                  <progressionFactor>0.0</progressionFactor>
                  <maximumDuration>0</maximumDuration>
               </suspendOnFailure>
               <markForSuspension>
                  <errorCodes>101505,101504</errorCodes>
               </markForSuspension>

            </address>
         </endpoint>
         This is an endpoint declaration in a sample proxy, and i'm setting an endpoint timeout of 10 seconds for it. By setting the responseAction property to fault, on timeout it will invoke the fault sequence defined.  markForSuspension tag basically directly marks this endpoint as suspended if the provided errorCode (errors) occur. suspendFailure tag option can be configured so that when certain error code based error occurs, you can retry those requests before sending the endpoint to suspended state. You can gain more insight on this by going through [1].

The point I need to bring out here is , if you need to set the timeout to happen for something less than 15 seconds. In practice such a small timeout is not recommended because a normal endpoint callback would at least take 30 seconds. But in a situation where you need to update the endpoint to timeout in within a small time limit, you need to remember to configure following values.

There is a TimeoutHandler that is executed in an interval of 15 seconds. So the time the callbacks get cleared , can be deviated up to 15
seconds from the value you configure as endpoint timeout(in your proxy configuration). So say that you declare your endpoint timeout as 10 seconds, this will only be taken into count after this initial 15 seconds interval. So if you need it to timeout within 10 seconds , you have to declare following properties as well.  

(These files can be found in repository/conf)
http.socket.timeout=30000  (passthru-http.properties- depending on your transport type this can be nhttp.properties)
synapse.global_timeout_interval=20000 (synapse.properties)
synapse.timeout_handler_interval=5000 (synapse.properties)
<duration>10000</duration> ( in your proxy configuration)

The values should be configured that duration <= http.scoket.timeout .  You can go through [2] to gain more info on this.

[1] https://docs.wso2.com/display/ESB481/Endpoint+Error+Handling
[2]http://wso2.com/files/WSO2ESB-ATroubleshootGuide.pdf