Wednesday, March 30, 2016

Propagating both (input and queue) messages to output terminal in MQGet node of Message Broker / IBM Integration Bus


  • MQGet node receives a message on input terminal, but it also reads a message from MQ Queue. Thus you have access to two messages while using MQGet node. This is different than MQInput node where you have only one message coming from MQ Queue.
  • Have you wondered how to propagate both these messages to output? By default MQGet node only propagates message from input terminal and not the one read from MQ Queue.
  • Following steps can be taken to also include message read from queue in output message tree
  1. Go to properties of MQGet node
  2. Go to Advanced 
  3. Select "Message" for "Generate Mode"
  4. Select "Copy Entire Message" for "Copy message
  5. Go to Result
  6. Specify location in the output message tree where you want to place the message (or message part) from message read from MQ Queue in the field "Output data location". eg: OutputRoot.DFDL or OutputRoot.XMLNS or OutputRoot.DFDL.mymessage etc...
  7. Specify location from the message read from MQ queue in "Result data location". Default is ResultRoot. eg: ResultRoot.DFDL or ResultRoot.XMLNS or ResultRoot.XMLNS/XYZ 
  • Following is an example where MQ queue contains messages in CSV format for which DFDL message model is created.
  • In this example input message to MQGet is in xml format (XMLNSC parser) where as message from MQ Queue is in CSV format (DFDL parser - PersonCSV)

Tuesday, April 14, 2015

JMeter with WebSphere MQ as JMS Provider on 64 bit platform

To use JMeter test plan to use WebSphere MQ as JMS Provider on 64 bit platform in bindings mode, there seems to be a problem. By default JMeter will load 32 bit libraries of MQ and that causes problem. 

You may get error similar to the following:
com.ibm.mq.jmqi.JmqiException: CC=2;RC=2495;AMQ8568: The native JNI library 'mqjbnd' was not found. For a client installation this is expected. [3=mqjbnd]

To prevent this issue, update your JMether.sh/bat and add following argument. 

set JVM_ARGS=-Djava.library.path="C:/IBM/WebSphere MQ/java/lib64"

Note: The path may be different depending on where MQ is installed.



Tuesday, May 6, 2014

Running WebSphere Application Server nodeagents as a service on Linux (as non-root user)


People ask me why they should configure WebSphere Application Server (WAS) nodeagents/dmgr (deployment manager) as a service on Linux. Here is the answer!

Think of a situation when one of the WAS servers goes down due to an unknown reason. If you have a clustered environment, the deployment manager (dmgr) keeps eye on the members through nodeagents. When it sees that one of the member servers is down, it will try to bring the server up automatically. So here you don't need to worry. Dmgr is your savior!

Now think of a situation when a nodeagent of a node goes down for an unknown reason. If any of the servers on this node now goes down due to an unknown reason, dmgr will not be able start it as it has no communication channel (nodeagent is down!). If you would have any other custom monitoring in place, you may get notification about the server being down and you may take a manual action to bring the server and the nodeagent up. But this may take considerable amount of time.

How to prevent this situation?
Here comes the importance of running the nodeagent as a linux (or for that matter windows) server. You can configure nodeagent to run as a Linux service to start automatically if it goes down for unknown reason. There are also other options possible while setting up nodeagent to run as a service. 

You may configure to run as a specific user. This option can be used to run a nodeagent as a non-root user.

You may configure the service to start automatically or manually on reboot of the system.

In following example, the service is configured to run as wasadmin user, the nodeagent will be brought up automatically if it goes down due to an unknown reason and the nodeagent will not start automatically on system reboot.

#!/bin/sh
# Initialization
if [ -z "$4" ]
  then
     echo "Usage: ./installNodeagentService.sh    "
 exit -1
fi

echo installing nodeagent of profile $1 as service, with logroot for node: $2 and userid: $3 by executing wasservice.sh

${WASBIN}/wasservice.sh -add $1 -serverName nodeagent -profilePath "${PROFILEROOT}/$1" -wasHome "${WASROOT}" -logFile "$2/nodeagent/startServer.log" -logRoot "$2/nodeagent" -userid $3 -password $4 -restart true -startType manual

Note: To configure Linux Service you need root (sudo) access, but once service is configured you will not need root access. Thus you must run above script as root or with sudo. If you don't have either talk to your linux administrator. 

In the same manner dmgr can also be configured to run as a Linux Service.

Wednesday, April 30, 2014

WebSphere ESB 6.2 SIB as Message Provider for WebLogic 12c Message Driven Bean (MDB) using SIB Resource Adapter with XA transaction support

In my previous post I described how to setup your environments to achieve Distributed (XA) Transaction support for JMS through the use of SIB Resource Adapter. It was specifically for WebSphere ESB 7.5 and WebLogic 12c. 

I have been busy today to achieve the same between WebSphere ESB 6.2 and WebLogic 12c. To my surprise if you deploy the Resource Adapter from WebSphere ESB 7.5 on WebLogic 12c and configure your MDB to connect to the WebSphere ESB 6.2 destination, it works and that too with XA support.

Monday, April 28, 2014

WebSphere SIB as Message Provider for WebLogic Message Driven Bean (MDB) using SIB Resource Adapter with XA transaction support

One of my customers wanted to subscribe to a topic on our WebSphere Application Server 7.0 SIB (Service Integration Bus). The customer wanted to use a Message Driven Bean (MDB - Message Driven Bean - EJB 3.0) deployed on Weblogic application server 12c as a message endpoint for the Topic on WAS SIB.

Client could have configured Foreign Server through WebLogic Console using SIB JMS client jar(s), but client wanted message guarantee with no loss. For this purpose MDB was configured to run as container managed bean. Resources from SIB must participate in a global (XA) transaction to support this requirement. 

As the SIB Resource Adapter (SIB RA) conforms JCA 1.5, we suggested to deploy the SIB RA on WebLogic and subscribe to the topic on WebSphere using Activation Specification. But due to lack of clear documentation client did not manage to achieve this. 

I decided to document how this can be achieved for people who might be in the same situation.

Following are the high level steps to configure and run a message driven bean on WebLogic server to which the WebSphere SIB resource adapter will dispatch messages from a message provider running on WebSphere Application Server Service Integration Bus (SIB)
  1. Create Topic to which client want to subscribe on WebSphere SIB. 
  2. Install SIB RA on WebLogic Application Server
  3. Develop MDB
  4. Create ejb-jar.xml
  5. Create weblogic-ejb-jar.xml
  6. Install MDB on WebLogic Application Server
  7. Validate if the subscription is created
As you have the overview of the steps required to achieve above mentioned setup, let's dig into the details.

  1. Create the Topic to which MDB wants to subscribe on WebSphere SIB
    • Note: You may skip this step, if you already have created the Topic
    • Create TopicSpace (eg: MyTopicSpace) from Service Integration => Buses > <Your Bus Name> => Destinations with default settings
    • Create the topic (eg: MyTopic) from Resources => JMS => Topics at appropriate scope in the default messaging provider and by using MyTopicSpace as the topic space of this topic
    • Select "Persistent" for the JMS delivery mode for MyTopicSpace

  2. Install SIB RA on WebLogic Application Server

    • Copy the SIB Resource Adapter (sibc.jmsra.rar) from WebSphere (<WAS_INSTALL>/runtimes directory) to WebLogic.
    • Install the SIB RA on WebLogic Application Server.
    • Make sure to give a JNDI Name (eg: jms/websphere_ra) to the SIB RA so that the MDB can bind with it in the later steps.
    • See the figure below for example. 
  3. Develop MDB
    • In the MDB class do not specify any elements for the annotation "@MessageDriven" and it should implement "javax.jms.MessageListener"
    • No need to specify configurations for "mappedName" or "activationConfig" as they will be configured using ejb-jar.xml
    • See the figure below for example
    • While caching any exception, set the message driven context for rollback.
    • See the figure below for example
  4. Create ejb-jar.xml
    • ejb-jar.xml is used to specify various settings during deployment of the MDB
    • "messaging-type" is configured as "javax.jms.MessageListener"
    • "transaction-type" is configured as "Container" for container managed MDB. Refer the link for details.
    • Various activation config properties are configured such as durableSubscriptionHome, targetType (= "ME" for XA support), targetSignificance (= "Required" for XA support), target (= <Name of the messaging engine hosting the Topic>), topicSpace (= <Name of the TopicSpace>), clientId (= <any string as client identifier>), subscriptionName (= <any string as subscription name), subscriptionDurability (= durable), destination (= <name of the Topic>), destinationType (= javax.jms.Topic), providerEndpoints (<hostname of websphere application server:<SIB_ENDPOINT_ADDRESS port>:BootstrapBasicMessaging), busName (= bus name)
    • "trans-attribute" for method "onMessage" is set as "Required" for container-managed transaction. Refer the link for details.
    • Sample ejb-jar.xml
  5. Create weblogic-ejb-jar.xml
    • Through this file one can bind MDB with the SIB RA
    • Binding is done using the element "resource-adapter-jndi-name"
    • Specify the JNDI name of the SIB RA as configured in step 2
    • Sample weblogic-ejb-jar.xml
  6. Install MDB on WebLogic Application Server
    • Install the EAR containing the MDB developed above
    • Start the application
  7. Validate if the subscription is created
    • After completing above steps, durable subscription should be created on SIB. 
    • To validate the subscription go to WebSphere admin console => Service Integration => Buses > <Your Bus Name> => Destinations => <Topic Space> => Publication points => <publication point> => Runtime => Subscriptions => <created Subscrition>

Above steps should help you configure and run a message driven bean on WebLogic server to which the WebSphere SIB resource adapter will dispatch messages from a message provider running on WebSphere Application Server Service Integration Bus (SIB). 

If an exception occurs, transaction will be rolled back and the message will be redelivered  upto maximum of "Maximum failed deliveries per message" retries which is one of the configuration of a topic space.  If all the retries result into rollback, message will be moved to exception destination of the topic. 

Thursday, August 11, 2011

Oracle SOA Suite 11g: Populating a list or an array in BPEL without using XSLT

Few days ago, I was facing an issue where I wanted to generate a request for a webservice in a BPEL. This request had an element of type list. This Element had multiple children of type string.


I couldn't find a straight example to achieve this anywhere. So I hope my post will help you resolve the same issue!


Let's assume that you have a list of property which is called extraProps. Each property has two child 1) name and 2) value.


You want to populate your inputVariable with 3 property in extraProps. Part of your request would look like following:
     <extraProps>
          <property>
              <name>xStorageRule</name>
             <value>default</value>
          </property>
         <property>
             <name>xInvoiceType</name>
             <value>type1</value>
         </property>
         <property>
             <name>xRunID</name>
             <value>runid_5</value>
          </property>
     </extraProps>



To achieve this, you can do following:
1) Start with first entry in the list.
Copy the values (xStorageRule and default) using Edit Assign editor of JDeveloper as if they are not part of list. See the image below.



When you see the source, this will look like following:


            <copy>
              <from expression="'xStorageRule'"/>
              <to variable="checkInUniversal_InputVariable" part="payload"
                  query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property/ns6:name"/>
            </copy>
            <copy>
              <from expression="'default'"/>
              <to variable="checkInUniversal_InputVariable" part="payload"
                  query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property/ns6:value"/>
            </copy>

2) Append (add) next elements (property) into the list (extraProps)
Now instead of Copy function use Append function. I used the property populated in the last step to append 2nd and 3rd element in the list. See the image below.


The source code for this will look like:


            <bpelx:append>
              <bpelx:from variable="checkInUniversal_InputVariable"
                          part="payload"
                          query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property[1]"/>
              <bpelx:to variable="checkInUniversal_InputVariable" part="payload"
                        query="/ns6:CheckInUniversal/ns6:extraProps"/>
            </bpelx:append>
            <bpelx:append>
              <bpelx:from variable="checkInUniversal_InputVariable"
                          part="payload"
                          query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property[1]"/>
              <bpelx:to variable="checkInUniversal_InputVariable" part="payload"
                        query="/ns6:CheckInUniversal/ns6:extraProps"/>
            </bpelx:append>


After this step you already have list of property (3 elements) in extraProps, but all 3 of they have same name-value pair. So in the next step, we will overwrite the name-value pair for 2nd and 3rd element in the list.


3) Overwrite the name-value pairs with correct values.
Using the "Edit Assign" Editor, this steps looks little tricky. Once assigning the values you manually need to change the "To XPath" to specify correct element in the array. See the image below.




As you can see, I have overwritten 2nd and 3rd element of extraProps in this step with the correct values.


The source code for this step would look like:



            <copy>
              <from expression="'xInvoiceType'"/>
              <to variable="checkInUniversal_InputVariable" part="payload"
                  query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property[2]/ns6:name"/>
            </copy>
            <copy>
              <from variable="invoiceType"/>
              <to variable="checkInUniversal_InputVariable" part="payload"
                  query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property[2]/ns6:value"/>
            </copy>
            <copy>
              <from expression="'xRunID'"/>
              <to variable="checkInUniversal_InputVariable" part="payload"
                  query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property[3]/ns6:name"/>
            </copy>
            <copy>
              <from variable="billRunId"/>
              <to variable="checkInUniversal_InputVariable" part="payload"
                  query="/ns6:CheckInUniversal/ns6:extraProps/ns6:property[3]/ns6:value"/>
            </copy>


And that's the end of the post! If you find this helpful, please live a comment. Thank you.