Saturday, March 19, 2016

Pass Dynamic Values through Class Mediator in ESB Connector methods

In this post, let's discuss how we can pass a dynamic number of arguments  to connector methods, Normally we work with pre-defined parameters in connector  but here let's see how we can pass dynamic parameters with dynamic value and name and how we can use inside the connector method.

There are two types of actions we can do to get dynamic parameters. First one is set some key values and get the values start with that key value another method is through some pre-defined keywords.
Our regular synapse properties to send the parameters to connector method through a class mediator.

<template xmlns="http://ws.apache.org/ns/synapse" name="createFeed">
    <parameter name="HostAddress" description="HostAddress of the feed server"/>
    <parameter name="Title" description="Title of the feed entry"/>
    <parameter name="Content" description="Content of the feed entry"/>
    <parameter name="Author" description="Author of the feed entry"/>
    <parameter name="FeedID" description="FeedID of the feed entry"/>
    <sequence>
        <class name="org.wso2.carbon.connector.FeedCreation"/>
    </sequence>
</template>

In the above case, we know the number of parameters and the name of the parameters  but there are some cases we don't know the number of parameters and the name of te parameter(In EJB parameter name will vary depend on the backend server eg:JBoss Glassfish).

here is the example method to call init operation and to perform the method I need to create jndiProperties  but the property name and value will vary so here I 'm using the first approach  that setting a key value.
<ejbconnector.init>
    <key>raj</key>
    <raj.java.naming.factory.initial>com.sun.enterprise.naming.SerialInitContextFactory</raj.java.naming.factory.initial>
    <raj.org.omg.CORBA.ORBInitialHost>localhost</raj.org.omg.CORBA.ORBInitialHost>
    <raj.org.omg.CORBA.ORBInitialPort>3700</raj.org.omg.CORBA.ORBInitialPort>
</ejbconnector.init>

This is to call other operations. Normally we don't know how many methods user going to call while in the integration scenario so able to add parameters. here we are using pre-defined keyword call param, So when we add arguments we start the name with the keyword so we can identify at the code level.
<ejbconnector.stateless>
    <jndiName>HelloBean</jndiName>
    <method>sayHello</method>
    <param.arg1>Rajjaz</param.arg1>
</ejbconnector.stateless>
<ejbconnector.stateless>
    <jndiName>HelloBean</jndiName>
    <method>sayHello</method>
    <return>out</return>
</ejbconnector.stateless>

This is the code level implementation to get the parameters. Here we are checking two type of approaches first one is to get the values using user defined key values and the second one is to get the values from pre-defined keywords.

    public static Hashtable getParameters(MessageContext messageContext, String operationName) {
        Hashtable dynamicValues = new Hashtable();
        String key;
        if (operationName.equals(EJBConstants.INIT)) {
            key = ((String) getParameter(messageContext, EJBConstants.KEY));
        } else {
            key = EJBConstants.PARAMETER;
        }
        key = operationName + ":" + key;
        Map<String, Object> propertiesMap = (((Axis2MessageContext) messageContext).getProperties());
        Set prop = messageContext.getPropertyKeySet();
        Value probValues;
        for (String stringValue : (String[]) prop.toArray(new String[prop.size()])) {
            if (stringValue.startsWith(key)) {
                probValues = (Value) propertiesMap.get(stringValue);
                dynamicValues.put(stringValue.substring(key.length() + 1, stringValue.length())
                        , probValues.getKeyValue());
                messageContext.getPropertyKeySet().remove(stringValue);
            }
        }
        return dynamicValues;
}

Above code will return Hashtable wich contains the parameter name and value so easily we can use in our code level