Converting code page and message encoding

You can use ESQL within a Compute node to convert data for code page and message encoding.

About this task

If your message flow is processing IBM® MQ messages, you can use IBM MQ facilities (including get and put options and IBM MQ data conversion exits) to provide these conversions. If you are not processing IBM MQ messages, or you choose not to use IBM MQ facilities, you can use IBM App Connect Enterprise facilities by coding the appropriate ESQL in a Compute node in your message flow.

The contents of the MQMD, the MQRFH2, and the message body of a message in the MRM domain that has been modeled with a CWF physical format can be subject to code page and encoding conversion. The contents of a message body of a message in the XML, XMLNS, and JMS domains, and those messages in the MRM domain that have been modeled with an XML or TDS physical format, are treated as strings. Only code page conversion applies; no encoding conversion is required.

For messages in the MRM domain modeled with a CWF physical format, you can set the MQMD CCSID and Encoding fields of the output message, plus the CCSID and Encoding of any additional headers, to the required target value.

For messages in the MRM domain modeled with an XML or TDS physical format, you can set the MQMD CCSID field of the output message, plus the CCSID of any additional headers. XML and TDS data is handled as strings and is therefore subject to CCSID conversion only.

An example IBM MQ message has an MQMD header, an MQRFH2 header, and a message body. To convert this message to a mainframe CodedCharSetId and Encoding, code the following ESQL in the Compute node:

SET OutputRoot.MQMD.CodedCharSetId = 500; 
SET OutputRoot.MQMD.Encoding = 785; 
SET OutputRoot.MQRFH2.CodedCharSetId = 500; 
SET OutputRoot.MQRFH2.Encoding = 785;

The following example illustrates what you must do to modify a CWF message so that it can be passed from IBM App Connect Enterprise to IMS on z/OS®.

Procedure

  1. You have defined the input message in XML and are using an MQRFH2 header. Remove the header before passing the message to IMS.
  2. The message passed to IMS must have MQIIH header, and must be in the z/OS code page.
    This message is modeled in the MRM and has the name IMS1. Define the PIC X fields in this message as logical type string for conversions between EBCDIC and ASCII to take place. If the fields are binary logical type, no data conversion occurs; binary data is ignored when a CWF message is parsed by the MRM parser.
  3. The message received from IMS is also defined in the MRM and has the name IMS2.
    Define the PIC X fields in this message as logical type string for conversions between EBCDIC and ASCII to take place. If the fields are binary logical type, no data conversion occurs; binary data is ignored when a CWF message is parsed by the MRM parser.
  4. Convert the reply message to the Windows code page.
    The MQIIH header is retained on this message.
  5. You have created a message flow that contains the following nodes:
    :
    1. The outbound flow, MQInput1 --> Compute1 --> MQOutput1.
    2. The inbound flow, MQInput2 --> Compute2 --> MQOutput2.
  6. Code ESQL in Compute1 (outbound) node as follows, specifying the relevant MessageSet ID.
    This code shows the use of the default CWF physical layer name. You must use the name that matches your model definitions. If you specify an incorrect value, the integration node fails with message BIP5431.
    -- Loop to copy message headers
    DECLARE I INTEGER 1;
    DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
    
    WHILE I < J - 1 DO
      SET OutputRoot.*[I] = InputRoot.*[I];
      SET I=I+1;
    END WHILE;
    
    SET OutputRoot.MQMD.CodedCharSetId = 500;
    SET OutputRoot.MQMD.Encoding = 785;
    SET OutputRoot.MQMD.Format = 'MQIMS   ';
    SET OutputRoot.MQIIH.Version = 1;
    SET OutputRoot.MQIIH.StrucLength = 84;
    SET OutputRoot.MQIIH.Encoding = 785;
    SET OutputRoot.MQIIH.CodedCharSetId = 500;
    SET OutputRoot.MQIIH.Format = 'MQIMSVS ';
    SET OutputRoot.MQIIH.Flags = 0;
    SET OutputRoot.MQIIH.LTermOverride = '        ';
    SET OutputRoot.MQIIH.MFSMapName = '        ';
    SET OutputRoot.MQIIH.ReplyToFormat = 'MQIMSVS ';
    SET OutputRoot.MQIIH.Authenticator = '        ';
    SET OutputRoot.MQIIH.TranInstanceId = X'00000000000000000000000000000000';
    SET OutputRoot.MQIIH.TranState = ' ';
    SET OutputRoot.MQIIH.CommitMode = '0';
    SET OutputRoot.MQIIH.SecurityScope = 'C';
    SET OutputRoot.MQIIH.Reserved = ' ';
    SET OutputRoot.MRM.e_elen08 = 30;
    SET OutputRoot.MRM.e_elen09 = 0;
    SET OutputRoot.MRM.e_string08 = InputBody.e_string01;
    SET OutputRoot.MRM.e_binary02 = X'31323334353637383940';
    SET OutputRoot.Properties.MessageSet = 'DHCJOEG072001';
    SET OutputRoot.Properties.MessageType = 'IMS1';
    SET OutputRoot.Properties.MessageFormat = 'Binary1';

    The use of a variable, J, that is initialized to the value of the cardinality of the existing headers in the message, is more efficient than calculating the cardinality on each iteration of the loop, which happens if you code the following WHILE statement:

    WHILE I < CARDINALITY(InputRoot.*[]) DO
    
  7. Create ESQL in Compute2 (inbound) node as follows, specifying the relevant MessageSet ID.
    This code shows the use of the default CWF physical layer name. You must use the name that matches your model definition. If you specify an incorrect value, the integration node fails with message BIP5431.
    -- Loop to copy message headers
    DECLARE I INTEGER 1;
    DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
    
    WHILE I < J DO
      SET OutputRoot.*[I] = InputRoot.*[I];
      SET I=I+1;
    END WHILE;
    
    SET OutputRoot.MQMD.CodedCharSetId = 437;
    SET OutputRoot.MQMD.Encoding = 546;
    SET OutputRoot.MQMD.Format = 'MQIMS   ';
    SET OutputRoot.MQIIH.CodedCharSetId = 437;
    SET OutputRoot.MQIIH.Encoding = 546;
    SET OutputRoot.MQIIH.Format = '        ';
    SET OutputRoot.MRM = InputBody;
    SET OutputRoot.Properties.MessageSet = 'DHCJOEG072001';
    SET OutputRoot.Properties.MessageType = 'IMS2';
    SET OutputRoot.Properties.MessageFormat = 'Binary1';

Results

You do not have to set any specific values for the MQInput1 node properties, because the message and message set are identified in the MQRFH2 header, and no conversion is required.

You must set values for message domain, set, type, and format in the MQInput node for the inbound message flow (MQInput2). You do not need to set conversion parameters.

One specific situation in which you might need to convert data in one code page to another is when messages contain newline characters and are passed between EBCDIC and ASCII systems. The required conversion for this situation is described in Converting EBCDIC NL to ASCII CR LF.