IBM Support

Maximo 7.6: Configuring Maximo JMS resources for use by the Integration Framework

Question & Answer


Question

What is the procedure to manually create JMS resources used by the Integration Framework?

Answer

In previous versions of Maximo, the Maximo clustering configuration used for the Integration Framework typically contained separate buses – one bus for each of the UI and MIF clusters – to avoid affecting the user experience in terms of performance while loading data into Maximo. This was often complicated and had drawbacks when it came to high availability and simplicity of the configuration. 

Often times, the clusters designated as IF or CRON may need to be able to access the sequential outbound queues, and users may need to access the inbound continuous or sequential queues from the UI cluster.

To make the JMS resources accessible from all clusters to avoid the complication of creating duplicate JMS resources for just such scenarios, the following configuration is designed to contain a single service integration bus, and all resources are visible to all cluster members regardless which cluster each server resides in.

For this configuration, we are assuming the following clusters already exist:

UI cluster (uicluster) containing two members

IF cluster (ifcluster) containing two members

CRON cluster (croncluster) containing two members

Below is a simple diagram depicting the solution outlined here:


Below is the list of steps used to configure WebSphere Application Server:

1.  To accomplish load distribution and visibility of the JNDI objects throughout the WebSphere cell, we will need several messaging Engines.  We will also need a database for each messaging engine.  In this configuration, we will have a messaging engine for each of the three clusters for accessing the sequential queues.  This means we will have a total of three messaging engines, so we will need three empty databases or schemas for this configuration before proceeding.  These databases will be used only by the messaging engines and will not be used by the Maximo application.  The owner of the database must have permissions to create tables.

Remember that no two messaging engines can share the same schema for their persistent storage, so each messaging engine must have its own persistent storage location.

Once you have three empty databases or schemas, proceed to the next step.

2. Create a JDBC Provider for your database which we will use for your messaging engines’ persistent storage.

The example below is for Oracle:

1. Launch a browser and open the WebSphere administrative console by typing the following: https://<dmgr_host_name>:9043/ibm/console
2. Click Resources > JDBC > JDBC Providers
3. From the Scope drop-down list select Cell=ctgCell01
4. Click New.
5. Enter/select the following information

  • Database Type Select Oracle
  • Provider type Select Oracle JDBC Driver
  • Implementation type Select XA data source
  • Name Enter oraclexa

6. Click Next
7. Leave Directory location blank
8. Click Next
9. Click Finish
10. Click Save
11. Click OK
12. Click oraclexa to open the dialog box.
13. Change the class path to a local path containing a copy of the JAR file from the Maximo installation folder/lib/oraclethin.jar

Note that this file must be placed in the same location on each node.This can be a mount point or UNC path as well as a local location that the WebSphere JVM user has access to.

AVOID TROUBLE: Do not place database driver files in the WebSphere Installation/lib folder.
14. Click OK
15. Click Save

3. Now we need to create data sources for each messaging engine.  Since there are three messaging engines required for this configuration we will need to create three data sources (one for each database used by each messaging engine for persistent storage).  If you create three schemas in a single database, you will need to create only one data source and three authentication aliases (one for each db/schema user).  The number of data sources you create will depend on which database vendor you are using and your database configuration.  In the example below, we create a single data source and three authentication aliases (one per schema user):

Click Resources > JDBC > Data sources

1. From the Scope drop-down list select Cell= ctgCell01
2. Click New.
3. Enter the following information
1. Data source Name Enter oraclexads
2. JNDI Name Enter jdbc/oraclexads
3. Component-managed authentication alias Select (none)
4. Click Next
5. Select an existing JDBC provider oraclexa
6. Click Next
7. Enter the JDBC URL information using the format shown below:
  • URL Enter jdbc:oracle:thin:@<hostname.domain.com>:1521:<yourdbname>
  • Data store helper class name Select Oracle11g data store helper
  • data source in container managed persistence (CMP) <Checked>
8. Click Next
9. Click Finish
10. Click Save
11. Click oraclexads to open the dialog box
12. Click JAAS - J2C authentication data
13. Click New.
14. Enter the user information for the first schema
  • Alias Enter me1
  • User ID Enter me1
  • Password Enter <PASSWORD>
15. Click OK
16. Click Save
17. Click Resources > JDBC > Data sources > oraclexads
18. Select ctgCellManager01/me1 for Component-managed authentication alias
19. Click OK
20. Click Save
21. Using the steps from 12 to 17, create four remaining schemas and save the changes.The end result will be a total of three authentication aliases created using the following aliases:

me1

me2

me3
22.  Test your data source connection.  Once successful, proceed to the next step.

4. Creating the JMS Bus

1. Click Service Integration > Buses to open the Buses dialog
2. Click New to create a new bus
3. Enter mifjmsbus as the name of the new bus
4. Deselect the Bus security check box
5. Click Next
6. Click Finish
7. Click Save

 5. Adding Clusters to the service integration bus

Add the UI Cluster to the bus

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Under Topology on the right, click Bus members.
4. In the Buses > mifjmsbus > Bus members dialog box, click Add
5. Click the Cluster drop-down arrow, and select the cluster uicluster to add to the bus, and then click Next
6. Check that the data store radio button is selected, and then click Next
7. Check that the Use existing data store radio button is selected
8. Enter the following information

  • Data source JNDI name Enter jdbc/oraclexads
  • Schema name Enter me1
  • Authentication alias Select ctgCellManager01/me1
  • Create tables <checked>

9. Click Next
10. Click Finish
11. Click Save

 Add the Cron Cluster to the bus

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Under Topology, click Bus members
4. In the Buses > mifjmsbus > Bus members dialog box, click Add
5. Click the Cluster drop-down arrow, and select the cluster croncluster and then click Next
6. Check that the data store radio button is selected, and then click Next
7. Check that the Use existing data store radio button is selected
8. Enter the following information:
  • Data source JNDI name Enter jdbc/oraclexads
  • Schema name Enter me2
  • Authentication alias Select ctgCellManager01/me2
  • Create tables <checked>
9. Click Finish
10. Click Save
11. Click OK

Add the IF Cluster to the bus

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Under Topology, click Bus members.
4. In the Buses > mifjmsbus > Bus members dialog box, click Add
5. Click the Cluster drop-down arrow, and select the cluster ifcluster to add to the bus, and then click Next
6. Check that the data store radio button is selected, and then click Next
7. Check that the Use existing data store radio button is selected
8. Enter the following information
  • Data source JNDI name Enter jdbc/oraclexads
  • Schema name Enter me3
  • Authentication alias Select ctgCellManager01/me3
  • Create tables <checked>
9. Click Finish
10. Click Save

6. Creating the destination for the continuous inbound (CQINBD) queue

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Click Destinations under Destination resources on the right
4. Click New
5. Leave Queue radio button checked as the destination type, and click Next
6. Type CQINBD in the Identifier field then click Next
7. Select the Bus Member pull-down and choose cluster ifcluster as the bus member
8. Click Next to open the confirm queue creation dialog box
9. Review your selections, then click Finish
10. Navigate again to Buses > mifjmsbus> Destinations, then click CQINBD
  • Click Specify as the Exception destination value
  • Enter CQINERRBD as the Exception destination value
  • Change the Maximum failed deliveries value to 5
11. Click Apply
12. Click Save

7. Creating the destination for the sequential inbound (SQINBD)

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Click Destinations under Destination on the right side of the screen
4. Click New
5. Leave Queue checked as the destination type, and click Next
6. Enter SQINBD in the Identifier, then click Next
7. Select the Bus Member pull-down and choose cluster ifcluster
8. Click Next
9. Review your selections, then click Finish
  • Navigate the path Buses > mifjmsbus > Destinations, then click SQINBD
Click None as the Exception destination value.
10. Click Apply
11. Click Save

8. Creating the destination for the sequential outbound (SQOUTBD) queue

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Click Destinations under Destination resources on the right side of the screen
4. Click New
5. Leave Queue checked as the destination type, and click Next
1. Enter SQOUTBD in the Identifier field, then click Next
2. Select the Bus Member pull-down and choose cluster uicluster as the bus member
3. Click Next
4. Click Finish
  • Navigate to Buses > mifjmsbus > Destinations, then click SQOUTBD
  • Click None as the Exception destination value
5. Click Apply
13. Click Save

9. Creating the destination for the inbound error queue (CQINERRBD) queue

1. From the WebSphere administrative console, click Service Integration > Buses
2. Click mifjmsbus
3. Click Destinations under Destination resources on the right side of the screen
4. Click New
5. Leave Queue checked as the destination type, and click Next
6. Enter CQINERRBD in the Identifier field, then click Next
7. Select the Bus Member pull-down and choose Cluster ifcluster
8. Click Next
9. Click Finish
10. Navigate to Buses > mifjmsbus > Destinations, then click CQINERRBD
  • Click Specify as the Exception destination value
  • Enter CQINERRBD as the Exception destination value
  • Change the Maximum failed deliveries value to 5
11. Click Apply
12. Click Save


10. Creating the JMS connection factory

1. From the WebSphere administrative console, click Resources → JMS → Connection factories.
2. From the Scope drop-down list select Cell=ctgCell01
3. Click New
4. Verify that the Default Messaging Provider is selected and click OK
5. Enter the following information, and then click OK
  • Name Enter intjmsconfact
  • JNDI name Enter jms/maximo/int/cf/intcf
  • Bus name Select mifjmsbus
6. Click Save


11. Creating the continuous inbound (CQIN) JMS queue

1. From the WebSphere administrative console, click Resources > JMS > Queues
2. From the Scope drop-down list, select Cell=ctgCell01
3. Click New
4. Verify that the Default Messaging Provider is selected and click OK
5. Enter the following information, and click OK
  • Name Enter CQIN
  • JNDI name Enter jms/maximo/int/queues/cqin
  • Bus name Select mifjmsbus
  • Queue name Select CQINBD
6. Click OK
7. Click Save

12. Creating the sequential inbound (SQIN) JMS queue

1. From the WebSphere administrative console, click Resources > JMS > Queues
2. From the Scope drop-down list, select Cell=ctgCell01
3. Click New
4. Verify that the Default Messaging Provider is selected and click OK
5. Enter the following information, and click OK
  • Name Enter SQIN
  • JNDI name Enter jms/maximo/int/queues/sqin
  • Bus name Select mifjmsbus
  • Queue name Select SQINBD
6. Click OK
7. Click Save


13. Creating the sequential outbound (SQOUT) JMS queue

1. From the WebSphere administrative console, click Resources > JMS > Queues
2. From the Scope drop-down list, select Cell=ctgCell01
3. Click New
4. Verify that the Default Messaging Provider is selected and click OK
5. Enter the following information, and click OK
  • Name Enter SQOUT
  • JNDI name Enter jms/maximo/int/queues/sqout
  • Bus name Select mifjmsbus
  • Queue name Select SQOUTBD
6. Click OK
7. Click Save

14. Creating the error (CQINERR) JMS queue

1. From the WebSphere administrative console, click Resources > JMS > Queues
2. From the Scope drop-down list, select Cell=ctgCell01
3. Click New
4. Verify that the Default Messaging Provider is selected and click OK
5. Enter the following information, and click OK
  • Name Enter CQINERR
  • JNDI name Enter jms/maximo/int/queues/cqinerr
  • Bus name Select mifjmsbus
  • Queue name Select CQINERRBD
6. Click OK
7. Click Save


15. Creating JMS activation specification for the continuous inbound queue (CQIN)

1. From the WebSphere administrative console, click Resources → JMS → Activation Specifications
2. From the Scope drop-down list, select Cell=ctgCell01
3. Click New
4. Click OK
5. Enter the following information, and then click OK
  • Name intjmsact
  • JNDI name intjmsact
  • Destination type Queue
  • Destination JNDI name jms/maximo/int/queues/cqin
  • Bus name mifjmsbus
  • Maximum concurrent endpoints 5
  • Maximum batch size 10
  • Check “Always activate MDB in all servers”
6. Click OK
7. Click Save

16. Creating JMS activation specification for the inbound error queue (CQINERR)

1. From the WebSphere administrative console, click Resources > JMS > Activation Specifications.
2. From the Scope drop-down list, select Cell=ctgCell01
3. Click New. to complete the General Properties section for the new JMS activation specification.
4. Click OK
5. Enter the following information, and click OK.
  • Name Enter intjmsacterr.
  • JNDI name Enter intjmsacterr
  • Destination type Enter Queue
  • Destination JNDI name jms/maximo/int/queues/cqinerr
  • Bus name mifjmsbus
  • Maximum batch size 10
  • Maximum concurrent endpoints 5
  • Check the checkbox “Always activate MDB in all servers”
6. Click OK
7. Click Save

17. Enable the Message Driven beans for the Integration Framework maximo.ear file. To do so, modify the ejb-jar.xml and ibm-ejb-jar-bnd.xmi files.

Open the file /opt/IBM/SMP/maximo/applications/maximo/mboejb/ejbmodule/META-INF/ejb-jar.xml

The file contains two sections that have Message Driven beans (MDBs) commented out and will look like the contents below:

  <!-- MEA MDB        <message-driven id="MessageDriven_JMSContQueueProcessor_1">        <ejb-name>JMSContQueueProcessor-1</ejb-name>        <ejb-class>psdi.iface.jms.JMSContQueueProcessor</ejb-class>        <transaction-type>Container</transaction-type>        <message-destination-type>javax.jms.Queue</message-destination-type>        <env-entry>          <env-entry-name>MESSAGEPROCESSOR</env-entry-name>          <env-entry-type>java.lang.String </env-entry-type>          <env-entry-value>psdi.iface.jms.QueueToMaximoProcessor</env-entry-value>        </env-entry>      </message-driven>  -->      <!-- MEA MDB for error queue      <message-driven id="MessageDriven_JMSContQueueProcessor_2">        <ejb-name>JMSContQueueProcessor-2</ejb-name>        <ejb-class>psdi.iface.jms.JMSContQueueProcessor</ejb-class>        <transaction-type>Container</transaction-type>        <message-destination-type>javax.jms.Queue</message-destination-type>          <env-entry>          <env-entry-name>MESSAGEPROCESSOR</env-entry-name>          <env-entry-type>java.lang.String </env-entry-type>          <env-entry-value>psdi.iface.jms.QueueToMaximoProcessor</env-entry-value>        </env-entry>          <env-entry>          <env-entry-name>MDBDELAY</env-entry-name>          <env-entry-type>java.lang.Long </env-entry-type>          <env-entry-value>30000</env-entry-value>        </env-entry>               <env-entry>          <env-entry-name>ERRORQUEUE</env-entry-name>          <env-entry-type>java.lang.String </env-entry-type>          <env-entry-value>1</env-entry-value>        </env-entry>           </message-driven>  -->    <!-- MEA MDB      <container-transaction>          <method>             <ejb-name>JMSContQueueProcessor-1</ejb-name>             <method-name>*</method-name>          </method>          <trans-attribute>Required</trans-attribute>      </container-transaction>  -->    <!-- MEA MDB for error queue      <container-transaction>          <method>             <ejb-name>JMSContQueueProcessor-2</ejb-name>             <method-name>*</method-name>          </method>          <trans-attribute>Required</trans-attribute>      </container-transaction>  -->

Uncomment the MDBs.  Uncommented, the MDBs will look like the following:

  <!-- MEA MDB  -->      <message-driven id="MessageDriven_JMSContQueueProcessor_1">        <ejb-name>JMSContQueueProcessor-1</ejb-name>        <ejb-class>psdi.iface.jms.JMSContQueueProcessor</ejb-class>        <transaction-type>Container</transaction-type>        <message-destination-type>javax.jms.Queue</message-destination-type>        <env-entry>          <env-entry-name>MESSAGEPROCESSOR</env-entry-name>          <env-entry-type>java.lang.String </env-entry-type>          <env-entry-value>psdi.iface.jms.QueueToMaximoProcessor</env-entry-value>        </env-entry>      </message-driven>  	  <!-- MEA MDB for error queue -->      <message-driven id="MessageDriven_JMSContQueueProcessor_2">        <ejb-name>JMSContQueueProcessor-2</ejb-name>        <ejb-class>psdi.iface.jms.JMSContQueueProcessor</ejb-class>        <transaction-type>Container</transaction-type>        <message-destination-type>javax.jms.Queue</message-destination-type>        <env-entry>          <env-entry-name>MESSAGEPROCESSOR</env-entry-name>          <env-entry-type>java.lang.String </env-entry-type>          <env-entry-value>psdi.iface.jms.QueueToMaximoProcessor</env-entry-value>        </env-entry>        <env-entry>          <env-entry-name>MDBDELAY</env-entry-name>          <env-entry-type>java.lang.Long </env-entry-type>          <env-entry-value>30000</env-entry-value>        </env-entry>             <env-entry>          <env-entry-name>ERRORQUEUE</env-entry-name>          <env-entry-type>java.lang.String </env-entry-type>          <env-entry-value>1</env-entry-value>        </env-entry>           </message-driven>  	  <!-- MEA MDB -->      <container-transaction>          <method>             <ejb-name>JMSContQueueProcessor-1</ejb-name>             <method-name>*</method-name>          </method>          <trans-attribute>Required</trans-attribute>      </container-transaction>  	  <!-- MEA MDB for error queue -->      <container-transaction>          <method>             <ejb-name>JMSContQueueProcessor-2</ejb-name>             <method-name>*</method-name>          </method>          <trans-attribute>Required</trans-attribute>      </container-transaction>

Open the file /opt/IBM/SMP/maximo/applications/maximo/mboejb/ejbmodule/META-INF/ibm-ejb-jar-bnd.xmi. The file contains a section that has Message Driven beans (MDBs) commented out and will look like the contents below:

  <!-- MEA MDB    <ejbBindings xmi:type="ejbbnd:MessageDrivenBeanBinding" xmi:id="MessageDrivenBeanBinding_1" activationSpecJndiName="intjmsact">      <enterpriseBean xmi:type="ejb:MessageDriven" href="META-INF/ejb-jar.xml#MessageDriven_JMSContQueueProcessor_1"/>    </ejbBindings>  -->    <!-- MEA MDB for error queue    <ejbBindings xmi:type="ejbbnd:MessageDrivenBeanBinding" xmi:id="MessageDrivenBeanBinding_1" activationSpecJndiName="intjmsacterr">      <enterpriseBean xmi:type="ejb:MessageDriven" href="META-INF/ejb-jar.xml#MessageDriven_JMSContQueueProcessor_2"/>    </ejbBindings>  -->

Uncomment the MDBs so they look like the following:

  <!-- MEA MDB -->    <ejbBindings xmi:type="ejbbnd:MessageDrivenBeanBinding" xmi:id="MessageDrivenBeanBinding_1" activationSpecJndiName="intjmsact">      <enterpriseBean xmi:type="ejb:MessageDriven" href="META-INF/ejb-jar.xml#MessageDriven_JMSContQueueProcessor_1"/>    </ejbBindings>    <!-- MEA MDB for error queue -->    <ejbBindings xmi:type="ejbbnd:MessageDrivenBeanBinding" xmi:id="MessageDrivenBeanBinding_1" activationSpecJndiName="intjmsacterr">      <enterpriseBean xmi:type="ejb:MessageDriven" href="META-INF/ejb-jar.xml#MessageDriven_JMSContQueueProcessor_2"/>    </ejbBindings>

NOTE:  the MDBs are only to be uncommented for the IF ear.  For the UI and CRON maximo ear files, the MDBs are commented out in both the ejb-jar.xml and the ibm-ejb-jar-bnd.xmi.

18. Which cron tasks should run where?

Now that we have three clusters, and all of our JMS resources have been created and the MDBs deployed, we will need to set properties to control where cron tasks will run.

Here are a list of cron tasks that we will need to consider:

JMSQSEQCONSUMER.SEQQOUT

JMSQSEQCONSUMER.SEQQIN

IFACETABLECONSUMER

FLATFILECONSUMER

XMLFILECONSUMER

All other cron tasks

The Message Driven beans will only be deployed to ifcluster and will be activated in both server instances in this cluster.

All cron tasks should be configured to run in the croncluster with the exception of integration related crontask instances.  The cron task JMSQSEQCONSUMER.SEQQOUT should be configured to run in the uicluster, where the sqout queue point for this queue has been assigned.  This ensures that the queue point is available when users are able to log into the uicluster and messages will be delivered to their destination regardless of the status of any of the servers in ifcluster or croncluster.

The JMSQSEQCONSUMER.SEQQIN, IFACETABLECONSUMER, FLATFILECONSUMER, XMLFILECONSUMER crontask instances should be configured to run in the ifcluster, where the cqin, cqinerr, and sqin queue points have been assigned.   This keeps inbound message processing on the mifcluster and will have no dependency on the uicluster or croncluster.

 The mxe.crontask.donotrun or mxe.crontask.dorun properties can be specified in the maximo.properties file for each cluster to simplify the configuration.  Below is an example of what would be configured:

uicluster maximo.properties:

mxe.crontask.dorun=JMSQSEQCONSUMER.SEQQOUT

ifcluster maximo.properties:

mxe.crontask.dorun=JMSQSEQCONSUMER.SEQQIN, IFACETABLECONSUMER.instancename, FLATFILECONSUMER.instancename,XMLFILECONSUMER.instancename

croncluster maximo.properties:

mxe.crontask.donotrun=JMSQSEQCONSUMER.SEQQOUT,IFACETABLECONSUMER.instancename, FLATFILECONSUMER.instancename,XMLFILECONSUMER.instancename,JMSQSEQCONSUMER.SEQQIN

NOTE: Be sure to replace your crontask instance name with the actual name of your crontask instance.

19.  Rebuild and redeploy the maximo.ear for each cluster


Putting it all together

Now that we have configured the system, how does it work? Here is a high level description of how data might be retrieved from the Maximo interface tables associated with an external system, sent to the continuous inbound queue.

  • Data is entered into the interface table associated with a Maximo enterprise service and external system, then the mxin_inter_trans queue table
  • The IFACETABLECONSUMER crontask runs in croncluster and picks up the messages from the interface table and routes them to ifcluster since that is where the queue point destination is hosted for both the continuous and sequential inbound queues
  • The message driven beans running in the ifcluster members pick up the messages in the continuous queue and process them into Maximo. If the messages are routed to the sequential inbound queue, the JMSQSEQCONSUMER.SEQQIN crontask instance will pick up the messages and process them into Maximo.

When data is saved by a user in Maximo which triggers an event to write the message to the sequential outbound queue, the message is written to the sequential outbound queue point assigned to the uicluser.  The sequential outbound crontask JMSQSEQCONSUMER.SEQQOUT which also runs on uicluster will pick up the messages and deliver them to the respective external system endpoints.

If croncluster runs an escalation that causes an event to trigger an outbound message to the sequential outbound queue, since croncluster is a member of the same bus, it can access the sequential outbound queue point assigned to uicluster, even if the uicluster is down, due to store and forward behavior.  The same is true for the ifcluster in that it will have access to the sequential outbound queue if needed without additional configuration required.  If croncluster and ifcluster are both down, uicluster will continue to function independently from the others allowing users to continue working and sending data to external systems without interruption.

For any questions regarding this configuration, contact IBM Support.

[{"Product":{"code":"SSLKT6","label":"IBM Maximo Asset Management"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Component":"MEA: Generic","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"7.6","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}},{"Product":{"code":"SS4RKY","label":"Maximo Integration Adapter"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Component":" ","Platform":[{"code":"","label":""}],"Version":"","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]

Document Information

Modified date:
18 November 2021

UID

swg21989836