Payara Server 171 was a huge release with lots of new features and improvements on many others. We've already written about improvements to the Request Tracing service and had a guest blog about using the email notifier.
The email notifier is just one of a whole host of notifiers we now have available. A lot were added in the 171 release and more are on their way in the imminent 172 release!
The current list of notifiers is:
- Log notifier
- Email notifier
- HipChat notifier
- JMS notifier
- Slack notifier
- SNMP notifier (tech preview)
- XMPP notifier
- Datadog notifier (available in the 172 release)
- New Relic notifier (available in the 172 release)
In this blog, I would like to focus on just one of these notifiers: the JMS notifier.
Why focus on the JMS notifier?
Since we are on the cusp of the 172 release of Payara Server and Payara Micro, this blog will take a look at an upcoming feature in Payara Micro - the ability to use Payara Micro as a JMS client!
Being derived from GlassFish, Payara Server inherited several editions, including "Full" and "Web" which, for GlassFish, correspond to the Java EE Full and Web Profiles. The Payara Server Full and Web editions contain the same set of APIs, but with the addition of JCache provided by Hazelcast being the sole change.
When we created Payara Micro, we started with the Payara Web edition and added Concurrency utilities and JBatch on top of the already-added JCache API. With the forthcoming 172 release of Payara Micro, we have added the ability to deploy JCA adapters - meaning you can now deploy a JMS resource adaptor (RAR) and use Payara Micro as a JMS client!
So how can I consume JMS notifications from Payara Micro?
Setting up this demo is relatively straightforward, although there are a few things to gather together first. We will use an example I prepared which listens on a specific queue for JMS messages using the JMS 1.1 API (this is because ActiveMQ does not yet support JMS 2.0)
The key parts of the relevant class - JMS11NotificationConsumer.java - are shown below:
1. Download Resources
You will need to make sure you have everything prepared in advance before following along with this blog. Do be aware that you need version 172 of Payara Micro, which may mean you need to download our snapshot build to preview the feature we're looking at. Our snapshot builds are always available from the website and track the master branch from our public GitHub repository:
Below is a checklist of everything you will need to download to follow along with this blog:
- Payara Micro 172+; and Payara Server 171+
- Payara Micro can be downloaded from the Payara Website. Your Payara Micro version will need to be 172 or higher and Payara Server will need to be 171 or higher.
- ActiveMQ Broker
- ActiveMQ Resource Adaptor (I used 5.14.5)
- JMS11NotificationConsumer example @ tag 2017.05.18
- This is one of our Payara Examples. If you've never used these before, I'll explain how to build this example in step 2.
- If you are following along, make sure to check out tag 2017.05.18 to make sure you have the right version for this post.
- Payara Micro 172+; and Payara Server 171+
2. Build the JMS11NotificationConsumer EJB JAR
If you haven't already cloned the Payara Examples repository, then you will need to do that now:
Next, change to the JMS11NotificationConsumer directory where the module's pom.xml is located and check out the right tag:
And finally, use Maven to build the JAR and install to your local Maven repository:
mvn clean install
Once that has completed, you should have an EJB JAR file that you can deploy to Payara Micro. It can't be deployed yet, however, because Payara Micro doesn't ship with any JMS RAR file.
3. Create Post-Deploy File
Payara Micro 171 introduced the ability to supply asadmin commands in files. Since you can't interact with Payara Micro on the command line after it has been started, we had to consider timing; certain commands need to be run later than others. For this example, we need to create a post-deploy.asadmin file with the following contents:
It's important to note that you may need to change the version number of your ActiveMQ RAR if you are using a different version, and you will need to change the deploy command to point to the resulting JAR file that you have built in step 2. Here, I am using the path to the JAR installed in my local Maven repository, so the path will never change in my environment, even if I run this example from a different directory.
4. Deploy to Payara Micro and Start ActiveMQ
By now, you should have downloaded Payara Micro, built the JMS11NotificationConsumer JAR and downloaded ActiveMQ.
Before we can run Payara Micro, we need to start ActiveMQ. It's not problematic to start them the other way round, but you will get periodic errors from Payara Micro as it tries and fails to connect to the local ActiveMQ broker every 30 seconds. If you haven't already extracted ActiveMQ, do that now and then start it with the following command:
java -jar apache-activemq-5.14.5/activemq-all-5.14.5.jar start
Assuming you are in the directory that you downloaded Payara Micro to, you can now start Payara Micro with the following command:
java -jar payara-micro.jar
--deploy activemq-rar-5.14.5.rar --postdeploycommandfile post-deploy.asadmin --port 9090
This command will result in Payara Micro:
- Booting Payara Micro on port 9090 (to avoid later port conflicts)
- Deploying the ActiveMQ RAR file
- Creating the resource adapter config, connection pool, connector resource, and queue
- Deploying our EJB JAR.
You should now see a message similar to the following at the bottom of the Payara Micro output:
2017-05-16 09:17:25,701 [l #1): worker-3] INFO ActiveMQEndpointWorker - Successfully established connection to broker [tcp://127.0.0.1:61616]
5. Configure Payara Server to use the ActiveMQ Resource Adaptor
Now, we can configure Payara Server to push notifications to the ActiveMQ queue where our EJB is listening. First, we need to deploy the same RAR to Payara Server (make sure Payara Server is started first!)
Next, rather than create connection resources ourselves, we can simply modify the default connection pool to use the ActiveMQ RAR we have just deployed, either through the admin console, or with the following asadmin command:
asadmin set resources.connector-connection-pool.jms/__defaultConnectionFactory-Connection-Pool.resource-adapter-name=activemq-rar-5.14.5
6. Configure the JMS Notifier
Now we have connection resources which use the ActiveMQ RAR, we can point the JMS notifier to our broker endpoint:
asadmin notification-jms-configure --password=admin --connectionFactoryName=jms/__defaultConnectionFactory --queueName=notifierQueue --contextFactoryClass=com.sun.enterprise.naming.SerialInitContextFactory --dynamic=true --enabled=true --url=localhost:61616 --username=admin --target=server-config
That's all the set up we need! Our next step is to prove that it works so, for that, we will enable the CPU checker in the HealthCheck service since we can reliably get regular notifications from it.
7. Test Notifications With the Healthcheck Service
To configure the HealthCheck service to log CPU activity every 5 seconds, use the following asadmin commands:
asadmin healthcheck-service-configure-checker-with-thresholds --thresholdWarning=50 --unit=MILLISECONDS --thresholdCritical=80 --checkerName=CPUC --dynamic=true --time=5000 --serviceName=healthcheck-cpu --thresholdGood=0 --enabled=true --target=server-config
asadmin healthcheck-configure --historicalTraceEnabled=false --notifierEnabled=true --dynamic=true --enabled=true --historicalTraceStoreSize=20 --target=server-config
You should now find both the Payara Server logs and our Payara Micro instance begin to log the same CPU checker notifications:
Using Payara Micro as a JMS client, you can now create your own microservice to listen for HealthCheck events and action them based on your own rules. You may notice from the above output that the log notifier from Payara Server will simply show the Healthcheck message, but the JMS notifier also sends out information on the server that is sending the notification. This can help you distinguish between which server is sending events and allow you to take action on a specific server if your conditions are met.