Configure Your Programs for Message Queue Polling

Environment Variables for the Polling Server

Environment Variables That Are Set Automatically

When a polling server session is started, the object spawner automatically creates the following environment variables for the session:
SASQSID
specifies the unique identifier for the object spawner.
SASQUEUE
specifies the name of the queue for the polling server.
SASQMGR
specifies the name of the queue manager that the polling server uses to access the queue.

Specifying Environment Variables on the SAS Command

For WebSphere MQ, you can also set environment variables on the server by using the –SET option on the SAS command for the server session. For example, you might want to specify the queue model by using the MQMODEL variable. The following SAS command sets the queue model to client and sets the MQSERVER variable to enable remote access:
sas -sysin "myfile.sas" -set MQMODEL client
    -set MQSERVER "CHANNEL1/TCP/192.168.0.10(1414)"

Retrieving Environment Variable Values

You can retrieve the values of the environment variables by using the SYSGET( ) function. For example, the following code retrieves the SASQMGR value and stores it in the QMGR variable:
qmgr= sysget('SASQUEUE');
You can also use the %SYSGET macro function. Here is an example:
%let qmgr=%sysget(SASQUEUE);
On z/OS, if you use a UNIX shell script to invoke SAS, then you must use the -SET invocation option to retrieve the environment variables within the script and pass them to the SAS session. For example:
-set \"SASQSID ${SASQSID}\" -set \"SASQMGR ${SASQMGR}\"

Checking for Stop Messages

Overview of Checking for Stop Messages

The message queue polling server uses SAS sessions to perform processing. These sessions are managed by the object spawner. When the object spawner is stopped, it puts high-priority stop messages on the message queue for each server session that it started. Each stop message contains a unique identifier string that identifies the spawner. The DATA step program must check for this, perform cleanup, and close immediately upon receiving the stop message.
The SASQSID value is passed to the polling server by the object spawner as an environment variable. For more information, see Environment Variables for the Polling Server .

Checking for Stop Messages with the JMS Access Method

To check for stop messages when you use the JMS file access method:
  1. Get the value of the SASQSID variable by using the following code:
    %let sid_var= %sysget(SASQSID);
  2. In the FILENAME or INFILE statement that uses the JMS access method, specify the &SID_VAR macro variable as the value for EOFCHECK=.
    eofcheck="&SID_VAR"

Checking for Stop Messages with WebSphere MQ

If you set the SASQSID value in the get message options (on the MQGMO CALL routine), then the MQGET call will check for a stop message. If the message is found, and the SASQSID value matches the identifier in the message, then MQGET returns a completion code of 2 and a reason code of -2.
For queues that are monitored by the message queue polling server, the MsgDeliverySequence property must be set to Priority.
The following code fragment shows an MQGET call that checks for a stop message:
call mqget(hconn, hobj, hmd, hgmo, msglen,
cc, reason);
   if cc ^= 0 then do;
      if reason = 2033 then do;
         put 'No message available';
      end;
      else do;
         if reason = -2 then do;
            put "MQGET: received stop message from object spawner";
            goto exit;
         end;
         else put 'MQGET: failed with reason= ' reason;
      end;
   end;
   else put 'MQGET: message received: ';

Message Queue Polling Example for WebSphere MQ

The following code is a sample application that you can run with message queue polling.
data _null_;
length hconn hobj cc reason 8;
length rc hod hgmo hmd hmap msglen 8;
length parms $ 200 options $ 200 action $ 3 msg $ 200;
length desc $ 50;

msglen=0;
hconn=0;
hobj=0;
hod=0;
hgmo=0;
hmd=0;
hmap=0;

/* Get the variables set by the object spawner for this session */
sid =  sysget('SASQSID');
qmgr= sysget('SASQMGR');
qname= sysget('SASQUEUE');

put "Spawner job started.";
put "sid = " sid;
put "qmgr = " qmgr;
put "qname = " qname;

call mqconn(qmgr, hconn, cc, reason);

action = "GEN";
parms="OBJECTNAME";
objname=qname;
call mqod(hod, action, rc, parms, objname);
if rc ^= 0 then do;
   put 'MQOD: failed with rc= ' rc;
   msg = sysmsg();
   put msg;
   goto exit;
end;

options="INPUT_SHARED";
call mqopen(hconn, hod, options, hobj, cc, reason);
if cc ^= 0 then do;
   put 'MQOPEN: failed with reason= ' reason;
   goto exit;
end;

parms= "SASQSID";
call mqgmo(hgmo, action, rc, parms, sid);
if rc ^= 0 then do;
   put 'MQGMO: failed with rc= ' rc;
   msg = sysmsg();
   put msg;
   goto exit;
end;

desc="CHAR,,100";
call mqmap(hmap, rc, desc);
if rc ^= 0 then do;
   put 'MQMAP: failed with rc= ' rc;
   msg = sysmsg();
   put msg;
   goto exit;
end;

reason = 0;
do until (reason = 2033);

   action = "GEN";
   call mqmd(hmd, action, rc);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
   end;

   call mqget(hconn, hobj, hmd, hgmo, msglen, cc, reason);
   if cc ^= 0 then do;
      if reason = 2033 then do;
         put 'No message available';
      end;
      else do;
         if reason = -2 then do;
            /* -2 indicates that a session-specific stop message has */
            /* been received from the object spawner queue monitor   */
            /* application.  We should clean up and shutdown         */
            /* immediately.                                          */
            put "MQGET: received stop message from object spawner";
            goto exit;
         end;
         else put 'MQGET: failed with reason= ' reason;
      end;
   end;
   else put 'MQGET: message received: ';
/* Do any application-specific processing of messages here. */

if hmd ^= 0 then do;
   call mqfree(hmd);
end;

end; /* end do loop */

exit:
if hobj ^= 0 then do;
   options="NONE";
   call mqclose(hconn, hobj, options, cc, reason);
   if cc ^= 0 then do;
      put 'MQCLOSE: failed with reason= ' reason;
   end;
end;

if hconn ^= 0 then do;
   call mqdisc(hconn, cc, reason);
   if cc ^= 0 then do;
      put 'MQDISC: failed with reason= ' reason;
   end;
end;

if hod ^= 0 then do;
   call mqfree(hod);
end;
if hgmo ^= 0 then do;
   call mqfree(hgmo);
end;
if hmd ^= 0 then do;
   call mqfree(hmd);
end;
if hmap ^= 0 then do;
   call mqfree(hmap);
end;

run;