Using Caché Internet Utilities
Sending and Receiving IBM WebSphere MQ Messages
[Home] [Back] [Next]
InterSystems: The power behind what matters   
Class Reference   
Search:    

Caché provides an interface to IBM WebSphere MQ, which you can use to exchange messages between Caché and the message queues of IBM WebSphere MQ. To use this interface, you must have access to an IBM WebSphere MQ server, and the IBM WebSphere MQ client must be running on the same machine as Caché.

The interface consists of the %Net.MQSend and %Net.MQRecv classes, which are both subclasses of %Net.abstractMQ. These classes use a dynamic-link library that is automatically installed by Caché on all suitable platforms. (This is MQInterface.dll on Windows; the file extension is different for other platforms.) In turn, the Caché dynamic-link library requires IBM WebSphere MQ dynamic-link libraries.
The interface supports sending and receiving only text data, not binary data. If you do not have long strings enabled, you can send and receive long messages by using file streams.
This chapter discusses the following topics:
To use IBM WebSphere MQ, you will need the formal documentation for this product. Also, for additional information on the Caché interface to IBM WebSphere MQ, see the class reference for %Net.abstractMQ.
Using the Caché Interface to IBM WebSphere MQ
In general, to use the Caché interface to IBM WebSphere MQ, you do the following:
  1. Make sure that you have access to IBM WebSphere MQ v7.x or higher. Specifically:
  2. Create a new instance of %Net.MQSend or %Net.MQRecv, depending on whether you are going to send or receive messages.
  3. Connect to an IBM WebSphere MQ server. When you do so, you provide the following information:
    You can also provide a name and password if you are using the authentication feature of IBM WebSphere MQ.
  4. Invoke the appropriate methods of %Net.MQSend or %Net.MQRecv to send or receive messages.
Note:
To use IBM Websphere MQ on 64–bit Linux platforms, you must set the LD_LIBRARY_PATH to include the location of the MQ libraries. Because the path must be set for any Caché process that uses the MQ interface, it must be set prior to starting Caché if running background processes, and set in any UNIX® terminal prior to running csession.
Getting Error Codes
The methods of %Net.MQSend and %Net.MQRecv return either 1 if successful or 0 if unsuccessful. In the case of an error, call the %GetLastError() method, which returns the last reason code given by IBM WebSphere MQ. For information on the reason codes, see the formal IBM documentation.
Creating a Connection Object
Before you can send or receive messages via IBM WebSphere MQ, you must create a connection object, a Caché term for an object that establishes a connection to a queue manager, opens a channel, and opens a queue for use. There are two ways you can do this:
Using the %Init() Method
To use the %Init() method to create a connection object:
  1. Create an instance of %Net.MQSend (if you are going to send messages) or %Net.MQRecv (if you are going to receive messages). This chapter refers to this instance as the connection object.
    Note:
    If you receive the <DYNAMIC LIBRARY LOAD> error, a dynamic-link library is missing, and the cconsole.log file (in the system manager’s directory) has more details.
  2. If authentication is required, set the following properties of the connection object:
  3. Call the %Init() method of the connection object. This method takes the following arguments, in order.
    1. (Required) A string that specifies the queue name; this should be a valid queue for the specified queue manager.
    2. A string that specifies the queue manager; this should be a valid queue manager on the IBM WebSphere MQ server.
      If you omit this argument, the system uses the default queue manager, as configured in IBM WebSphere MQ. Or, if IBM WebSphere MQ has been the configured so that the queue manager is determined by the queue name, the system uses the queue manager that is appropriate for the given queue name.
    3. A string that specifies the specification for the channel, in the following form:
      "channel_name/transport/host_name(port)"
      Here channel_name is the name of the channel to use, transport is the transport used by the channel, host_name is the server name (or IP address) that is running the IBM WebSphere MQ server, and port is the port that this channel should use.
      Transport can be one of the following: TCP, LU62, NETBIOS, SPX
      For example:
      "CHAN_1/TCP/rodan(1401)"
      "CHAN_1/TCP/127.0.0.1(1401)"
      If you omit this argument, the system uses the default channel specification, as configured in IBM WebSphere MQ. Or, if the system has been the configured so that the channel is determined by the queue name, the system uses the channel that is appropriate for the given queue name.
    4. An optional string that specifies the log file to write error messages to. The default is that no logging occurs.
  4. Check the value returned by the %Init() method. If the method returns 1, the connection was established successfully, and you can use the connection object to either send or receive messages (depending on the class you are using). See Getting Error Codes.”
Using the %Connect() Method
In some cases, you might prefer to specify all the details of the connection individually. To do so, you use the %Connect() method, as follows:
  1. Create an instance of %Net.MQSend (if you are going to send messages) or %Net.MQRecv (if you are going to receive messages). As noted previously, this chapter refers to this instance as the connection object.
    Note:
    If you receive the <DYNAMIC LIBRARY LOAD> error, a dynamic-link library is missing, and the cconsole.log file (in the system manager’s directory) has more details.
  2. Set the following properties of the connection object:
  3. Optionally specify the channel to use by setting the following properties of the connection object:
    If you omit these arguments, the system uses the default channel specification, as configured in IBM WebSphere MQ. Or, if the system has been the configured so that the channel is determined by the queue name, the system uses the channel that is appropriate for the given queue name.
  4. If authentication is required for the channel, set the following properties of the connection object:
  5. Call the %ErrLog() method of the connection object. This method takes one argument, the name of the log file to use for this connection object.
  6. Check the value returned by the %ErrLog() method. See Getting Error Codes.”
  7. Call the %Connect() method of the connection object.
  8. Check the value returned by the %Connect() method. If the method returns 1, the connection was established successfully, and you can use the connection object to either send or receive messages (depending on the class you are using). See Getting Error Codes.”
Specifying the Character Set (CCSID)
To set the character set used for message conversions, call the %SetCharSet() method of your connection object. Specify an integer Coded Character Set ID (CCSID) as used in IBM WebSphere MQ.
To get the CCSID that is currently being used, call the %CharSet() method. This method returns the CCSID by reference and it returns 1 or 0 to indicate whether it was successful; see Getting Error Codes.”
For information on the CCSID that corresponds to a given character set, see the formal IBM documentation.
Specifying Other Message Options
To specify message descriptor options, optionally set the following properties of your connection object:
Sending Messages
To send messages, do the following:
  1. Create a connection object as described in “Creating a Connection Object.” In this case, create an instance of %Net.MQSend. The connection object has a message queue to which you can send messages.
  2. Call the following methods, as needed:
  3. Check the value returned by the method you called. See Getting Error Codes.”
  4. When you are done retrieving messages, call the %Close() method of the connection object to release the handle to the dynamic-link library.
Example 1: SendString()
The following class method sends a simple string message to the queue cachetest, using queue manager QM_antigua, and a queue channel named S_antigua. The channel uses TCP transport, and the IBM WebSphere MQ server is running on a machine called antigua and is listening on port 1401.
///Method returns reason code from IBM WebSphere MQ
ClassMethod SendString() As %Integer
{
 Set send=##class(%Net.MQSend).%New()
 Set queue="cachetest"
 Set qm="QM_antigua"
 Set chan="S_antigua/TCP/antigua(1414)"
 Set logfile="c:\mq-send-log.txt"

 Set check=send.%Init(queue,qm,chan,logfile)
 If 'check  Quit send.%GetLastError()
 
 //send a unique message
 Set check=send.%Put("This is a test message "_$h)

 If 'check  Quit send.%GetLastError()
 Quit check
}
Example 2: SendCharacterStream()
The following class method sends the contents of a file character stream. It uses the same queue used in the previous example:
///Method returns reason code from IBM WebSphere MQ
ClassMethod SendCharacterStream() As %Integer
{
 Set send=##class(%Net.MQSend).%New()
 Set queue="cachetest"
 Set qm="QM_antigua"
 Set chan="S_antigua/TCP/antigua(1414)"
 Set logfile="c:\mq-send-log.txt"

 Set check=send.%Init(queue,qm,chan,logfile)
 If 'check  Quit send.%GetLastError()
 
 //initialize the stream and tell it what file to use
 Set longmsg=##class(%FileCharacterStream).%New()
 Set longmsg.Filename="c:\input-sample.txt"
 
 Set check=send.%PutStream(longmsg)

 If 'check  Quit send.%GetLastError()
 Quit check
}
Example 3: Sending a Message from the Terminal
The following example shows a Terminal session that sends a message to an IBM WebSphere MQ queue. This works only on a machine that has been configured with the IBM WebSphere MQ client.
Set MySendQ = ##class(%Net.MQSend).%New()

Do MySendQ.%Init("Q_1", "QM_1","QC_1/TCP/127.0.0.1(1401)","C:\mq.log")

Do MySendQ.%Put("Hello from tester")

Set MyRecvQ =##class(%Net.MQRecv).%New()

Do MyRecvQ.%Init("Q_1", "QM_1","QC_1","C:\mq.log")

Do MyRecvQ.%Get(.msg, 10000)

Write msg,!
Also see the preceding sections for other examples.
Retrieving Messages
To retrieve messages, do the following:
  1. Create a connection object as described in “Creating a Connection Object.” In this case, create an instance of %Net.MQRecv. The connection object has a message queue from which you can retrieve messages.
  2. Call the following methods, as needed:
    For both methods, the second argument is the timeout, in milliseconds; this controls the time used to contact the server. The default timeout is 0.
  3. Check the value returned by the method you called. See Getting Error Codes.” Remember that IBM WebSphere MQ returns 2033 when the queue is empty.
  4. When you are done retrieving messages, call the %Close() method of the connection object to release the handle to the dynamic-link library.
Example 1: ReceiveString()
The following class method retrieves a message from the cachetest queue.
/// This is useful only if you enable long strings or you are
/// sure that you will receive strings < 32k in length.
///Method returns string or null or error message
ClassMethod ReceiveString() As %String
{
 Set recv=##class(%Net.MQRecv).%New()
 Set queue="cachetest"
 Set qm="QM_antigua"
 Set chan="S_antigua/TCP/antigua(1414)"
 Set logfile="c:\mq-recv-log.txt"
 
 Set check=recv.%Init(queue,qm,chan,logfile)
 If 'check  Quit recv.%GetLastError()

 Set check=recv.%Get(.msg)
 If 'check {
     Set reasoncode=recv.%GetLastError()
     If reasoncode=2033 Quit ""
     Quit "ERROR: "_reasoncode
     }
 
 Quit msg
}
Example 2: ReceiveCharacterStream()
The following method can retrieve a longer message because it uses %GetStream():
/// Method returns reason code from IBM WebSphere MQ
ClassMethod ReceiveCharacterStream() As %Integer
{
 Set recv=##class(%Net.MQRecv).%New()
 Set queue="cachetest"
 Set qm="QM_antigua"
 Set chan="S_antigua/TCP/antigua(1414)"
 Set logfile="c:\mq-recv-log.txt"

 Set check=recv.%Init(queue,qm,chan,logfile)
 If 'check  Quit recv.%GetLastError()
 
 //initialize the stream and tell it what file to use
 //make sure filename is unique we can tell what we received
 Set longmsg=##class(%FileCharacterStream).%New()
 Set longmsg.Filename="c:\mq-received"_$h_".txt"

 Set check=recv.%GetStream(longmsg)

 If 'check  Quit recv.%GetLastError()
 Quit check
}
Updating Message Information
The %Net.MQSend and %Net.MQRecv classes also provide the following methods:
%CorId()
Updates (by reference) the Correlation Id for the last message read.
%ReplyQMgrName()
Updates (by reference) the reply queue manager name for the last message read.
%ReplyQName()
Updates (by reference) the reply queue name for the last message read.
Troubleshooting
If you encounter problems when using the Caché interface to IBM WebSphere MQ, you should first determine whether the client is correctly installed and can communicate with the server. To perform such a test, you can use sample programs that are provided by IBM WebSphere MQ. The executables are in the bin directory of the IBM WebSphere MQ client.
The following steps describe how to use these sample programs on Windows. The details may be different on other operating systems; consult the IBM documentation and check the names of the files present in your client.
  1. Create an environment variable called MQSERVER. Its value should be of the form channel_name/transport/server, where channel_name is the name of the channel to use, transport is a string that indicates the transport to use, and server is the name of the server. For example: S_antigua/TCP/antigua
  2. At the command line, enter the following command:
    amqsputc queue_name queue_manager_name
    where queue_name is the name of the queue to use and queue_manager_name is the name of the queue manager. For example:
    amqsputc cachetest QM_antigua
    If the amqsputc command is unrecognized, make sure that the PATH environment variable has been updated to include the bin directory of the IBM WebSphere MQ client.
    In case of other errors, consult the IBM documentation.
  3. You should see a couple of lines like the following:
    Sample AMQSPUT0 start
    target queue is cachetest
  4. Now you can send messages. Simply type each message and press Enter after each message. For example:
    sample message 1
    sample message 2
  5. When you are done sending messages, press Enter twice. You will then see a line like the following:
    Sample AMQSPUT0 end
  6. To complete this test, we will retrieve the messages you sent to the queue. Type the following command at the command line:
    amqsgetc queue_name queue_manager_name
    where queue_name is the name of the queue to use and queue_manager_name is the name of the queue manager. For example:
  7. You should then see a start line, followed by the messages that you sent previously, as follows:
    Sample AMQSGET0 start
    message <sample message 1>
    message <sample message 2>
  8. This sample program waits briefly to receive any other messages and then displays the following:
    no more messages
    Sample AMQSGET0 end
    
If the test fails, consult the IBM documentation. Possible causes of problems include the following: