Friday 22 November 2019

Esql vs Java

ESQL vs Java in IIB/ACE


This blog compares two languages that are used in IIB to write transformation logic. 


Many a times there arrives a situation where one thinks which one is better to use, ESQL or Java. A java developer always gives preference to writing in Java where as a person who knows IIB prefers ESQL. 

Here I am going to compare ESQL with Java and explain some of the things based on my personal experience so that one would be able to decide which one can be used.

In reality, there is no hard and fast rule that ESQL is preferred than Java or vice versa. It all depends on the comfort level of the developer and requirements.

If you ask me, I know both Java and ESQL and having worked on both of them, I would always prefer ESQL over Java in most of the cases and go with Java only if one needs to write complex logic in ESQL which can be easily achieve in Java.


Below I will be talking in detail with respect to the following parameters. This is purely based on my learning and experience and there can be many more parameters that are available. 


1. Performance: With respect to performance, there is no major difference between ESQL and Java. The only difference that I can think of is that there will be a context switching that happens whenever Java compute node is called as ESQL is written in C and java is JVM based. So when a messages moves from message flow to java compute node context switching happens leading to a little overhead.

2. Routing: If you ever have a requirement where you need to route to more than 2 targets or to two nodes compute node is always preferable as Java compute node has only two terminals (out and alt) whereas in compute you have 5 out terminals(out, out1, out2, out3, out4) along with propagating to label options. 

Hence if routing is needed for more than 2, use compute else you can opt for Java/ESQL.

3. Labelled loops: In some scenarios, there might be situations where one has to exit the loop if a certain condition is satisfied for which one makes use of labels in while loop or for loop.

  Labelled while loop is supported both in ESQL and Java, but Labelled for loop is supported only in Java but not ESQL. So if you want to use Labelled for loop you have to opt for Java only.

4. Data Propagation: In compute node, user has to option to propagate message, message and local environment, localenvironment, Exception, Exception & message, Exception and localenvironment, All. Depending on the requirement, user can select any one of the above option from the dropdown. 

In case of Java compute node, there is no such option available, by default all data gets propagated from its out terminal.

5. ESQL functionalities: ESQL has SELECT statement which is very powerful,which can be applied to messages and databases but no such statement exists in Java. So you can chose which one to use again depending on your requirement. Be careful while using SELECT statement for large payload data as one needs to consider performance factor as well before making a decision on this

6. Regular Expressions: There is a good support available for regular expression in Java but in esql one needs to write complex logic or algorithm to achieve this. So if you requirement has regular expressions that needs to be implemented it is better to go with Java than ESQL.

7. Sorting: There is no inbuilt sorting functionality available in ESQL and one needs to write algorithm to achieve this. In case of java, sorting can be easily achieved. Again the sorting can also be achieved for XML messages using XSLT or by interacting with DB and allowing DB to sort and send back the result. But these are rare case requirement. If you have option of selecting between ESQL and java for sorting, go for Java.

8. Exception Handling: As usual, everyone knows that in java its easy to capture exception message directly by using inbuilt functions whereas in ESQL, you need to traverse through the exception list for retrieving the exception details. I have just mentioned this point to show the difference between Java and ESQL but in my view this is not a factor for deciding if you want to for ESQL or Java.

9. Shared Variables: Shared variables can be created in ESQL but cannot be accessed in java. This is based on my experience so far where I could not find a way to retrieve shared variables in java so far. If any one has a way to retrieve it, please comment on this so that I can correct this. 


I will keep updating this blog once i figure out more differences between java and ESQL. For now the above mentioned ones is what I have.

Thursday 17 January 2019

APP Connect V11 Software Download

https://www-01.ibm.com/marketing/iwm/iwm/web/pickUrxNew.do?source=swg-wmbfd&transactionid=451565821

Sort the Alphabet or String In ESQL

InPutMessage :

<Roots>
<Names>
<Name>Venkat</Name>
</Names>
<Names>
<Name>Krishna</Name>
</Names>
<Names>
<Name>Rathod</Name>
</Names>

</Roots>




ESQL LOGIC :



CREATE COMPUTE MODULE AlphabetSorting_MF_LogicTOSortAlphabet
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN

DECLARE Names INTEGER 1;
DECLARE  rInputMessage REFERENCE TO InputRoot.XMLNSC.Roots.Names[1];
WHILE LASTMOVE(rInputMessage)  DO
SET Environment.Variables.Names[Names] =  rInputMessage.Name;
SET Names = Names +1;
MOVE rInputMessage NEXTSIBLING REPEAT TYPE NAME;
END WHILE;

DECLARE n INTEGER CARDINALITY(Environment.Variables.Names[]);

DECLARE i INTEGER 1;
DECLARE temp CHARACTER;

WHILE i < n DO
SET i = i +1;
DECLARE j INTEGER 1;
WHILE j < n DO
SET j = j + 1;
DECLARE IntName1 CHARACTER UPPER(Environment.Variables.Names[j-1]);
DECLARE IntName2 CHARACTER UPPER(Environment.Variables.Names[j]);
DECLARE NameConstatnt INTEGER;

IF IntName1 = IntName2 THEN
SET NameConstatnt = 0;
ELSEIF  IntName1 > IntName2 THEN
SET NameConstatnt = 1;
ELSEIF IntName1 < IntName2 THEN
SET NameConstatnt = -1;
END IF;

IF (NameConstatnt > 0 ) THEN
SET temp = Environment.Variables.Names[j-1];
SET Environment.Variables.Names[j-1] = Environment.Variables.Names[j];
SET Environment.Variables.Names[j] = temp;
END IF;
END WHILE;

END WHILE;

END;


END MODULE;





Tuesday 15 January 2019

Aggreegation - ParallelCall


If we are using queue prefixes then we can use the below command to create the Configurable service:


mqsicreateconfigurableservice IB9NODE -c Aggregation -o myAggregationService 
-n queuePrefix,timeoutSeconds -v AGGRPOC,60 

1.myAggregationService :  This is name where we need to provide for AggregateControl and AggregateReply Node property 

2. AGGRPOC : This is the queue name where we need to create the new system queue .

SYSTEM.BROKER.AGGR.AGGRPOC.CONTROL
SYSTEM.BROKER.AGGR.AGGRPOC.REPLY
SYSTEM.BROKER.AGGR.AGGRPOC.REQUEST
SYSTEM.BROKER.AGGR.AGGRPOC.UNKNOWN
SYSTEM.BROKER.AGGR.AGGRPOC.TIMEOUT



1.Aggregation_FanOut_MF.msgflow

Before  or AFter AggregateControlNode :

SET OutputRoot.XMLNSC = InputRoot.XMLNSC;
CREATE LASTCHILD OF Environment NAME 'Variables';
DECLARE rEnv REFERENCE TO Environment.Variables;

SET rEnv.HTTPRequestIdentifier = InputLocalEnvironment.Destination.HTTP.RequestIdentifier;
SET rEnv.transactionId = InputRoot.XMLNSC.*:membershipRequest.*:eieHeader.*:transactionID;

SET OutputRoot.HTTPInputHeader = NULL;
SET OutputRoot.HTTPRequestHeader = NULL;
SET OutputRoot.HTTPResponseHeader = NULL;
SET OutputRoot.MQMD = NULL;
SET OutputRoot.Properties = InputRoot.Properties;

CREATE NEXTSIBLING OF OutputRoot.Properties DOMAIN 'MQMD';
SET OutputRoot.MQMD.Version = MQMD_CURRENT_VERSION;
SET OutputRoot.MQMD.Format = 'MQRFH2 ';
CREATE NEXTSIBLING OF OutputRoot.MQMD DOMAIN 'MQRFH2';
SET OutputRoot.MQRFH2.(MQRFH2.Field)Version = 2;
SET OutputRoot.MQRFH2.(MQRFH2.Field)Format = 'MQSTR ';
SET OutputRoot.MQRFH2.psc.HTTPRequestIdentifier = rEnv.HTTPRequestIdentifier;
SET OutputRoot.MQRFH2.psc.TransactionIdentifier = rEnv.transactionId;
SET OutputRoot.MQRFH2.psc.inputmsg = InputRoot.XMLNSC.*:membershipRequest;

RETURN TRUE;


--Backend Call Flow

1st Compute node before WS call


CREATE FIELD Environment.Variables;
DECLARE rEnv REFERENCE TO Environment.Variables;
SET rEnv.Properties            = InputRoot.Properties;
    SET rEnv.MQMD                  = InputRoot.MQMD;
    SET rEnv.MQRFH2                = InputRoot.MQRFH2;
    SET rEnv.HTTPRequestIdentifier = InputRoot.MQRFH2.psc.HTTPRequestIdentifier;

    SET rEnv.TransactionIdentifier = InputRoot.MQRFH2.psc.TransactionIdentifier;
SET rEnv.inputmsg    = InputRoot.MQRFH2.psc.inputmsg;
SET OutputRoot.Properties = InputProperties;
-- SET OutputLocalEnvironment = InputLocalEnvironment;

SET OutputRoot.HTTPRequestHeader.Host = 'abc.xyz.com';
SET OutputRoot.HTTPRequestHeader."Accept-Encoding" = 'gzip';
SET OutputRoot.HTTPRequestHeader."Content-Type" = 'application/xml';


SET OutputRoot.XMLNSC = NULL;

                 Construct the request message as per requirement


2nd ComputeNode After WS call :

DECLARE rEnv REFERENCE TO Environment.Variables;
SET OutputLocalEnvironment = InputLocalEnvironment;


SET OutputRoot.MQMD = rEnv.MQMD;
SET OutputRoot.MQMD.CorrelId = rEnv.MQMD.MsgId;
SET OutputRoot.MQRFH2 = rEnv.MQRFH2;
SET OutputRoot.MQRFH2.psc.HTTPRequestIdentifier = rEnv.HTTPRequestIdentifier;
SET OutputRoot.MQRFH2.psc.TransactionIdentifier = rEnv.TransactionIdentifier;
SET OutputRoot.MQRFH2.psc.inputmsg = rEnv.inputmsg;
--SET OutputRoot.MQRFH2.psc.Accesstoken = Environment.Variable.AccessToken;
SET OutputRoot.XMLNSC = InputRoot.XMLNSC;

RETURN TRUE;

AggregateFanIn Flow :

After AggreegateReply an Before HTTPreply Node:


                SET OutputRoot.Properties = InputProperties;

SET OutputRoot.Properties.ReplyProtocol = '';
SET OutputRoot.Properties.Encoding = 546;
SET OutputRoot.Properties.CodedCharSetId = 1208;
SET OutputRoot.Properties.Transactional = false;
SET OutputRoot.Properties.Persistence = false;
SET OutputRoot.Properties.ReplyProtocol = 'SOAP-HTTP';

SET OutputLocalEnvironment = InputLocalEnvironment;

SET Environment.HTTPRequestIdentifier  =  InputRoot.ComIbmAggregateReplyBody.Request1.MQRFH2.psc.HTTPRequestIdentifier;

SET OutputRoot.Properties.ReplyIdentifier = CAST(Environment.HTTPRequestIdentifier AS BLOB);
SET OutputRoot.Properties.ContentType = 'application/xml';
SET OutputLocalEnvironment.Destination.HTTP.RequestIdentifier = CAST(Environment.HTTPRequestIdentifier AS BLOB);

SET OutputRoot.XMLNSC.FinalResponse.IMI = InputRoot.ComIbmAggregateReplyBody.Request1.XMLNSC.*:GetIndividualDetailsRes;

SET OutputRoot.XMLNSC.FinalResponse.CommunicationPreference = InputRoot.ComIbmAggregateReplyBody.Request2.XMLNSC;