Wednesday, March 1, 2017

Add failed endpoint name and address through fault sequence in WSO2 ESB

When generating custom fault sequence messages, one common use case is when you need to send the endpoint name and endpoint address of the failed endpoint back to the client. This can be done by getting the value of two properties which are 'last_endpoint' and 'ENDPOINT_PREFIX'.

However you can't get 'last_endpoint' property value directly as it sends the endpoint object. Therefore you will have to write a class mediator like below and get the value of that endpoint object and set it to a custom property that you have in your fault sequence.

 public boolean mediate(MessageContext mc) {
          // Get 'last_endpoint' property from message context
         AbstractEndpoint failedEP =(AbstractEndpoint)mc.getProperty("last_endpoint");
         // Get name of the failed endpoint
         String failedEPName =  failedEP.getName();
         // Set value to the endpoint name holder in proxy
         mc.setProperty("default_ep", failedEPName);
            return true;
        }

Now you can create your fault sequence like below.

<faultSequence>
         <property name="default_ep" value="default"/>
         <class name="org.test.EPMediator"/>
         <payloadFactory media-type="xml">
            <format>
               <tp:fault xmlns:tp="http://test.com">
                  <tp:message>Error connecting to the backend</tp:message>
                  <tp:description>Endpoint $1 with address $2 failed!</tp:description>
               </tp:fault>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('default_ep')"/>
               <arg evaluator="xml" expression="get-property('ENDPOINT_PREFIX')"/>
            </args>
         </payloadFactory>
        </send>
</faultSequence>

Wednesday, February 15, 2017

Firefox issue with javascript functions directly called on tags

If you try adding a javascript method on a html link like below, You will run into issues when trying out in firefox.

<a href="javascript:functionA();" />

This is because if this functionA returns some value (true/false) other than undefined, it will be appended to the link as a string value , and will try to be rendered which will redirect you to a blank page. Therefore it is always better to add a js function like below.

<a href="#" onclick="functionA();"/>

Sunday, October 9, 2016

Creating a custom mode and worker files in Ace editor

[1] and [2]  contain a good example on how to create your own worker code , and integrating the worker to the mode with a worker client. The problem I faced was  though this content was added to two new files, syntax validation was not working as the worker file was lacking some initial methods that was coming from ace editor itself. So in order to create your custom worker with all those basic methods include this is what you can follow.

Let us assume your custom language is called 'lang1'.
1. Create mode and worker content files with the naming convention a 'lang1.js' and 'lang1_worker.js.
2. Download ace source code from https://github.com/ajaxorg/ace.
3. In ace source code go to '/lib/ace/mode' folder and place your lang1.js and lang1_worker.js files.
4. Build ace source code with command ' node ./Makefile.dryice.js '.(Check github page for instructions)
5. Once successfully built, go to 'build/src' folder and you can find your mode file as 'lang1.js' and your worker file created as 'worker-nel.js'.

Now you can place these files in your source code location and work with them. Do remember to update the worker name to new one,  when creating the worker client.
var worker = new WorkerClient(["lang1"], "lang1/mode/worker-lang1", "Lang1Module");

[1] https://github.com/antlr/antlr4/blob/master/doc/ace-javascript-target.md
[2] https://github.com/ajaxorg/ace/wiki/Syntax-validation

Thursday, September 15, 2016

XSLT stylesheet template to add a namespace with namespace prefix

If you need to write down a xslt stylesheet ,and you need to add a namespace to a certain element with a namespace prefix , you could write a template like below. In this it will add the namespace to <UserRequest> node.

<xsl:template match="UserRequest">
        <!--Define the namespace with namespace prefix ns0 -->
        <xsl:element name="ns0:{local-name()}" namespace="http://sample.org">
            <!--apply to above selected node-->
            <xsl:apply-templates select="node()|@*">
        </xsl:apply-templates></xsl:element>
    </xsl:template>


If you need to add this namespace to <UserRequest> and its child element , the template match should change to below.

<xsl:template match="UserRequest | UserRequest/*">

Handeling namespaces in xpath expressions of WSO2 ESB payload mediator

You could checkout payload factory mediator of WSO2 ESB in https://docs.wso2.com/display/ESB500/PayloadFactory+Mediator.  If you need to provide an xml input that has namespaces (other than default namespace) included, and you need to access some node of this in <args> of payloadFactory mediator you could do it like this with xpath.

 <payloadFactory media-type="xml">
<format key="conf:resources/output.xml"/>
    <args>
      <arg xmlns:ns0="http://sample.org" expression="//ns0:UserRequest" />
    </args>
  </payloadFactory>



Saturday, August 27, 2016

Why are human tasks important for your business process?

Business processes can be considered as workflows ranging from a vacation approval process to a pizza ordering process. With WSO2 Business Process Server , you can easily create these workflows by creating your own BPEL processes.  BPEL is a standard to model your web service orchestration and you read more on it in [1] . In simple terms you can create a BPEL process to interact with different web services getting the responses that you need.  However there are scenarios where everything is not based on just sending a request and getting a response. Some business processes require a human touch.

For example if you consider a leave approving process, you need to send your request to probably your HR manager and wait until he/she approves/rejects your request. Your HR manager might do this right on that day or it could be next week. So until this decision is made, you have to hold back on booking your airline tickets for your vacation. Right? Wouldn't it be nice if you just get notified once the HR manager makes a decision?

Ok , so it is important.... but how to implement this?
Well as a developer  if you were to create a solution with above requirements it will not be an easy task. You need to know when a request was sent, need to make sure that the requests are sent to the correct person, need to keep track on when the HR manager approves/rejects it and finally need to let the employee know about the decision that was made. If it was just about calling a web service yeah sure you can model a BPEL process with few WSDLs but now a real user will be interacting in a step.  So how can we add this human interaction to a BPEL process ?  With WSO2 BPS server this is easily done through human tasks.

Does WSO2 BPS Server make it easy?
[2] is a really good blog on what human tasks are and how you can use it and explains the anatomy behind it with respect to WSO2 BPS. I suggest you first go through it. First you need to create your human task based on WS-HumanTask specification [3].  You can easily create it and deploy in WSO2 BPS which is explained in [4]. Once your human task is all set up, now you need a link to add this human task step into your BPEL process. With the use of  WS-BPEL Extension for People (BPEL4People) specification [5]  you could include your human task interaction to your BPEL process.

But now you might think it is a very tedious task to implement those specifications AND worry about the actual business process creation. But since WSO2 BPS comes with implementations of these specifications you only need to worry about creating those artifacts.

Link human tasks to the BPEL process
For example in your BPEL process when you add a bpel4people step, you could add a remote task partner link defining your human task details, so that once this step is reached, a human task will be created in the human task engine, and the BPEL  process will wait until that task is completed.

 <extensionActivity>
                    <b4p:peopleActivity name="TestTASKPeopleActivity"
                                        inputVariable="b4pInput"
                                        outputVariable="b4pOutput"
                                        isSkipable="no">
                        <b4p:remoteTask partnerLink="b4pPartnerLink"
                                        operation="approve"
                                        responseOperation="approvalResponse">
                        </b4p:remoteTask>
                    </b4p:peopleActivity>
                </extensionActivity>

Create Human Tasks in one go
 If you went through [4] you might feel that creating a human task is a bit of hectic process where you need to create all those files manually. But with WSO2 BPS 3.6.0 that is not the case! Now we have introduced  BPS tooling where you can create your human task in one go and it is really easy. You could check out the basics of this in [6].

Finally now you need to decide how you are going to create the UI for those human tasks?  You can easily create your own API with the admin services that are exposed through WSO2 BPS. Go through [7] for a good explanation on this.


[1] http://wso2.com/library/articles/writing-simple-ws-bpel-process-wso2-bps-apache-ode/
[2]http://wso2.com/library/articles/2012/01/human-tasks-bridging-bits-real-world/
[3] http://docs.oasis-open.org/bpel4people/bpel4people-1.1-spec-cd-09.pdf
[4] https://docs.wso2.com/display/BPS360/Writing+a+Human+Task+Artifact
[5] http://docs.oasis-open.org/bpel4people/ws-humantask-1.1-spec-cd-10.pdf
[6] https://codeoutloud.wordpress.com/2016/06/22/creating-a-human-task-artifact-with-wso2-bps-tooling/
[7] http://nandikajayawardana.blogspot.com/2013/05/how-to-implement-your-own-task-ui-on.html

Wednesday, August 3, 2016

Manually create JWKS_URI for public certificates

A JWK is a JSON representation of a cryptographic key.  More details on this can be found in https://tools.ietf.org/html/rfc7517#section-4. Following blog would give out the steps on how you can manually extract modulus and exponent values of a public certificate , in the format expected in this JWKS_URI.

For this example, we will be trying to extract the values from WSO2 Identity Server's public certificate.

1. Find the public keystore .jks file which is located in <WSO2_IS>/repository/resources/security folder. (wso2carbon.jks)

2. Next step is to extract the public certificate from the keystore, and get the RSAPublic Key of it. For all these steps I will be creating a java client which will be using java.security.KeyStore functions.

 FileInputStream file = new FileInputStream("/Desktop/wso2IS/repository/resources/security/wso2carbon.jks");
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystore.load(file, "wso2carbon".toCharArray());
            String alias = "wso2carbon";
            // Get certificate of public key
            Certificate cert = keystore.getCertificate(alias);
            // Get public key
            publicKey = (RSAPublicKey) cert.getPublicKey();

3. Now that you have the publicKey extracted, you can get the modulus and exponent values.
 like below.
BigInteger n =  publicKey.getModulus();
BigInterger e =  publicKey.getPublicExponent();


 But in order to add these into JWKS_URI format , as explained in [1], you need to have those integer values, base64url encoded in their bigendian format. So for this following code snippets will be used.
Following function can be called, where bytes represents n.toByteArray() and e.toByteArray() accordingly.
base64Encode(bytes, 0, bytes.length, false);
So you could invoke like below.

base64Encode(n.toByteArray(), 0 , n.toByteArray().length,false);
base64Encode(e.toByteArray(), 0 , e.toByteArray().length,false);

 this base64Encode function code will be like below.

 public String base64Encode(final byte[] bytes, final int offset, final int length, final boolean padding) {
        final StringBuilder buffer = new StringBuilder(length * 3);
        for (int i = offset; i < offset + length; i += 3) {

            int p0 = bytes[i] & 0xFC;
            p0 >>= 2;

            int p1 = bytes[i] & 0x03;
            p1 <<= 4;

            int p2;
            int p3;
            if (i + 1 < offset + length) {
                p2 = bytes[i + 1] & 0xF0;
                p2 >>= 4;
                p3 = bytes[i + 1] & 0x0F;
                p3 <<= 2;
            } else {
                p2 = 0;
                p3 = 0;
            }
            int p4;
            int p5;
            if (i + 2 < offset + length) {
                p4 = bytes[i + 2] & 0xC0;
                p4 >>= 6;
                p5 = bytes[i + 2] & 0x3F;
            } else {
                p4 = 0;
                p5 = 0;
            }

            if (i + 2 < offset + length) {
                buffer.append(ENCODE_MAP[p0]);
                buffer.append(ENCODE_MAP[p1 | p2]);
                buffer.append(ENCODE_MAP[p3 | p4]);
                buffer.append(ENCODE_MAP[p5]);
            } else if (i + 1 < offset + length) {
                buffer.append(ENCODE_MAP[p0]);
                buffer.append(ENCODE_MAP[p1 | p2]);
                buffer.append(ENCODE_MAP[p3]);
                if (padding) {
                    buffer.append('=');
                }
            } else {
                buffer.append(ENCODE_MAP[p0]);
                buffer.append(ENCODE_MAP[p1 | p2]);
                if (padding) {
                    buffer.append("==");
                }
            }
        }
        return buffer.toString();
    }
This code block will convert the exponent and modulus values to their big endian format, and finally encode them. ENCODE_MAP value will be "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray();

After you get these value in proper format, you can look into [1] and create the json representation as required.

[1] https://tools.ietf.org/html/rfc7517#section-4.