/***************************************************************************/ /* */ /* (c) Copyright IBM Corp. 2002 All rights reserved. */ /* */ /* This sample program is owned by International Business Machines */ /* Corporation or one of its subsidiaries ("IBM") and is copyrighted */ /* and licensed, not sold. */ /* */ /* You may copy, modify, and distribute this sample program in any */ /* form without payment to IBM, for any purpose including developing, */ /* using, marketing or distributing programs that include or are */ /* derivative works of the sample program. */ /* */ /* The sample program is provided to you on an "AS IS" basis, without */ /* warranty of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, */ /* EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* Some jurisdictions do not allow for the exclusion or limitation of */ /* implied warranties, so the above limitations or exclusions may not */ /* apply to you. IBM shall not be liable for any damages you suffer as */ /* a result of using, modifying or distributing the sample program or */ /* its derivatives. */ /* */ /***************************************************************************/ /* */ /* Program name: mqreqro */ /* */ /* Description: Sample C++ program that shows how a requester */ /* application can instruct the server application on how it */ /* would like the message id and correlation id handled in */ /* the reply. */ /* */ /* This program should be used in conjunction with the */ /* mqsrvro sample program. */ /* */ /* The best way to use the mqreqro and mqsrvro samples is to */ /* start them in separate MS-DOS Prompt windows. They need */ /* to run against the same queue and queue manager. Mqreqro */ /* asks the user if it wants a reply with the message id */ /* copied to the correlatation id. If not the same */ /* correlation is passed on the reply. It also asks if the */ /* user wants a new message id generated. If not the same */ /* message id is passed back with the reply. */ /* When a blank line is entered in the mqreqro window, the */ /* program will end. It also sends an application specific */ /* message to mqsrvro to notify it to terminate. */ /* */ /* */ /* Build: */ /* This program has been tested with Microsoft Visual C++ 6.0 */ /* and MQSeries V5.2 and Websphere MQ 5.3 on Windows/2000. */ /* Compile it with: */ /* */ /* cl -MT mqreqro.cpp imqb23vn.lib imqs23vn.lib */ /* */ /* Note: Use imqc23vn.lib instead of imqs23vn.lib for a client */ /* connection. */ /* */ /* */ /* Execution: */ /* mqreqro queuename */ /* */ /* where queuename is a required queue name */ /* and queuemgrname is an optional queue manager name */ /* */ /***************************************************************************/ #include #include #include #include #include const int MAX_BUFF_SIZE = 100; const char * MODELQUEUE = "SYSTEM.MQSC.REPLY.QUEUE"; const char * QTEMPLATE = "MQREQRO*"; const char * TERMINATE = "TERMINATE"; int main(int argc, char **argv) { ImqQueueManager qmgr; ImqQueue qServer; ImqQueue qReply; ImqMessage msg; ImqMessage msgReply; ImqGetMessageOptions gmo; ImqPutMessageOptions pmo; ImqBoolean passCorrelID = FALSE; ImqBoolean newMsgID = FALSE; ImqBoolean pendingReq = FALSE; MQBYTE24 MsgId; MQBYTE24 CorrelId; MQLONG qCC; MQLONG reportOpts; char buffer[MAX_BUFF_SIZE]; cout << "Program " << argv[0] << " started." << endl; if (argc < 2) { cerr << "Required parameter missing - queue name" << endl; exit(99); } /***************************************************************/ /* Connect to queue manager */ /***************************************************************/ if ( argc > 2 ) { qmgr.setName(argv[2]); } if ( !qmgr.connect() ) { cerr << "ImqQueueManager::connect failed with reason code " << qmgr.reasonCode( ) << endl; exit(99); } /*************************************************************/ /* Get and open the server queue. */ /*************************************************************/ qServer.setConnectionReference(qmgr); qServer.setName(argv[1]); qServer.setOpenOptions(MQOO_OUTPUT + MQOO_INQUIRE + MQOO_FAIL_IF_QUIESCING); qServer.open(); /***************************************************************/ /* If there was an error opening the queue, print it out. */ /***************************************************************/ if ( qServer.reasonCode() ) { cerr << "ImqQueue::open ended with reason code " << qServer.reasonCode( ) << endl; } if ( qServer.completionCode() ) { cout << "Unable to open queue for output" << endl; } /*************************************************************/ /* Open a dynamic queue for the replies that will come back. */ /*************************************************************/ qReply.setConnectionReference(qmgr); qReply.setName(MODELQUEUE); qReply.setDynamicQueueName(QTEMPLATE); qReply.setOpenOptions(MQOO_INPUT_EXCLUSIVE + MQOO_INQUIRE + MQOO_FAIL_IF_QUIESCING); qReply.open(); /***************************************************************/ /* If there was an error opening the queue, print it out. */ /***************************************************************/ if ( qReply.reasonCode() ) { cerr << "ImqQueue::open ended with reason code " << qReply.reasonCode( ) << endl; } if ( qReply.completionCode() ) { cerr << "Unable to open queue for output" << endl; } /****************************************************/ /* Indicate that this is a request that expects to */ /* get a reply back. */ /****************************************************/ msg.setMessageType(MQMT_REQUEST); msg.setReplyToQueueName(qReply.name()); /****************************************************/ /* Indicate that Message ID and Correlation ID are */ /* to be generated. */ /****************************************************/ pmo.setOptions(MQPMO_NEW_MSG_ID | MQPMO_NEW_CORREL_ID); /*****************************************************/ /* Ask the user how to set the report options. */ /*****************************************************/ qCC = qServer.completionCode( ); while ( qCC != MQCC_FAILED ) { /*****************************************************/ /* Indicate reply desired on bad message. */ /*****************************************************/ reportOpts = MQRO_EXCEPTION_WITH_DATA; passCorrelID = FALSE; newMsgID = TRUE; pendingReq = TRUE; cout << endl; cout << " Would you like the message id copied to the correl id on the reply (y/n)?" << endl; cout << " Enter to exit "; cin.getline(buffer, MAX_BUFF_SIZE); if ( strlen(buffer) > 0 ) { if ( toupper(*buffer) == 'N' ) { passCorrelID = TRUE; reportOpts |= MQRO_PASS_CORREL_ID; } else { reportOpts |= MQRO_COPY_MSG_ID_TO_CORREL_ID; } cout << endl; cout << " Would you like a new message id generated on the reply (y/n)? "; cin.getline(buffer, MAX_BUFF_SIZE); if ( toupper(*buffer) == 'N' ) { newMsgID = FALSE; reportOpts |= MQRO_PASS_MSG_ID; } else { reportOpts |= MQRO_NEW_MSG_ID; } sprintf( buffer, "%s request message", argv[0]); cout << endl; cout << " Sending message with request to "; if ( passCorrelID == TRUE ) { cout << "reply with the same correlation id and "; } else { cout << "reply with the message id copied to the correlation id and "; } if ( newMsgID == TRUE ) { cout << "a new message id." << endl; } else { cout << "the same message id." << endl; } /*************************************************/ /* Set up the message buffer, format, and length */ /* Use of FullBuffer indicates the buffer is */ /* already populated. */ /*************************************************/ msg.useFullBuffer(buffer, strlen(buffer)); msg.setMessageId(); msg.setCorrelationId(); msg.setFormat(MQFMT_STRING); msg.setReport(reportOpts); /*************************************************/ /* Put the message on the server queue and print */ /* out any errors that were encountered. */ /*************************************************/ if ( !qServer.put(msg, pmo) ) { cerr << "ImqQueue::put ended with reason code " << qServer.reasonCode( ) << endl; } else { /************************************************/ /* Print out the message id that is sent to the */ /* request queue. */ /************************************************/ msg.messageId().copyOut(MsgId, MQ_MSG_ID_LENGTH, 0); cout << endl; cout << " Message ID from put: "; cout.setf(ios::hex); for (int i=0; i < MQ_MSG_ID_LENGTH; i++) { cout << (int)MsgId[i]; } cout << endl; cout.unsetf(ios::hex); /************************************************/ /* Print out the correlation id that is sent */ /* to the request queue. */ /************************************************/ msg.correlationId().copyOut(CorrelId, MQ_CORREL_ID_LENGTH, 0); cout << " Correlation ID from put: "; cout.setf(ios::hex); for (i=0; i < MQ_MSG_ID_LENGTH; i++) { cout << (int)CorrelId[i]; } cout << endl; cout.unsetf(ios::hex); /************************************************************/ /* Get the reply back from the server */ /************************************************************/ gmo.setOptions(MQGMO_WAIT | /* wait for new messages */ MQGMO_FAIL_IF_QUIESCING ); gmo.setWaitInterval(5000); /* 5 second limit for waiting */ while ( qCC != MQCC_FAILED ) { msgReply.useEmptyBuffer(buffer, sizeof(buffer)); /**************************************************************/ /* If a new message id is requested, set the reply message */ /* to null to get next available message. If request was to */ /* pass the message id, we know what it is on the reply so */ /* only look for this specific message id on the queue */ /**************************************************************/ if ( newMsgID ) { msgReply.setMessageId( ); } else { msgReply.setMessageId( msg.messageId( ) ); } /**************************************************************/ /* If pass correlid is requested, then look for the same */ /* correlid in the reply otherwise, the server will copy the */ /* messageid to the correlid field and we will look only */ /* only for this specific correlid. */ /**************************************************************/ if ( passCorrelID ) { msgReply.setCorrelationId( msg.correlationId( ) ); } else { msgReply.setCorrelationId( msg.messageId( ) ); } /*********************************************************/ /* Get the message. Print out the message or any errors */ /* that were received. */ /*********************************************************/ if ( qReply.get(msgReply, gmo) ) { pendingReq = FALSE; cout << endl; /************************************************/ /* Print out the message id that is received */ /* on the reply. */ /************************************************/ msgReply.messageId().copyOut(MsgId, MQ_MSG_ID_LENGTH, 0); cout << " Message ID from get: "; cout.setf(ios::hex); for (int i=0; i < MQ_MSG_ID_LENGTH; i++) { cout << (int)MsgId[i]; } cout << endl; cout.unsetf(ios::hex); /************************************************/ /* Print out the correlation id that is */ /* received on the reply. */ /************************************************/ msgReply.correlationId().copyOut(CorrelId, MQ_CORREL_ID_LENGTH, 0); cout << " Correlation ID from get: "; cout.setf(ios::hex); for (i=0; i < MQ_MSG_ID_LENGTH; i++) { cout << (int)CorrelId[i]; } cout << endl; cout.unsetf(ios::hex); } else { /* report reason, if any */ if ( qReply.reasonCode() == MQRC_NO_MSG_AVAILABLE ) { if ( pendingReq ) { cerr << endl << " ERROR: Either the server did not reply or it replied with a message id" << endl << " or correlation id that did not match our request criteria." << endl; } break; } else { cerr << "ImqQueue::get ended with reason code" << (long)qReply.reasonCode() << endl; } qCC = qReply.completionCode(); } } } qCC = qServer.completionCode(); } else { // send an application specific message to mqsrvro to // signal end of processing strcpy(buffer, TERMINATE); msg.useEmptyBuffer(buffer, sizeof(buffer)); msg.setMessageType(MQMT_APPL_FIRST); msg.setMessageId(); msg.setCorrelationId(); msg.setFormat(MQFMT_STRING); msg.setMessageLength(strlen(buffer)); /*************************************************/ /* Put the message on the server queue and print */ /* out any errors that were encountered. */ /*************************************************/ if ( !qServer.put(msg, pmo) ) { cerr << "ImqQueue::put ended with reason code " << qServer.reasonCode( ) << endl; } qCC = MQCC_FAILED; // break out of while loop } } /****************************************************************/ /* Close the Server queue (if it was opened) */ /****************************************************************/ if ( !qServer.close() ) { cerr << "ImqQueue::server close ended with reason code " << qServer.reasonCode() << endl; } /****************************************************************/ /* Close the Reply queue (if it was opened) */ /****************************************************************/ if ( !qReply.close() ) { cerr << "ImqQueue::reply close ended with reason code " << qReply.reasonCode() << endl; } /****************************************************************/ /* Disconnect from MQM if not already connected */ /****************************************************************/ if ( !qmgr.disconnect() ) { cerr << "ImqQueueManager::disconnect ended with reason code " << qmgr.reasonCode() << endl; } /******************************************************************/ /* End of mqreqro */ /******************************************************************/ return(0); }