Use data transformations with the MQ Service Provider

z/OSĀ® Connect provides the ability to transform JSON data to an arbitrary format before calling a back-end z/OS asset, such as a CICSĀ® transaction, and transform the response from the z/OS asset back into JSON.

This ability is provided by pluggable data transformation providers. A built in provider allows JSON to be transformed to or from COBOL, PLI, or C structures.

The MQ Service Provider works with z/OS Connect data transformations, but there are a number of considerations that you should take account of.


More information on z/OS Connect data transformations

For z/OS Connect Enterprise Edition, see Defining data transformers.

For z/OS Connect Version 1, see Defining z/OS Connect message payload transformations.


Sending messages to IBM MQ

When an MQ Service Provider service is configured with a data transformation, and is going to send a message to a queue manager (for example if it is a one-way or two-way service that has received an HTTP POST containing JSON) the MQ Service Provider performs the following steps:
  1. Takes the JSON payload from the HTTP request.
  2. Passes the payload to z/OS Connect to perform data transformation from JSON to a byte array.
  3. Takes the result of the data transformation and sends it to the queue manager in the form of a JMS BytesMessage.

By default, the message that is sent has a blank MQMD Format field. In many cases this is not appropriate, so we can set the mqmdFormat attribute in the mqzOSConnectService element to an appropriate value.

The built in data transformation support always generates output with a CCSID of 37. This information needs to be specified in the MQMD CodedCharSetId field, otherwise the application getting from the queue might not be able to decode the message. You do this by setting the CCSID attribute on the queue referenced by the mqzOSConnectService service element.

The following example configuration illustrates appropriate configuration for a one-way service, that is going to be used to send messages to a queue called SampleQ1.

The messages are to be sent with an MQMD Format field of AFORMAT and a CodedCharSetId field of 37.

The zosConnectDataXform element tells z/OS Connect where to locate configuration for data transformations, and is referred to using the dataXformRef attribute of the zosConnectService element.

For configuration for a two way service see Receiving messages from IBM MQ.
<jmsConnectionFactory 
  id="sampleCF1"
  jndiName="jms/sampleCF1"
  connectionManagerRef="sampleCF1ConnectionManager">

  <properties.wmqJms 
    transportType="BINDINGS" 
    queueManager="MQ21"/>
</jmsConnectionFactory>

<connectionManager 
  id="sampleCF1ConnectionManager" 
  maxPoolSize="5"/>

<jmsQueue id="sampleQ1" 
  jndiName="jms/sampleQ1">

  <properties.wmqJms 
    baseQueueName="SampleQ1"
    CCSID="37"/>
</jmsQueue>

<zosConnectService 
  id="samplezOSConnectService1" 
  invokeURI="/samplezOSConnectService1"
  serviceName="samplezOSConnectService1_name" 
  serviceRef="samplezOSConnectService1_MQ" 
  dataXformRef="xformJSON2Byte"/>

<mqzOSConnectService 
  id="samplezOSConnectService1_MQ" 
  connectionFactory="jms/sampleCF1"
  mqmdFormat="AFORMAT" 
  destination="jms/sampleQ1" />

<zosConnectDataXform id="xformJSON2Byte"
  bindFileLoc="/XFORM_ROOT/bindfiles" bindFileSuffix=".bnd"
  requestSchemaLoc="/XFORM_ROOT/json" requestSchemaSuffix=".json"
  responseSchemaLoc="/XFORM_ROOT/json"
  responseSchemaSuffix=".json" />	
 


Receiving messages from IBM MQ

When an MQ Service Provider instance is configured with a data transformation, and is going to receive a message from a queue manager (for example if it is a one-way service actioning an HTTP GET or DELETE, or a two-way service that has received an HTTP POST) the MQ Service Provider performs the following steps.Attention: If you are using a two way service, the service will have already performed the steps described in Sending messages to IBM MQ.
  1. Gets the message from the queue.
  2. Checks that the message is either a JMS BytesMessage or a JMS TextMessage. If the message is neither, an error is generated and returned to the caller."
  3. Passes the message payload to z/OS Connect to perform data transformation from a byte array to JSON.
  4. Takes the result of the data transformation and returns it as the response of the HTTP method.

Depending on the type of message received you might need to carry out some extra configuration. This is because the MQ Service Provider needs to convert the received message payload into the correct format for passing to the configured data transformation.

The default data transformation expects payload to be in CCSID 37, however the z/OS asset might not be generating messages in this CCSID.

The configuration needed depends on whether a BytesMessage or TextMessage is received, and whether you are using z/OS Connect V1, or z/OS Connect EE.


BytesMessage received on z/OS Connect V1

If a BytesMessage is to be received then we can specify the receiveConversion="QMGR" and receiveCCSID="37" attributes on the queue definition that is used to receive the message.

This is illustrated in the following example. In this case, the sampleQ2Receive definition has both the receiveConversion and receiveCCSID attributes set.
<jmsConnectionFactory 
  id="sampleCF2"
  jndiName="jms/sampleCF2"
  connectionManagerRef="sampleCF2ConnectionManager">

  <properties.wmqJms 
    transportType="BINDINGS" 
    queueManager="MQ21"/>
</jmsConnectionFactory>

<connectionManager 
  id="sampleCF2ConnectionManager" 
  maxPoolSize="5"/>

<jmsQueue id="sampleQ2Send" 
  jndiName="jms/sampleQ2Send">

  <properties.wmqJms 
    baseQueueName="SampleQ2Send"
    CCSID="37"/>
</jmsQueue>

<jmsQueue id="sampleQ2Receive" 
  jndiName="jms/sampleQ2Receive">

  <properties.wmqJms 
    baseQueueName="SampleQ2Receive"
    receiveCCSID="37"
    receiveConversion="QMGR"/>
</jmsQueue>


<zosConnectService 
  id="samplezOSConnectService2" 
  invokeURI="/samplezOSConnectService2"
  serviceName="samplezOSConnectService2_name" 
  serviceRef="samplezOSConnectService2_MQ" 
 dataXformRef="xformJSON2Byte"/>

<mqzOSConnectService 
  id="samplezOSConnectService2_MQ" 
  connectionFactory="jms/sampleCF2"
  mqmdFormat="AFORMAT" 
  destination="jms/sampleQ2Send"
  replyDestination="jms/sampleQ3Receive" />

<zosConnectDataXform id="xformJSON2Byte"
  bindFileLoc="/XFORM_ROOT/bindfiles" bindFileSuffix=".bnd"
  requestSchemaLoc="/XFORM_ROOT/json" requestSchemaSuffix=".json"
  responseSchemaLoc="/XFORM_ROOT/json"
  responseSchemaSuffix=".json" />	


BytesMessage received on z/OS Connect EE

If a BytesMessage is to be received then we can specify the receiveConversion="QMGR" and receiveCCSID="37" attributes on the queue definition that is used to receive the message.

This is illustrated in the following example. In this case, the sampleQ2Receive definition has both the receiveConversion and receiveCCSID attributes set.
<jmsConnectionFactory 
  id="sampleCF2"
  jndiName="jms/sampleCF2"
  connectionManagerRef="sampleCF2ConnectionManager">

  <properties.wmqJms 
    transportType="BINDINGS" 
    queueManager="MQ21"/>
</jmsConnectionFactory>

<connectionManager 
  id="sampleCF2ConnectionManager" 
  maxPoolSize="5"/>

<jmsQueue id="sampleQ2Send" 
  jndiName="jms/sampleQ2Send">

  <properties.wmqJms 
    baseQueueName="SampleQ2Send"
    CCSID="37"/>
</jmsQueue>

<jmsQueue id="sampleQ2Receive" 
  jndiName="jms/sampleQ2Receive">

  <properties.wmqJms 
    baseQueueName="SampleQ2Receive"
    receiveCCSID="37"
    receiveConversion="QMGR"/>
</jmsQueue>


<zosconnect_zosConnectService 
  id="samplezOSConnectService2" 
  invokeURI="/samplezOSConnectService2"
  serviceName="samplezOSConnectService2_name" 
  serviceRef="samplezOSConnectService2_MQ" 
 dataXformRef="xformJSON2Byte"/>

<mqzosconnect_mqzOSConnectService 
  id="samplezOSConnectService2_MQ" 
  connectionFactory="jms/sampleCF2"
  mqmdFormat="AFORMAT" 
  destination="jms/sampleQ2Send"
  replyDestination="jms/sampleQ3Receive" />

<zosconnect_zosConnectDataXform id="xformJSON2Byte"
  bindFileLoc="/XFORM_ROOT/bindfiles" bindFileSuffix=".bnd"
  requestSchemaLoc="/XFORM_ROOT/json" requestSchemaSuffix=".json"
  responseSchemaLoc="/XFORM_ROOT/json"
  responseSchemaSuffix=".json" />	


TextMessage received on z/OS Connect V1

If a TextMessage is to be received then you need to convert the message to the CCSID expected by the data transformation, by default 37.

If we use a custom data transformation, and the transformation expects a different CCSID from 37, we can specify the receiveTextCCSID attribute in the mqzOSConnectService element to set an appropriate CCSID.

This is illustrated in the following example. In this case the sample zOSConnectService3_MQ definition has the receiveTextCCSID attribute in the mqzOSConnectService element attribute set to 1208 (UTF-8).

<jmsConnectionFactory 
  id="sampleCF3"
  jndiName="jms/sampleCF3"
  connectionManagerRef="sampleCF3ConnectionManager">

  <properties.wmqJms 
    transportType="BINDINGS" 
    queueManager="MQ21"/>
</jmsConnectionFactory>

<connectionManager 
  id="sampleCF3ConnectionManager" 
  maxPoolSize="5"/>

<jmsQueue id="sampleQ3Send" 
  jndiName="jms/sampleQ3Send">

  <properties.wmqJms 
    baseQueueName="SampleQ3Send"
    CCSID="37"/>
</jmsQueue>

<jmsQueue id="sampleQ3Receive" 
  jndiName="jms/sampleQ3Receive">

  <properties.wmqJms 
    baseQueueName="SampleQ3Receive"/>
</jmsQueue>


<zosConnectService 
  id="samplezOSConnectService3" 
  invokeURI="/samplezOSConnectService3"
  serviceName="samplezOSConnectService3_name" 
  serviceRef="samplezOSConnectService3_MQ" 
 dataXformRef="customDataXForm"/>

<mqzOSConnectService 
  id="samplezOSConnectService3_MQ" 
  connectionFactory="jms/sampleCF3"
  mqmdFormat="AFORMAT" 
  destination="jms/sampleQ3Send"
  replyDestination="jms/sampleQ3Receive"
  receiveTextCCSID="1208" />


TextMessage received on z/OS Connect EE

If a TextMessage is to be received then you need to convert the message to the CCSID expected by the data transformation, by default 37.

If we use a custom data transformation, and the transformation expects a different CCSID from 37, we can specify the receiveTextCCSID attribute in the mqzOSConnectService element to set an appropriate CCSID.

This is illustrated in the following example. In this case the sample zOSConnectService3_MQ definition has the receiveTextCCSID attribute in the mqzOSConnectService element attribute set to 1208 (UTF-8).

<jmsConnectionFactory 
  id="sampleCF3"
  jndiName="jms/sampleCF3"
  connectionManagerRef="sampleCF3ConnectionManager">

  <properties.wmqJms 
    transportType="BINDINGS" 
    queueManager="MQ21"/>
</jmsConnectionFactory>

<connectionManager 
  id="sampleCF3ConnectionManager" 
  maxPoolSize="5"/>

<jmsQueue id="sampleQ3Send" 
  jndiName="jms/sampleQ3Send">

  <properties.wmqJms 
    baseQueueName="SampleQ3Send"
    CCSID="37"/>
</jmsQueue>

<jmsQueue id="sampleQ3Receive" 
  jndiName="jms/sampleQ3Receive">

  <properties.wmqJms 
    baseQueueName="SampleQ3Receive"/>
</jmsQueue>


<zosconnect_zosConnectService 
  id="samplezOSConnectService3" 
  invokeURI="/samplezOSConnectService3"
  serviceName="samplezOSConnectService3_name" 
  serviceRef="samplezOSConnectService3_MQ" 
 dataXformRef="customDataXForm"/>

<mqzosconnect_mqzOSConnectService 
  id="samplezOSConnectService3_MQ" 
  connectionFactory="jms/sampleCF3"
  mqmdFormat="AFORMAT" 
  destination="jms/sampleQ3Send"
  replyDestination="jms/sampleQ3Receive"
  receiveTextCCSID="1208" />