Cryptography in IIB

Not often but sometimes, there is a need to encrypt and decrypt messages flowing through IBM Integration Bus and there are some working solutions available in the market to achieve the same.

Since these algorithms are not available by default in ESQL, the next immediate solution is Java. So, if you are comfortable with Java Compute Node and know how to pick the Key from multiple locations like the below , then it is scalable and works like the same way as built-in nodes

  • User Defined Property
  • LocalEnvironment
  • Environment
  • Any other valid location in the Message Assembly

Here is a solution which uses AES algorithm to encrypt and decrypt the messages. All you need is 16bytes KEY.

Test flow

The KEY can be hard coded or its location can be $LocalEnvironment/Destination/Encrypt/Key or any other path which can be defined here

Now, this makes flexible that the KEY can be inside the incoming message or from LocalEnvironment or from Environment tree too.

Let us see how the encrypted message looks like after passing a simple XML file like below

Test message
Debugger
After Encryption Node
Encrypted Message
Decrypted Message in OUT Queue

If you are looking for the same solution or would like to know our capabilities in IIB, please contact us at support@vaithu.com/WhatsApp +1 6123058684.

We’ve rich experience in IIB and executed multiple projects since 2013. So, we assure that you get your solution on time in low cost without compromising on quality and efficiency.

IBM Integration API – What shall I get from this?

  • Are you a serious IIB developer/admin?
  • Are you switching with multiple applications/windows back & forth?
  • Are you not a fan of commands ?

Yes. Yes. Yes. We were also looking for some sort of way to get most of our stuff done with some simple clicks/buttons. So, we started looking the ways to achieve it and finally found this IBM Integration API which contains everything you & we needed.

Let us put here some high level things that you can get from this API

  • List all
    • messages flows/applications/static/shared libraries
    • UDPs
    • Queues used
    • Security Identities used
    • DSNs
    • Bar files
    • Integration Server properties
    • Configurable Services
    • Activity Log
    • Administrative Log
    • SubFlows
  • Stop/Start
    • Message Flow
    • Application
    • Integration Server
  • Deploy/Undeploy bar files
  • Update/Modify/Create Configurable service
  • Update UDPs
  • Set Workload Management Properties

Most of the above features might be available from Web UI but it does contain have a way to search. Also, it does not allow to copy one bar file from one environment to another. But when you know the above stuffs to do programmatically, you can do what ever you need.

import com.ibm.broker.config.proxy.*;
public class DeployBAR {

  public static void main(String[] args) {
    BrokerConnectionParameters bcp =
       new MQBrokerConnectionParameters("localhost", 2414, "IB9QMGR");
    try {
      BrokerProxy b = BrokerProxy.getInstance(bcp);
      ExecutionGroupProxy eg = b.getExecutionGroupByName("default");
      DeployResult dr = eg.deploy("MyBAR.bar", true, 30000);
      System.out.println("Result = "+dr.getCompletionCode());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

You can copy everything from one server and put it in another server. You can cross verify what is in multiple environments and much more can be done easily.

If you want to know more about this, we take training on these periodically. Join one of our training and control the Node as you wish. For more details, contact us at support@vaithu.com/WhatsApp +1 6123058684.

MQEdit-Web-based RFHUtil

Are you using RFHUtil but looking for some alternatives for

  • Editing the message on the fly
  • PrettyPrint XML/JSON messages
  • List All queue details with human understandable format
  • Purge selective messages
  • Move messages from one queue manager to another
  • Move selective messages
  • Create Queue
  • Queue Properties
  • Search Queues
  • Read message from two different queue from the same window
  • Get description of the MQ Return Code
  • Trigger N messages at a time for load testing
  • And many more

Yes. We were also looking for the same and so built a tool to help you improve your productivity and lessen the development/testing time. This tool has most of the sought features available in RFHUtil. Here is the video demonstrating the features and how to use this tool.

This is tool is a web-based tool and so works on all platforms. All you need is to run the below command and open a browser,type localhost:8080

java -jar mqedit-1.0-SNAPSHOT.jar
Main Page

You can put all your queue manager configuration details like in a text file and put them in your user’s directory

IIBv10QMGR;LOCALHOST;1414;SYSTEM.DEF.SVRCONN

To purchase this software, please contact us at support@vaithu.com.

For immediate response, you can WhatsApp us at +1 6123058684.

Vaadin Lazy Loading issues

I’ve a grid like this and if I edit the description column it throws error “java.lang.IndexOutOfBoundsException: Index: 0, Size: 0”.

It happens when there is only one matching value in the combobox filter. The combobox looks like this

The dataprovider used is

CallbackDataProvider<String, String> descDataProvider
                = DataProvider.fromFilteringCallbacks(query -> {
            String filter = query.getFilter().orElse("");
            datastore.query(Product.TARGET)
                    .restrict(query.getLimit(), query.getOffset())
                    .stream(Product.DESCRIPTION)
                    .filter(s -> StringUtils.startsWithIgnoreCase(s,filter))
                    .forEach(s -> System.out.print(s+"\t"));
            Stream<String> propertyBoxStream = datastore.query(Product.TARGET)
                    .restrict(query.getLimit(), query.getOffset())
                    .stream(Product.DESCRIPTION)
                    .filter(s -> StringUtils.startsWithIgnoreCase(s,filter));
                           // s -> s.startsWith(filter)
            return propertyBoxStream;
        }, query -> {
            String filter = query.getFilter().orElse("");
            long propertyBoxStream = datastore.query(Product.TARGET)
//                    .filter(Product.DESCRIPTION.startsWithIgnoreCase(filter))
//                    .filter(Product.DESCRIPTION.startsWithIgnoreCase(filter))
                    .stream(Product.DESCRIPTION)
            .filter(s -> StringUtils.startsWithIgnoreCase(s,filter))
                    .count();
            write("filter " + filter+"\t count :"+propertyBoxStream);
            return (int) propertyBoxStream;
        });

and the stacktrace is

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
	at java.util.ArrayList.rangeCheck(ArrayList.java:653) ~[na:1.8.0_131]
	at java.util.ArrayList.get(ArrayList.java:429) ~[na:1.8.0_131]
	at com.vaadin.flow.data.provider.DataCommunicator.lambda$getJsonItems$3(DataCommunicator.java:615) ~[flow-data-2.2.2.jar:2.2.2]
	at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250) ~[na:1.8.0_131]
	at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110) ~[na:1.8.0_131]
	at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693) ~[na:1.8.0_131]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_131]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_131]
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_131]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_131]
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_131]
	at com.vaadin.flow.data.provider.DataCommunicator.getJsonItems(DataCommunicator.java:617) ~[flow-data-2.2.2.jar:2.2.2]
	at com.vaadin.flow.data.provider.DataCommunicator.collectChangesToSend(DataCommunicator.java:560) ~[flow-data-2.2.2.jar:2.2.2]
	at com.vaadin.flow.data.provider.DataCommunicator.flush(DataCommunicator.java:477) ~[flow-data-2.2.2.jar:2.2.2]
	at com.vaadin.flow.data.provider.DataCommunicator.lambda$requestFlush$2f364bb9$1(DataCommunicator.java:425) ~[flow-data-2.2.2.jar:2.2.2]
	at com.vaadin.flow.internal.StateTree.lambda$runExecutionsBeforeClientResponse$1(StateTree.java:368) ~[flow-server-2.2.2.jar:2.2.2]
	at java.util.ArrayList.forEach(ArrayList.java:1249) ~[na:1.8.0_131]
	at com.vaadin.flow.internal.StateTree.runExecutionsBeforeClientResponse(StateTree.java:365) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.communication.UidlWriter.encodeChanges(UidlWriter.java:411) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.communication.UidlWriter.createUidl(UidlWriter.java:187) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:121) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1545) ~[flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:247) [flow-server-2.2.2.jar:2.2.2]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:120) [vaadin-spring-12.2.0.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.27.jar:9.0.27]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]

I do not know what is the problem and why it fails when there is only one matching value. If you know any solution, please put in the comments below.

Audit Logging using Log4j in IIB

Every project has its own way to capture the logs and they are mostly falls under one of these categories

  • Subflows
  • Monitoring Profiles

And these logs are stored either as files or in database tables. So, here I’m going to explain how to use Log4j to capture the logs from monitoring profiles. Note, we’re not going to use Log4j node but instead we use a simple log4j configuration file and some java code to capture all the elements available from the monitoring profiles.

Let us take a simple flow to understand.

And the monitoring configurations for MQInput Node are

So, the monitoring profile is ready and I’m going to use MQTT instead of MQ to get the monitoring event messages.

To test MQTT is enabled to accept Monitoring Events
To get MQTT port number

MQTT is enabled and the port number is 11884. Let us test the monitoring profile configured and see how the event message looks like.

MQ client to trigger message
MQTT client to view subscribed message

The event monitoring messages are published in topic IBM/IntegrationBus/IB10NODE/Monitoring/default/# and the message looks like

<wmb:event xmlns:wmb="http://www.ibm.com/xmlns/prod/websphere/messagebroker/6.1.0/monitoring/event">
   <wmb:eventPointData>
      <wmb:eventData wmb:productVersion="100011" wmb:eventSchemaVersion="6.1.0.3" wmb:eventSourceAddress="MQ Input.transaction.Start">
         <wmb:eventIdentity wmb:eventName="OrderReceived"/>
         <wmb:eventSequence wmb:creationTime="2020-06-01T02:02:32.402892Z" wmb:counter="1"/>
         <wmb:eventCorrelation wmb:localTransactionId="f8a1af6d-013b-4420-9c1b-baf23d5e10a4-5" wmb:parentTransactionId="" wmb:globalTransactionId=""/>
      </wmb:eventData>
      <wmb:messageFlowData>
         <wmb:broker wmb:name="IB10NODE" wmb:UUID="b7d2e6dd-0b36-4728-9015-818133dbeb14"/>
         <wmb:executionGroup wmb:name="default" wmb:UUID="61704de3-b47c-4b23-b95f-0ffd934fdcb1"/>
         <wmb:messageFlow wmb:uniqueFlowName="IB10NODE.default.TestMon.TestMon" wmb:name="TestMon" wmb:UUID="429ff9ef-1c8d-48c1-bf42-99ac3bd247fb" wmb:threadId="21980"/>
         <wmb:node wmb:nodeLabel="MQ Input" wmb:nodeType="ComIbmMQInputNode" wmb:detail="IN.Q"/>
      </wmb:messageFlowData>
   </wmb:eventPointData>
   <wmb:applicationData xmlns="">
      <wmb:complexContent wmb:elementName="MQMD">
         <MQMD>
            <SourceQueue>IN.Q</SourceQueue>
            <Transactional>true</Transactional>
            <Encoding>273</Encoding>
            <CodedCharSetId>1208</CodedCharSetId>
            <Format>MQSTR   </Format>
            <Version>2</Version>
            <Report>0</Report>
            <MsgType>8</MsgType>
            <Expiry>-1</Expiry>
            <Feedback>0</Feedback>
            <Priority>0</Priority>
            <Persistence>0</Persistence>
            <MsgId>414d5120494942763130514d475220204064d15e10000105</MsgId>
            <CorrelId>000000000000000000000000000000000000000000000000</CorrelId>
            <BackoutCount>0</BackoutCount>
            <ReplyToQ>                                                </ReplyToQ>
            <ReplyToQMgr>IIBv10QMGR                                      </ReplyToQMgr>
            <UserIdentifier>vaithu      </UserIdentifier>
            <AccountingToken>160105150000002d74cc5dfa721e73431607412b32030000000000000000000b</AccountingToken>
            <ApplIdentityData>                                </ApplIdentityData>
            <PutApplType>28</PutApplType>
            <PutApplName>vaithu</PutApplName>
            <PutDate>2020-06-01</PutDate>
            <PutTime>02:02:32.480</PutTime>
            <ApplOriginData>    </ApplOriginData>
            <GroupId>000000000000000000000000000000000000000000000000</GroupId>
            <MsgSeqNumber>1</MsgSeqNumber>
            <Offset>0</Offset>
            <MsgFlags>0</MsgFlags>
            <OriginalLength>-1</OriginalLength>
         </MQMD>
      </wmb:complexContent>
   </wmb:applicationData>
   <wmb:bitstreamData>
      <wmb:bitstream wmb:encoding="base64Binary">TUQgIAIAAAAAAAAACAAAAP////8AAAAAEQEAALgEAABNUVNUUiAgIAAAAAAAAAAAQU1RIElJQnYxMFFNR1IgIEBk0V4QAAEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElJQnYxMFFNR1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN4cDI2NyAgICAgIBYBBRUAAAAtdMxd+nIec0MWB0ErMgMAAAAAAAAAAAALICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAcAAAAZ21haWwuc3Jpbml2YXNhLkFwcGxpY2F0aW9uIDIwMjAwNjAxMDIwMjMyNDggICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA/////zxPcmRlcnM+CiAgIDxPcmRlcj4KICAgICAgPEN1c3RvbWVySUQ+R1JFQUw8L0N1c3RvbWVySUQ+CiAgICAgIDxFbXBsb3llZUlEPjY8L0VtcGxveWVlSUQ+CiAgICAgIDxPcmRlckRhdGU+MTk5Ny0wNS0wNlQwMDowMDowMDwvT3JkZXJEYXRlPgogICAgICA8UmVxdWlyZWREYXRlPjE5OTctMDUtMjBUMDA6MDA6MDA8L1JlcXVpcmVkRGF0ZT4KICAgICAgPFNoaXBJbmZvIFNoaXBwZWREYXRlPSIxOTk3LTA1LTA5VDAwOjAwOjAwIj4KICAgICAgICAgPFNoaXBWaWE+MjwvU2hpcFZpYT4KICAgICAgICAgPEZyZWlnaHQ+My4zNTwvRnJlaWdodD4KICAgICAgICAgPFNoaXBOYW1lPkdyZWF0IExha2VzIEZvb2QgTWFya2V0PC9TaGlwTmFtZT4KICAgICAgICAgPFNoaXBBZGRyZXNzPjI3MzIgQmFrZXIgQmx2ZC48L1NoaXBBZGRyZXNzPgogICAgICAgICA8U2hpcENpdHk+RXVnZW5lPC9TaGlwQ2l0eT4KICAgICAgICAgPFNoaXBSZWdpb24+T1I8L1NoaXBSZWdpb24+CiAgICAgICAgIDxTaGlwUG9zdGFsQ29kZT45NzQwMzwvU2hpcFBvc3RhbENvZGU+CiAgICAgICAgIDxTaGlwQ291bnRyeT5VU0E8L1NoaXBDb3VudHJ5PgogICAgICA8L1NoaXBJbmZvPgogICA8L09yZGVyPgo8L09yZGVycz4=</wmb:bitstream>
   </wmb:bitstreamData>
</wmb:event>

Let us see what happens when there is an exception. To generate an exception, I’m just going to make the out queue name to a random non-existing queue OUTaa.Q and now the monitoring event with Exception tree looks like

<wmb:event xmlns:wmb="http://www.ibm.com/xmlns/prod/websphere/messagebroker/6.1.0/monitoring/event">
   <wmb:eventPointData>
      <wmb:eventData wmb:productVersion="100011" wmb:eventSchemaVersion="6.1.0.3" wmb:eventSourceAddress="MQ Input.transaction.Rollback">
         <wmb:eventIdentity wmb:eventName="OrderRollback"/>
         <wmb:eventSequence wmb:creationTime="2020-06-01T02:17:30.450741Z" wmb:counter="2"/>
         <wmb:eventCorrelation wmb:localTransactionId="47ab24c4-91c8-48b6-91a2-e0cc0393085b-1" wmb:parentTransactionId="" wmb:globalTransactionId=""/>
      </wmb:eventData>
      <wmb:messageFlowData>
         <wmb:broker wmb:name="IB10NODE" wmb:UUID="b7d2e6dd-0b36-4728-9015-818133dbeb14"/>
         <wmb:executionGroup wmb:name="default" wmb:UUID="61704de3-b47c-4b23-b95f-0ffd934fdcb1"/>
         <wmb:messageFlow wmb:uniqueFlowName="IB10NODE.default.TestMon.TestMon" wmb:name="TestMon" wmb:UUID="429ff9ef-1c8d-48c1-bf42-99ac3bd247fb" wmb:threadId="8076"/>
         <wmb:node wmb:nodeLabel="MQ Input" wmb:nodeType="ComIbmMQInputNode" wmb:detail="IN.Q"/>
      </wmb:messageFlowData>
   </wmb:eventPointData>
   <wmb:applicationData xmlns="">
      <wmb:complexContent wmb:elementName="ExceptionList">
         <ExceptionList>
            <RecoverableException>
               <File>F:\build\S1000_slot1\S1000_P\src\DataFlowEngine\TemplateNodes\ImbOutputTemplateNode.cpp</File>
               <Line>303</Line>
               <Function>ImbOutputTemplateNode::processMessageAssemblyToFailure</Function>
               <Type>ComIbmMQOutputNode</Type>
               <Name>TestMon#FCMComposite_1_2</Name>
               <Label>TestMon.MQ Output</Label>
               <Catalog>BIPmsgs</Catalog>
               <Severity>3</Severity>
               <Number>2230</Number>
               <Text>Caught exception and rethrowing</Text>
               <Insert>
                  <Type>14</Type>
                  <Text>TestMon.MQ Output</Text>
               </Insert>
               <MessageException>
                  <File>F:\build\S1000_slot1\S1000_P\src\DataFlowEngine\Connectors\mqconnector\MQConnection.cpp</File>
                  <Line>1003</Line>
                  <Function>MQConnection::acquireOutputQueueHandle</Function>
                  <Type></Type>
                  <Name></Name>
                  <Label></Label>
                  <Catalog>BIPmsgs</Catalog>
                  <Severity>3</Severity>
                  <Number>2666</Number>
                  <Text>Failed to open queue</Text>
                  <Insert>
                     <Type>2</Type>
                     <Text>-1</Text>
                  </Insert>
                  <Insert>
                     <Type>5</Type>
                     <Text>MQW101</Text>
                  </Insert>
                  <Insert>
                     <Type>2</Type>
                     <Text>2085</Text>
                  </Insert>
                  <Insert>
                     <Type>5</Type>
                     <Text></Text>
                  </Insert>
                  <Insert>
                     <Type>5</Type>
                     <Text>IIBv10QMGR</Text>
                  </Insert>
                  <Insert>
                     <Type>5</Type>
                     <Text>OUTaa.Q</Text>
                  </Insert>
                  <Insert>
                     <Type>2</Type>
                     <Text>2</Text>
                  </Insert>
               </MessageException>
            </RecoverableException>
         </ExceptionList>
      </wmb:complexContent>
   </wmb:applicationData>
</wmb:event>

Now, we know how the monitoring profile and monitoring events works. Let us develop a solution which will accept these messages and log them as we needed. For this, I’ve another message flow and it looks like

The MQTTSubscribe node is used to get the published event monitoring messages and the Java compute node is used to decipher the event monitoring XML message and log them. A sample log file looks like

2020-05-31 22:54:29.036 [Thread-49] INFO  - ----------------------------------------Transaction Starts---------------------------------------------------------
2020-05-31 22:54:29.058 [Thread-49] INFO  - Event Number :2
2020-05-31 22:54:30.001 [Thread-49] ERROR - Data Element Name :ExceptionList
2020-05-31 22:54:32.301 [Thread-49] ERROR - Error Message :Failed to open queue;MQW101;2085;IIBv10QMGR;OUTaa.Q;
2020-05-31 22:54:32.301 [Thread-49] INFO  - ----------------------------------------Transaction Ends---------------------------------------------------------
2020-05-31 22:54:36.142 [Thread-49] INFO  - ----------------------------------------Transaction Starts---------------------------------------------------------
2020-05-31 22:54:36.156 [Thread-49] INFO  - Event Number :1
2020-05-31 22:54:37.475 [Thread-49] INFO  - Data Element Name :MQMD
2020-05-31 22:54:37.476 [Thread-49] INFO  - ***********************************************************************
2020-05-31 22:54:37.477 [Thread-49] INFO  - SourceQueue : IN.Q
2020-05-31 22:54:37.478 [Thread-49] INFO  - Transactional : true
2020-05-31 22:54:37.478 [Thread-49] INFO  - Encoding : 273
2020-05-31 22:54:37.480 [Thread-49] INFO  - CodedCharSetId : 1208
2020-05-31 22:54:37.480 [Thread-49] INFO  - Format : MQSTR   
2020-05-31 22:54:37.481 [Thread-49] INFO  - Version : 2
2020-05-31 22:54:37.482 [Thread-49] INFO  - Report : 0
2020-05-31 22:54:37.483 [Thread-49] INFO  - MsgType : 8
2020-05-31 22:54:37.484 [Thread-49] INFO  - Expiry : -1
2020-05-31 22:54:37.484 [Thread-49] INFO  - Feedback : 0
2020-05-31 22:54:37.485 [Thread-49] INFO  - Priority : 0
2020-05-31 22:54:37.485 [Thread-49] INFO  - Persistence : 0
2020-05-31 22:54:37.486 [Thread-49] INFO  - MsgId : 414d5120494942763130514d475220204064d15e1000010d
2020-05-31 22:54:37.486 [Thread-49] INFO  - CorrelId : 000000000000000000000000000000000000000000000000
2020-05-31 22:54:37.487 [Thread-49] INFO  - BackoutCount : 1
2020-05-31 22:54:37.487 [Thread-49] INFO  - ReplyToQ :                                                 
2020-05-31 22:54:37.487 [Thread-49] INFO  - ReplyToQMgr : IIBv10QMGR                                      
2020-05-31 22:54:37.488 [Thread-49] INFO  - UserIdentifier : vaithu      
2020-05-31 22:54:37.488 [Thread-49] INFO  - AccountingToken : 160105150000002d74cc5dfa721e73431607412b32030000000000000000000b
2020-05-31 22:54:37.488 [Thread-49] INFO  - ApplIdentityData :                                 
2020-05-31 22:54:37.490 [Thread-49] INFO  - PutApplType : 28
2020-05-31 22:54:37.490 [Thread-49] INFO  - PutApplName : vaithu
2020-05-31 22:54:37.491 [Thread-49] INFO  - PutDate : 2020-06-01
2020-05-31 22:54:37.492 [Thread-49] INFO  - PutTime : 02:54:15.150
2020-05-31 22:54:37.493 [Thread-49] INFO  - ApplOriginData :     
2020-05-31 22:54:37.493 [Thread-49] INFO  - GroupId : 000000000000000000000000000000000000000000000000
2020-05-31 22:54:37.494 [Thread-49] INFO  - MsgSeqNumber : 1
2020-05-31 22:54:37.494 [Thread-49] INFO  - Offset : 0
2020-05-31 22:54:37.494 [Thread-49] INFO  - MsgFlags : 0
2020-05-31 22:54:37.495 [Thread-49] INFO  - OriginalLength : -1
2020-05-31 22:54:37.495 [Thread-49] INFO  - ***********************************************************************
2020-05-31 22:54:37.495 [Thread-49] INFO  - OrderReceived Payload :
MD            ÿÿÿÿ      ¸  MQSTR           AMQ IIBv10QMGR  @dÑ^ 
                                                                           IIBv10QMGR                                      vaithu         -tÌ]úrsCA+2                                            vaithu 2020060102541515                                       ÿÿÿÿ<Orders>
   <Order>
      <CustomerID>GREAL</CustomerID>
      <EmployeeID>6</EmployeeID>
      <OrderDate>1997-05-06T00:00:00</OrderDate>
      <RequiredDate>1997-05-20T00:00:00</RequiredDate>
      <ShipInfo ShippedDate="1997-05-09T00:00:00">
         <ShipVia>2</ShipVia>
         <Freight>3.35</Freight>
         <ShipName>Great Lakes Food Market</ShipName>
         <ShipAddress>2732 Baker Blvd.</ShipAddress>
         <ShipCity>Eugene</ShipCity>
         <ShipRegion>OR</ShipRegion>
         <ShipPostalCode>97403</ShipPostalCode>
         <ShipCountry>USA</ShipCountry>
      </ShipInfo>
   </Order>
</Orders>
2020-05-31 22:54:37.497 [Thread-49] INFO  - ----------------------------------------Transaction Ends---------------------------------------------------------
2020-05-31 22:54:41.125 [Thread-49] INFO  - ----------------------------------------Transaction Starts---------------------------------------------------------
2020-05-31 22:54:41.135 [Thread-49] INFO  - Event Number :2
2020-05-31 22:54:42.179 [Thread-49] ERROR - Data Element Name :ExceptionList
2020-05-31 22:54:44.299 [Thread-49] ERROR - Error Message :Failed to open queue;MQW101;2085;IIBv10QMGR;OUTaa.Q;
2020-05-31 22:54:44.299 [Thread-49] INFO  - ----------------------------------------Transaction Ends---------------------------------------------------------

Here each event message is clearly separated and easily readable. The exception handler captures the right error message and ignores all other unnecessary information. So, we know the key elements, input and output payload and the exception message. Since we’re using monitoring profile, there is no need for any custom subflows and this solution is production tested code and works fantastically, thanks to log4j settings.

2020-05-31 22:54:41.125 [Thread-49] INFO  - ----------------------------------------Transaction Starts---------------------------------------------------------
2020-05-31 22:54:41.135 [Thread-49] INFO  - Event Number :2
2020-05-31 22:54:42.179 [Thread-49] ERROR - Data Element Name :ExceptionList
2020-05-31 22:54:44.299 [Thread-49] ERROR - Error Message :Failed to open queue;MQW101;2085;IIBv10QMGR;OUTaa.Q;
2020-05-31 22:54:44.299 [Thread-49] INFO  - ----------------------------------------Transaction Ends---------------------------------------------------------

All these logs are categorically separated like nodename/servername/flowname so that it is easy to identify the log files. The log files gets rolled up automatically and each log file size is 10MB as these are controlled by the log4j settings.

All you’ve to do is, just enable monitoring and see the logs in the folder configured in the log4j config file.

If you’d like to understand how the log4j file looks like and the Java code used, there is a session on this next week Sunday.

By attending the session, you will get complete understanding of this solution and can extend the same as you need. You will also get the complete solution for free. If you’d like to attend the session, please contact support@vaithu or WhatsApp +1 6123058684.

Time 10 AM EST

Date : Jun, 07, 2020

Mode : Online (Webex)

Fee : contact support@vaithu.com. First 50 participants, get a discounted rate of $15.

Vaadin dialog window show default scroller

I think the new vaadin dialog window in v14.2 has some issue. I just added one textfield into a formlayout and added it to the Dialog window. But it shows a vertical scroller like below

The code is

Dialog dialog = new Dialog();
FormLayout layout = new FormLayout(new TextField("Queue Name", mqQueue.getName(), ""));
            dialog.add(new H2("Queue Properties"));
            dialog.add(layout);
            dialog.open();

if you know any fix, please update in the comments.

Monitoring activities in IIB

Usually, the admin guys use System Logs to see what is happening in remote node. Sometimes, the developer also wants to see but he/she doesn’t have access to System Logs. So, they have depend on the admin guys or go with what is available in Web UI like  activity logs or administrative logs or any custom audit logs.

Is there a way to see what is happening in the remote integration node ? How do I know if someone deletes or creates an integration server? Can I keep getting every activity from the remote node?

Yes. You can keep getting every activity from the remote node by using IBM Integration API Java Program. Here is a sample showing what has happened when an user tried to stop default integration node.

Thu Jan 24 00:54:55 EST 2019 : affectedObject = Log
Thu Jan 24 00:54:55 EST 2019 : new_subcomponent 2871<<Administration Request<<2019-01-24 00:54:55.287 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<INITIATED
Thu Jan 24 00:54:55 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:15 EST 2019 : affectedObject = Log
Thu Jan 24 00:55:15 EST 2019 : new_subcomponent 2871<<Administration Request<<2019-01-24 00:55:15.317 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<INITIATED
Thu Jan 24 00:55:15 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = default
Thu Jan 24 00:55:26 EST 2019 : changed_attribute "ExecutionGroupRuntimeProperty/This/runMode" = "stopped"

Thu Jan 24 00:55:26 EST 2019 : changed_attribute "object.runstate" = "stopped"

Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = Log
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2880<<Change Notification<<2019-01-24 00:55:26.360 EST<<object.runstate<<running<<stopped<<default<<ExecutionGroup<<IB10NODE<<Broker
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2871<<Administration Result<<2019-01-24 00:55:26.349 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<COMPLETE
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2871<<Administration Result<<2019-01-24 00:55:26.326 EST<<user<<stop<<default<<ExecutionGroup<<IB10NODE<<Broker<<COMPLETE
Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = default
Thu Jan 24 00:55:26 EST 2019 : changed_attribute "ExecutionGroupRuntimeProperty/This/processId" = "0"

Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)
Thu Jan 24 00:55:26 EST 2019 : affectedObject = Log
Thu Jan 24 00:55:26 EST 2019 : new_subcomponent 2880<<Change Notification<<2019-01-24 00:55:26.396 EST<<processId<<14008<<0<<default<<ExecutionGroup<<IB10NODE<<Broker
Thu Jan 24 00:55:26 EST 2019 : ----------------------------------------.processModify(...)

 

If you are looking for the complete code or training on IBM Integration API, connect with us at support@vaithu.com/WhatsApp +1 6123058684. F0r more details, please visit www.vaithu.com

 

 

Exception Handler using Java Compute Node

Every project has its own way of implementing Error Handler and the subflows are the most common among them and in some cases the same is getting converted into an user defined node.

The problem with subflows are, “Every project should reference it and with UDN , the message flows and esql files become cmf file which hides information about what are all inside it. For any reason, if you need the code back again, it is difficult to get from CMF file so this is not a good solution.

Moving to Monitoring Profiles is another option but not sure why most of the projects did not explore the greatness of this. So, anyone who is looking for a pure java implementation for exception handling without any CMF issues, here is the code.

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbJSON;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbUserException;
import com.ibm.broker.plugin.MbXMLNSC;
import com.iib.broker.utilities.MbUtils;


public class ExJCN extends MbJavaComputeNode {
  
  private String errorNumber;
  private String exceptionType;
  private String errorFunction;
  private String errorMsg;
  private String errorPath;
  private String errorLocation;
  private String transactionXPath;
  private String causeOfError;
  private String logLevel;
  private String sqlStatement;
  private boolean isValidInputMessage;
  
  
  private Pattern REGEX_PATTERN ;
  private Set<String> ignoreErrorTexts;
  
  public void onInitialize() throws MbException {
    REGEX_PATTERN = Pattern.compile("^\\p{XDigit}+$");
    ignoreErrorTexts = new HashSet<String>(Arrays.asList(
        new String[] {"Caught exception and rethrowing","Error detected, rethrowing","Node throwing exception"}));
    
  }
  
  public void evaluate(MbMessageAssembly inAssembly) throws MbException {
    MbOutputTerminal out = getOutputTerminal("out");
//		MbOutputTerminal alt = getOutputTerminal("alternate");

    MbMessage inMessage = inAssembly.getMessage();
    MbMessageAssembly outAssembly = null;
    try {
      MbMessage outMessage = new MbMessage();
      outAssembly = new MbMessageAssembly(inAssembly, inAssembly.getLocalEnvironment(),inAssembly.getExceptionList(),outMessage);
      // ----------------------------------------------------------
      // Add user code below
      MbElement exception = MbUtils.getExceptionList(inAssembly).getFirstChild();
      MbElement inputRoot = inMessage.getRootElement();
      String ipMsgStatus = MbUtils.isValidMessage(inputRoot);
      this.isValidInputMessage = ipMsgStatus == null ? true : false;
      
      if (exception != null && exception.getName().endsWith("Exception")) {
        getExceptionDetails(exception, inputRoot);
      }else if (null != inputRoot && !MbUtils.getValueAsString(inputRoot, "HTTPResponseHeader/X-Original-HTTP-Status-Code").isEmpty() 
        && !MbUtils.getValueAsString(inputRoot, "HTTPResponseHeader/X-Original-HTTP-Status-Code").equals("200")	) {
        
        MbElement httpResponse = inputRoot.getFirstElementByPath("HTTPResponseHeader");
        this.exceptionType = httpResponse.getFirstChild().getValueAsString();
        this.errorNumber = MbUtils.getValueAsString(httpResponse, "X-Original-HTTP-Status-Code");
        this.errorLocation = MbUtils.getValueAsString(httpResponse, "X-Original-HTTP-Status-Line") +":"+MbUtils.getValueAsString(httpResponse,"Server");
        
        if (inputRoot.getLastChild().getName().equals("BLOB")) {
          this.errorMsg = MbUtils.getStringFromBlob(inputRoot);
        }else{
          this.errorMsg = MbUtils.getPayloadAsString(inputRoot, inputRoot.getLastChild().getName());
        }
      }else if (MbUtils.getLocalEnvironment(inAssembly).getFirstElementByPath("/HTTP/Input/Timeout") != null) {
        this.exceptionType = "Timeout Exception";
        this.errorNumber = "504";
        this.errorMsg = "Request could not be completed with in the defined " 
        + MbUtils.getValueAsString(MbUtils.getLocalEnvironment(inAssembly).getFirstElementByPath("/HTTP/Input/Timeout"), "OriginalClientWaitTime") + " seconds.";
        this.errorLocation = getMessageFlow().getName();
      }else if (null != inputRoot && inputRoot.getLastChild().getName().equals("SOAP")) {
        
        exception = inputRoot.getFirstElementByPath("/Body/Fault");
        
        if (exception != null) {

          this.exceptionType = MbUtils.getValueAsString(exception, "faultcode");
          this.errorMsg = MbUtils.getValueAsString(exception, "faultstring") ;
          
          MbElement detail = exception.getFirstElementByPath("detail"); 
          detail = detail == null ? null : detail.getFirstChild();
          
          while (detail != null) {
            this.errorMsg = this.errorMsg +";" + detail.getName() +" = "+ detail.getValue();
            detail = detail.getNextSibling();
          }
          this.errorLocation = MbUtils.getValueAsString(exception, "faultactor");
        } 
      }else{
        String unknown = "Unknown";
        this.errorNumber = unknown;
        this.errorFunction = unknown;
        this.errorLocation = getMessageFlow().getName();
        this.errorMsg = "Unable to capture the error message as it is not having any exceptionlist, soap fault, http timeout, http error. Debug the flow and see what is happening";
        this.errorPath = unknown;
        this.exceptionType = unknown;
      }
      
      
      MbMessage errorMessage = new MbMessage();
      MbElement errorRoot = errorMessage.getRootElement();
      MbElement errorXML = null;
      
      switch (MbUtils.getDomainName(inputRoot).toUpperCase()) {
      case MbJSON.PARSER_NAME:
        errorXML = prepErrorMessageInJSON(errorRoot);
        break;
      case "SOAP":
        errorXML = MbUtils.prepSOAPFault(errorRoot, MbUtils.getValueAsString(inputRoot, "HTTPInputHeader/X-Original-HTTP-Command"));
        break;
      default:
        errorXML = prepErrorMessageInXML(errorRoot);
        break;
      }
      
      MbElement detail = errorXML.createElementAsLastChild(MbElement.TYPE_NAME, "Detail", null);
      getTransactionDetails(inputRoot, detail);
      
      if (!this.isValidInputMessage) {
        this.errorMsg += "\n"+ipMsgStatus;
      }
      
      prepErrorMessage(detail);
      MbUtils.copyLocalEnvironmentAsXML(inAssembly, errorXML);
      MbUtils.copyEnvironmentAsXML(inAssembly, errorXML);
      
      MbElement outputRoot = outMessage.getRootElement();
      MbUtils.copyProperties(inputRoot, outputRoot);
      MbUtils.copyMQMD(inputRoot, outputRoot);
      MbUtils.createMQRFH2(inputRoot, outputRoot);
      MbUtils.setPubTopic(outputRoot, "Excep");
      
      MbElement parts = MbUtils.createMIMEParser(outputRoot, "ExceptionHandler");
      MbUtils.addToMimePart(parts,  errorRoot);
      
      if (isValidInputMessage) {
        MbUtils.addToMimePart(parts,  inputRoot);
      }
      
      // End of user code
      // ----------------------------------------------------------
    } catch (MbException e) {
      // Re-throw to allow Broker handling of MbException
      throw e;
    } catch (RuntimeException e) {
      // Re-throw to allow Broker handling of RuntimeException
      throw e;
    } catch (Exception e) {
      // Consider replacing Exception with type(s) thrown by user code
      // Example handling ensures all exceptions are re-thrown to be handled in the flow
      throw new MbUserException(this, "evaluate()", "", "", e.toString(),
          null);
    }
    // The following should only be changed
    // if not propagating message to the 'out' terminal
    out.propagate(outAssembly);

  }
  
  
  public MbElement prepErrorMessageInJSON(MbElement outRoot) throws MbException {
    return
           outRoot.createElementAsLastChild(MbJSON.PARSER_NAME)
           .createElementAsLastChild(MbJSON.ARRAY, "Data", null)
           .createElementAsLastChild(MbElement.TYPE_NAME, "Error", null);
  }
  
  public MbElement prepErrorMessageInXML(MbElement outRoot) throws MbException {
    return
           outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME).
          createElementAsLastChild(MbElement.TYPE_NAME, "Error", null);
  }
  
  
  
public void getExceptionDetails(MbElement exceptionRef, MbElement inputRoot) throws MbException {
    
    StringBuffer errorMessage = new StringBuffer("");
    StringBuffer errorPath = new StringBuffer("");
    String text,label,hexText,payload;
    byte[] bs = null;
    
    if (inputRoot.getLastChild().getName().equals("BLOB")) {
      bs = (byte[]) MbUtils.getBlob(inputRoot).getValue();
    } else if (isValidInputMessage) {
      bs = MbUtils.getPayloadAsBlob(inputRoot);
    }
//		MbElement blob;
    final int MSG_MAX_SIZE = 10240;
    final String FAILED_MSG_IGNORE = "Failed message is more than "+ MSG_MAX_SIZE +" bytes.So not capturing it";
    
    while ( exceptionRef != null && exceptionRef.getName().endsWith("Exception")) {
      
      text = MbUtils.getValueAsString(exceptionRef, "Text");
      
      if (!ignoreErrorTexts.contains(text)) {
        errorMessage.append(text);
        errorMessage.append("->");
      }
      
      label = MbUtils.getValueAsString(exceptionRef, "Label");
      if (!label.isEmpty()) {
        errorPath.append(label);
        errorPath.append("-->");
        
        if (!label.startsWith("Imb")) {
          this.errorLocation = label;
        }
      }
      
      for (MbElement errInsRef = exceptionRef.getFirstElementByPath("Insert"); errInsRef != null && errInsRef.getName().equals("Insert"); errInsRef = errInsRef.getNextSibling()) {
        
        text = MbUtils.getValueAsString(errInsRef, "Text");
        
        if (null != text && !text.isEmpty() ) {
          
            switch (Integer.parseInt(errInsRef.getFirstChild().getValueAsString())) {
            case 2:
              if (text.contains("SOCKET")) {
                errorMessage.append(text);
                errorMessage.append("->");
              }
              break;
            case 12:
              if (text.getBytes().length <= MSG_MAX_SIZE && isHex(text)) {
                
                payload = null != bs && bs.length <= MSG_MAX_SIZE ?  new String(bs) : FAILED_MSG_IGNORE;
                hexText = !payload.equals(FAILED_MSG_IGNORE) ? convertHexToString(text) : "";
                
                if (hexText.contentEquals(payload) ) {
                  errorMessage.append("Failed Input Message :\n");
                }
                errorMessage.append(hexText);
              }else{
                errorMessage.append(FAILED_MSG_IGNORE);
              }
              errorMessage.append("->");
              break;
            default:
              errorMessage.append(text);
              errorMessage.append("->");
            }
        } 
      }
      text = MbUtils.getValueAsString(exceptionRef, "Function");
      this.sqlStatement = text.isEmpty()  ? null : text;
      
      errorMessage.append("\n");
      exceptionRef = exceptionRef.getLastChild();
    }
    
    exceptionRef = exceptionRef.getParent();
    this.errorNumber = MbUtils.getValueAsString(exceptionRef, "Number");
    this.errorFunction = MbUtils.getValueAsString(exceptionRef, "Function");
    this.causeOfError = MbUtils.getValueAsString(exceptionRef, "Text");
    this.exceptionType = exceptionRef.getName();
    this.errorMsg = errorMessage.substring(0, errorMessage.length() - "->\n".length());
    this.errorPath = errorPath.substring(0, errorPath.length() - "-->".length());
    
  }


public void prepErrorMessage( MbElement output) throws MbException {
  
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "TimeStamp", new Date().toString());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ExceptionType", this.exceptionType);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorNumber", this.errorNumber);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "CauseOfError", this.causeOfError);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorMessage", this.errorMsg);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorLocation", this.errorLocation);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorFunction", this.errorFunction);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ErrorPath", this.errorPath);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "SqlStatement", this.sqlStatement);
  
}
public Boolean isHex(String str) {
    return REGEX_PATTERN.matcher(str).matches();
}


private String convertHexToString(String hex){

    StringBuilder sb = new StringBuilder();

    for( int i=0; i<hex.length()-1; i+=2 ){
      sb.append((char)Integer.parseInt(hex.substring(i, (i + 2)), 16));
    }
    return sb.toString();
  }

public void getBrokerDetails(MbElement output) throws MbException {
  
  output = output.createElementAsLastChild(MbElement.TYPE_NAME, "RuntimeDetail", null);
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "MessageFlowLabel", getMessageFlow().getName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Application", getMessageFlow().getApplicationName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Library", getMessageFlow().getLibraryName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "ExecutionGroup", getExecutionGroup().getName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "BrokerName", getBroker().getName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Queue Manager", getBroker().getQueueManagerName());
  output.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "User", System.getProperty("user.home"));
}
}

If you are looking for complete implementation of the PI or any session with Java Compute Node, connect with us at support@vaithu.com/WhatsApp +1 6123058684. We offer complete solution in IIB for low cost.

Monthly Summary Report using DFDL

Recently we have been asked to design a message model which shows as a report like below. It was a nice report and they want the same intact.

Entry       Per         Post Date   GL Account  Description                                                                                                                                                                                                                                                     
--------------------------------------------------------------
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test                                              
16524       01          09/15/2018  123456      Test

After playing with DFDL Fixed Length format couple of times, we were able to achieve the desired format and it was really interesting when you know the power and simplicity of DFDL. The message model created is

 

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ibmDfdlExtn="http://www.ibm.com/dfdl/extensions" xmlns:ibmSchExtn="http://www.ibm.com/schema/extensions" xmlns:recFixLengthFieldsFmt="http://www.ibm.com/dfdl/RecordFixLengthFieldFormat">

    <xsd:import namespace="http://www.ibm.com/dfdl/RecordFixLengthFieldFormat" schemaLocation="IBMdefined/RecordFixLengthFieldFormat.xsd"/>
        <xsd:simpleType dfdl:length="150" dfdl:terminator="" dfdl:textStringPadCharacter="-" name="border">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>
    <xsd:complexType name="Header">
    <xsd:sequence dfdl:separator="%SP;%SP;">
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="Entry" name="Entry" type="xsd:string"/>
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="Per" name="Per" type="xsd:string"/>
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="Post Date" name="PostDate" type="xsd:string"/>
      <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="GL Account" name="GLAccount" type="xsd:string"/>
      <xsd:element dfdl:length="256" ibmDfdlExtn:sampleValue="Description" name="Descrption" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
    <xsd:annotation>
    <xsd:appinfo source="http://www.ogf.org/dfdl/">
      <dfdl:format encoding="{$dfdl:encoding}" escapeSchemeRef="" occursCountKind="fixed" ref="recFixLengthFieldsFmt:RecordFixLengthFieldsFormat" textPadKind="padChar"/>
    </xsd:appinfo>
  </xsd:annotation>

  <xsd:element dfdl:lengthKind="delimited" ibmSchExtn:docRoot="true" name="FLength">
    <xsd:complexType>
      <xsd:sequence dfdl:separator="%CR;%LF;%WSP*;" dfdl:separatorSuppressionPolicy="anyEmpty">
                				<xsd:element dfdl:lengthKind="delimited" name="header" type="Header"/>
                <xsd:element ibmDfdlExtn:sampleValue="" name="border" type="border"/>
                <xsd:element dfdl:lengthKind="delimited" dfdl:occursCountKind="implicit" ibmDfdlExtn:sampleOccurs="10" maxOccurs="unbounded" name="body">
          <xsd:complexType>
            <xsd:sequence dfdl:separator="%SP;%SP;">
              <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="16524" name="Entry" type="xsd:string"/>
              <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="01" name="Per" type="xsd:string"/>
              <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="09/15/2018" name="PostDate" type="xsd:string"/>
                            <xsd:element dfdl:length="10" ibmDfdlExtn:sampleValue="123456" name="GLAccount" type="xsd:string"/>
                            <xsd:element dfdl:length="50" dfdl:textPadKind="padChar" ibmDfdlExtn:sampleValue="Test" name="Description" type="xsd:string"/>
                                                                                                                                                                    </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
                			                        </xsd:sequence>
    </xsd:complexType>
  </xsd:element>


</xsd:schema>

If you have any requirements in DFDL Message modelling, connect with us at support@vaithu.com/+1 6123058684.