/ Management  

Discover the hidden power of the JMS Connector; Revive life and transform your world

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

Let’s start this post with my ChatGPT-friend on this request: Just a random question; What are best practices for implementing a loosely coupled architecture?. The response is amazing (as always!) with 2 out of the 12 highlights to share here:

  1. Decouple communication: Avoid direct communication between modules when possible. Use messaging systems, events, or message queues to enable asynchronous communication between components.
  2. Publish-Subscribe pattern: Implement a publish-subscribe pattern where modules can publish events and subscribe to events they are interested in. This way, modules don’t need to know about each other; they just communicate through the events.

Last week we installed Apache ActiveMQ; This week we dive into the OpenText JMS connector to boost our loosely coupled experiences. Almost every project has a request for this (especially from “Architectural roles”)…That’s also why I wanted to spend a good amount of time exploring it! Just to provide an answer to the request.


Let get right into it…

Boot up your AppWorks machine and make sure your ActiveMQ service is up and running as explained last week. Once both services are up and running, you need to make sure to login into the shared ‘/system’ space with your ‘sysadmin’ account. From this space we will deploy 2 new platform packages from the ‘Application Deployer’ artifact:

jms_001

In my screenshot they are already deployed, but you can follow the deployment wizard yourself…Not a hard task to do!

After this deployment I restart my TomEE instance sudo systemctl restart tomee as I see some deliveries (JAR’s) dropping off on the server as well! Now move to your own specific organization with your own developer/administration account. Open the ‘User Manager’ artifact and attach yourself to a new role called ‘JMS Connector Administrator’:

jms_002

With this new role applied, you will now see a new artifact passing by with the brilliant name ‘JMS Connector Configuration’. Open it and create yourself a new configuration with input from the below screenshots:

jms_003

jms_004

jms_005

So, the JMS configuration is called cfg_apache_activemq…It’s saved on the XMLStore /OpenText/JMSConnector!


The service container configuration part

The next step is to create a new service container of type ‘OpenText JMS Connector’ in the ‘System Resource Manager’ artifact. Use this as input to go through the wizard:

  • Groupname: sg_jms
    • Add the 2 available webservice interfaces
  • Service container name: sc_jms
    • You can let it start automagically
    • I do NOT connect it to any OS process…As ActiveMQ is already an application server process on its own. (not 100% sure, but it works well!)
    • Make sure to set the JRE Configuration tab to this specific JAR file: /opt/apache-activemq-5.18.2/activemq-all-5.18.2.jar
  • Select the configuration in the final step of the wizard: cfg_apache_activemq

Once the service container is up and running, you’ll see an active consumer is ActiveMQ as well:

jms_006


First AppWorks service call

I guess it’s time to fire our first ‘SendMessage’ SOAP call. Open the artifact ‘Web Service Interface Explorer’ and have a look for namespace http://schemas.cordys.com/jmsconnector/operations/3.0:

jms_007

Time to make a test request on ‘SendMessage’ like this:

1
2
3
4
5
6
7
8
9
10
11
<SOAP:Envelope>
<SOAP:Body>
<SendMessage>
<!--It's a 2-part value!; The DestinationManager.Name plus Destination.Name-->
<destination>apache_activemq.myqueue</destination>
<!--The documentation quotes Queue|Topic-->
<jmstype>Queue</jmstype>
<message>Hello world...</message>
</SendMessage>
</SOAP:Body>
</SOAP:Envelope>

This is a response you can expect:

1
2
3
4
5
<data>
<SendMessageResponse>
<messageid>ID:appworks.23.1.com-45019-1691418483069-1:1:2:1:1</messageid>
</SendMessageResponse>
</data>

I just send out 2 messages and this is my view in ActiveMQ:

jms_008

Behind the ‘Browse’-button, I find the exact 2 message IDs:

jms_009

You can open them and delete them, but we also receive them via another service call:

1
2
3
4
5
6
7
<SOAP:Envelope>
<SOAP:Body>
<GetMessage>
<destination>apache_activemq.myqueue</destination>
</GetMessage>
</SOAP:Body>
</SOAP:Envelope>

With a response:

1
2
3
4
5
6
7
8
9
10
<data>
<GetMessageResponse>
<message>
<![CDATA[Hello world...]]>
</message>
<messageid>ID:appworks.23.1.com-45019-1691418483069-1:1:2:1:1</messageid>
<jmstype>Queue</jmstype>
<fromdestination>apache_activemq.myqueue</fromdestination>
</GetMessageResponse>
</data>

This is the up-to-date ActiveMQ view after receiving 2 of my messages (2 x ‘GetMessage’) with the service call:

jms_010

This concludes me with an interesting FiFo (First-in; First-out) principle mimicking a row/queue of people/entries going inside a building via a ticket checker:


Documentation

Any documentation on the above knowledge? Just search for JMS in the AppWorks documentation artifact:

jms_011


Triggers

Yes, what about those triggers we saw in the screenshots above!? What can we do with these so-called “Inbound Message” triggers? Well, I made a first example with test values, but we can make it better with an example like this:

jms_012

Have a look in the documentation as it’s even possible to pass data (like {$inputmessage}) from the JMS message as input to that BPM!!

With this example I started to manually send messages with the webservice, receive messages with the webservice, and eventually I tried to just post a new message directly into the queue from the ActiveMQ administration portal…The conclusion? Nothing triggered my BPM…Strange!

After some blood, sweat, and tears, I made a change in my configuration…Specifically in the polling mechanism:

jms_013

With this configuration, I don’t have a direct “consumer” link to ActiveMQ, but it polls (in my case) every 5000 milliseconds (= 5 sec.) for new messages (can be from other external clients as well!); When you enable the logging on your service container to debug like this:

jms_014

You’ll see this message passing by on each interval: Thread jms-interval-poller of destination apache_activemq.myqueue is sleeping for 5000

Now when I put a new message on the queue, the poller picks it up and my BPM gets a trigger (see the PIM artifact for the instance)…NICEEEE! 🤗


Errors

Some errors that passed my journey…

When I attached my service container to the OS process:

1
2
3
4
java.lang.ClassCastException: class org.apache.activemq.ActiveMQXAConnectionFactory 
cannot be cast to class javax.jms.ConnectionFactory (org.apache.activemq.ActiveMQXAConnectionFactory
is in unnamed module of loader java.net.URLClassLoader @1d548a08;
javax.jms.ConnectionFactory is in unnamed module of loader com.eibus.applicationconnector.monitor.ProcessorClassLoader @6faa4687)

After switching it without OS process (running in own JMV):

1
2
JNDI not found or destination manager myqueue not found in JNDI.
Caused by: java.lang.ClassNotFoundException: org.apache.activemq.jndi.ActiveMQInitialContextFactory

This last error was solved by adding the activemq-all-5.18.2.jar to the JRE classpath of the service container (as already explained)!


That is a queuey(?) “DONE” where we all saw the power of a loosely coupled JMS principle to place messages on a queue and getting them off the queue via the FiFo technique. We (at least I) will have great benefits on this knowledge for my current project where the queue will be shared with a second external consumer where we want reliable message sharing across both platforms! Have a good weekend and I see you in the next one…🍺

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?