WebSphere Application Server & Liberty

JSR-352 (Java Batch) Post #79: The Multi-Server Batch Configuration – Job Routing

By David Follis posted Wed February 26, 2020 10:54 AM

This post is part of a series delving into the details of the JSR-352 (Java Batch) specification. Each post examines a very specific part of the specification and looks at how it works and how you might use it in a real batch application.

To start at the beginning, follow the link to the first post.

The next post in the series is here.

This series is also available as a podcast on iTunesGoogle PlayStitcher, or use the link to the RSS feed

We’ve been talking about how to solve the problem of needing to know which batch applications are installed in which servers, so you know which host/port to use to direct the REST request to submit a job.  So far, we’ve shown how configuring a WebSphere Liberty server as a dispatcher (or several servers as dispatchers) creates a front-end for the REST requests.  The dispatcher(s) then put a message on a queue that is picked up by an executor server which runs the job.  But we still haven’t seen how jobs end up in the right servers.

The basic configuration needed to establish a server as an executor just points to the right queue and defines an activation specification needed to get messages when they show up.  But if we go just a bit past that we can solve the last part of our problem.  Part of configuring an activation specification can be the definition of a message selector string.  This somewhat SQL-WHERE-clause-like string defines what messages should be handled by this server (instead of just handling any message that shows up). 

Message selectors allow you to select messages based on the attributes of the message.  This can include properties assigned to the message.  For example, if you know some messages on a queue will have a property named CLASS and you want to process only messages where that property is defined and has a value of “ABC” you can specify a message selector string of CLASS=’ABC’.  You can AND and OR together different specifications and some other fancier stuff to get exactly the messages you want.

So what?  Well, it turns out that when the dispatcher puts the message on the queue representing the job, it sets some properties on that message that you can use in a message selector string.  The first, and probably most important, is the application name.  The name of the application (basically the .war name) is a required parameter to submit a job using the REST interface.  The dispatcher creates a message property called com_ibm_ws_batch_applicationName and sets it to the specified application name.  Which means you can use that application name in the server configuration in the message selector to make sure the server only processes messages that will run batch jobs using applications that are deployed in this server.

Problem solved!  But wait, there’s more!  The dispatcher also takes any job parameters that are specified as part of submitting the job and turns them into properties on the message.  Thus, if you submit a job with a job parameter of JOBCLASS=’A’ you can have two servers that can run jobs in the same application, but one selects messages with JOBCLASS=’A’ and the other server selects messages where JOBCLASS is NOT A and all the A-class job go to the first server. 

One caution – message property names can’t contain dots, so things like com.ibm.my.property won’t work as property names (thus the underscores in the application name property).