Configuring the MQ Service Provider for z/OS Connect EE
Matt Leming from MQ development in an earlier blog entry provided a detailed overview of the MQ Service Provider for z/OS Connect and how it can be used to send and receive messages using REST APIs. Support for accessing IBM MQ with REST APIs using IBM z/OS Connect EE was shipped with IBM MQ V9.0.1 and concurrently made available as a download from IBM Fix Central, (see the MQ Knowledge Center for details about obtaining the code from Fix Central). In this blog entry I want to provide details on how I installed and configured the MQ Service Provider for z/OS Connect EE in an existing z/OS Connect EE (zCEE) server and also how I developed and tested a RESTful API interface for the MQ service defined in the zCEE server.
Add the MQ Service Provider to the z/OS Connect EE configuration
The first decision made was to keep changes to the existing z/OS Connect server’s configuration file (server.xml) to a minimum. This was done by adding an include element to the server’s existing configuration file. The include element identified an external file (miniloan.xml) which will contain the MQ Service Provider configuration information and the connection details required to access a queue manager and specific queues.
The zosConnectDataXform element is shared among multiple APIs. This element identifies the directories that contain the JSON schema files and language structure to JSON (and vice-a-versa) conversion artifacts (wsbind files). This element will be referenced by elements in miniloan.xml.
The Liberty features required for the MQ Provider were added in the featureManager element of the miniloan.xml file. The MQ Service provider is a MQ JMS client so most of the features are the same features required by any JMS client application. The exception is the MQ Service Provider feature itself (e.g. mqzosconnect:zosConnectMQ-2.0).
Another requirement for running a JMS client application in Liberty is to provide the location of the JMS provider’s (IBM MQ) resource adapter file using variable wmqJMSClient.rar.location and the location of any JMS Provider’s executable binaries using variable nativeLibraryPath. Extending the z/OS Connect EE product by adding support for a new service provider required adding a properties file in the z/OS Connect extensions directory. This file was added by copying file mqzosconnect.properties from the MQ Provider directory to the z/OS Connect extensions directory, e.g. /var/zosconnect/v2r0/extensions. The productInstall directive in the file was updated to provide the root directory of the MQ Service provider. Since this file was encoded in ASCII an ASCII enabled editor (i.e., the ISPF line command EA) was used, see an example of the updated file below:
Add JMS resources to the z/OS Connect EE configuration
JMS applications running in Java container requires a name space which provides queue manager connection information (jmsConnectionFactory) and queue information (jmsQueue). This name space is accessed when the JMS application does a Java Naming and Directory Interface (JNDI) lookup during execution. This name space lookup also applies for the MQ Service Provider running in z/OS Connect EE server. For a JMS application running in Liberty the elements required for the name space also reside in the server’s configuration file. The same external file (miniloan.xml) was used for the JNDI configuration elements. The JMS elements below show the jmsConnectionFactory element with the attributes required to connect to the target queue manager and three jmsQueue elements with the attributes required to access 3 queues defined in that queue manager.
- The jmsConnectionFactory element associates the JMS connection factory (jndiName) with the target queue manager and details on how to connect to this queue manager.
- The jmsQueue elements provide details that associate the JMS destination (jndiName) with the target queue (baseQueueName) and its MQ JMS properties. In particular the MQ JMS property of CCSID=37 was added to ensure the message would be converted to EBCDIC and the targetClient property was added to indicate that no MQRFH2 header was to be included (the target application is an MQI application which does not expect an MQRFH2 header).
Add the MQ Service Provider elements to the server’s configuration
The MQ Service Provider and JMS resources have been added to the z/OS Connect configuration. The next step was to add the z/OS Connect MQ API service elements to the configuration. First the services were defined to z/OS Connect using zosConnectService elements and then for each service the MQ and JMS attributes for that service were provided using an mqzOSConnectionService element.
In the above example there are two services defined, Miniloan and FileaQueue. Service Miniloan will connect to the queue manager associated with JNDI name jms/qmgrCf and send messages to queue with JNDI name jms/request and retrieve messages from the queue with JNDI name jms/response. Service FileaQueue also connects to the queue manager associated with JNDI name jms/qmgrCf but perform only puts to or gets from the queue with JNDI name jms/default. The JMS elements defined earlier provides details, such as queue manager name, queue name, port, host, etc.
The Complete miniloan.xml file
The complete miniloan.xml file is shown below.
Create a Service Archive File
Two services have been defined to z/OS Connect, Miniloan and FileaQueue.
The Miniloan service is an example of a two-way service. The Miniloan service uses the MQ Service Provider to put a message on a request queue which has a trigger enabled so that when a message arrives a CICS application is started. The CICS application retrieves the request message from the request queue and processes a loan application. The results of the loan application process are returned as a message in the response queue. The MQ Service Provider returns the message to the REST client as a JSON response message. The CICS application is invoked using a CICS COMMAREA so the request and response messages had the same layout (see below). For a two-way service the only valid HTTP method is POST (create a new message and wait for a response).
The FileaQueue service is an example of a one-way service. The FileaQueue service uses the MQ Service Provider to send and receive messages from a single queue. For a one-way service the valid HTTP methods are POST (create a new message), GET (non-destructive get of a message) and DELETE (destructive get of a message).
For the Miniloan service we wanted to take advantage of the some of the advanced features provided by z/OS Connect EE. For example there is no need for a client to provide messages in their request so the two fields messages and messages-Num, should be removed from the request interface. Also we want to set the value of the approved field to ‘F’ (false) and the value of the yearlyInterestRate field to 00005 and not expose these fields to the REST client at all. No changes would be required for the request and response messages of the FileaQueue service.
To change the request and response messages for the Miniloan API the Eclipse based IBM z/OS Connect EE API Editor would be required. This is software that can be added to most Eclipse based tooling by adding as a software repository the URL http://public.dhe.ibm.com/ibmdl/export/pub/software/htp/zos/tools/aqua/).
The API Editor tool requires the importing of a Service Archive (SAR) file in order to do the desired mapping. The SAR file is a zip file containing the JSON schema representing the API request and response messages along with other information. An SAR file for the Miniloan service was generated using the z/OS Connect BAQLS2JS utility. The information needed is a COBOL structure representing the MQ message layout.
Below is an example of the JCL used to invoke the BAQLS2JS utility.
Below were the contents of the MINILOAN member used for input to the utility:
- Pointers to the data set where the request and response COPYBOOK member is located
- Pointers to the directory where the request and response JSON schemas will be created
- The PGMINIT indicates that this is a COMMAREA application.
- Pointers to the target directories for the binding file (required at runtime) and the service archive (SAR) file. The SAR file will be downloaded to a workstation where it will be imported in the z/OS Connect Enterprise Edition eclipse tooling.
This job was submitted and run successfully to completion. The generated SAR file was downloaded in binary format to the system where the z/OS Connect API Editor was installed.
Compose the API for the MQ Trigger Monitor Application
The downloaded SAR file was used to develop the MQ API for the Miniloan service. The SAR file was imported into the API Editor workspace and a z/OS Connect EE project created. Since an MQ two way service only supports the POST method the other methods were deleted.
The messages and message_Num fields are not meaningful in a request messages so these fields were removed during the mapping of the request message. Also a default interest rate of 0.00005% was assign to field yearlyInterestRate and a default of F (false) was assign to the approved field. No changes were made to the response message mapping. When the mapping changes were complete the API was deployed to the z/OS Connect server.
Test the MQ Miniloan Two-way API
The application used to the test the MQ API is a CICS application that used business rules for approving loan requests. The CICS transaction that invokes the application is started when a message is written to a request queue. The arrival of a message triggers the CICS transaction which starts a program which reads the message from the request queue. The application uses the information in the message to determine if a loan can be approved. The results are returned in a message in a reply queue including the explanation if the loan is denied.
The rules for rejecting a loan can be for any one of the following:
- If the credit score of the borrower is less than 300.
- If the yearly repayment amount is more than 30% of the borrower’s income.
- If the income of the borrower is less than $24,000.
- If the age of the borrower is more than 65 years.
- The loan amount is more than $1,000,000.
The RESTClient extensions (https://restclient.net) was added to a browser to provide a simple REST client add-on. This add-on add an icon that looks like this:
The RESTClient was opened and the Request Method was set to POST and the Header was set to Content-Type: application/json. The JSON below was entered into the Body area and the URL was set to https://host:port/miniloan.
Where host is the TCP/IP host name was the zCEE is running and port is the port on which the zCEE server is listening for inbound requests. The /miniloan part of the URI is the Base path provided when the API was developed.
When Send was clicked, the request message was sent to the zCEE server where the JSON message was transformed into a COMMAREA format and defaults values were assign to the yearlyIntererstRate and approved fields. The message was placed on the request queue and a trigger message was sent to CICS. The CICS application started and read the message from the queue and processed the loan request. The response message was placed into the response queue and the zCEE server retrieved the message and converted it back to a JSON format. If successful there should be a 200 OK status code in the Response Header area and a display of the response from the loan application in the Response Body (Preview). This is the message from the application returned in the reply queue
Changing the JSON body to the JSON below and pressing SEND again.
Resulted in a message that the loan have been approved.
Test the MQ One Way Service
A MQ “one way” service provides a REST interface for putting to and getting messages from a queue (or topic). The “one way” service only supports REST method; POST (‘put’ a message) , GET (nondestructive get of a message), and DELETE (destructive get of a message). Remember, the PUT method is not supported by the MQ for z/OS Service provider for z/OS Connect. The “one way” service, FileaQueue did not require an API since no mapping was going to be performed. A SAR could have been generated but there was no need in this case.
Again using the RESTClient plugin, the HTTP method was set to GET and the Header to Content-Type: application/json. The URL was set to https://host:port/FileaQueue and Send was pressed. The GET method performs a nondestructive get of the first message in the queue (see below). No response message was expected.
Where host is the TCP/IP host name was the zCEE is running and port is the port on which the zCEE server is listening for inbound requests. The /FileaQueue part of the URI is the value of the invokeURI provided in the server configuration zosConnectService element when the services was defined.
MQExplorer was used to browse the messages in the ZCONN2.DEFAULT.MQZCEE.QUEUE queue to confirm the new message had arrived.
Changing the Method to DELETE and press SEND again and review the response a few times. Each response was a different message and a review of the messages on the queue showed the count going down. (DELETE is destructive).
Changing the Method to POST and entering the JSON below in the Body area and pressing SEND resulted in no response being returned.
Using the MQ Explorer to browse the queue again showed this message as appearing first in the queue.
Now the MQ for z/OS Service Provider for z/OS Connect has been added to the z/OS Connect EE server and two services configured. One service (Miniloan) supports a reply/response application using two queues and the other service (FileaQueue) is a one way service where the same queue is used for both PUTs and GETs.