|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Channel Message exit program sample |
« View previous topic :: View next topic » |
Author |
Message
|
fernando2867 |
Posted: Thu Apr 04, 2019 3:38 pm Post subject: Channel Message exit program sample |
|
|
Newbie
Joined: 04 Apr 2019 Posts: 5
|
Hi!!!
I don’t know C programming, and never worked with MQ exits. I’d like to know if anyone has a channel message exit program sample to help me. My objective is:
- RCVR channel receives the message and call exit
- Exit program look at correlation id field of message descriptor
- If correlation id field is not null (has some value), exit does nothing and let channel put msg at destination queue;
- If correlation id field in null, exit changes name of destination queue at MQXQH
Thanks in advance
Best regards from Brazil!!! Fernando |
|
Back to top |
|
 |
RogerLacroix |
Posted: Thu Apr 04, 2019 5:01 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hello Fernando,
If you don't know C nor have you worked with MQ exits then I really don't think you should be messing around with it because you can potentially make your queue manager very unstable.
But if you must, here is sample channel message exit that gives you a starting point.
Code: |
/**
* ChlMsgExit is a sample channel message exit.
*
* Windows:
*
* Location of DLL: C:\temp\ChlMsgExit.dll
*
* DEFINE CHANNEL( 'MQA1.TO.MQB1') +
* CHLTYPE( RCVR ) +
* DESCR('CHANNEL FROM MQA1 TO MQB1') +
* TRPTYPE( TCP ) +
* MSGEXIT('C:\temp\ChlMsgExit(CMX)') +
* MSGDATA(' ') +
* REPLACE
*
* Unix/Linux:
*
* Location of shared module: /var/mqm/exits64/ChlMsgExit
*
* DEFINE CHANNEL( 'MQB1.TO.MQA1') +
* CHLTYPE( RCVR ) +
* DESCR('CHANNEL FROM MQB1 TO MQA1') +
* TRPTYPE( TCP ) +
* MSGEXIT('/var/mqm/exits64/ChlMsgExit(CMX)') +
* MSGDATA(' ') +
* REPLACE
*
* @author Roger Lacroix, Capitalware Inc.
* @version 1.0.0
* @license Apache 2 License
*/
/**
* standard headers
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/timeb.h>
#if defined(UNIX) || defined(WIN32)
#include <malloc.h>
#endif
#if defined(WIN32)
#include <windows.h>
#include <winsock.h>
#include <lm.h>
#elif defined(UNIX)
#include <sys/types.h>
#include <errno.h>
#endif
/* MQ headers */
#include <cmqc.h> /* MQI */
#include <cmqxc.h> /* */
/*
* Prototypes
*/
char * SetTimeStamp( char * );
/* */
#if defined(WIN32)
#define LOG_FILE_NAME "C:\\temp\\ChlMsgExit.log"
#else
#define LOG_FILE_NAME "/var/mqm/exits64/ChlMsgExit.log"
#endif
/*
* dummy function used as entry point to exit,
* only needed for *IX boxes
*/
extern void MQENTRY MQStart(void) {;}
#if defined (WIN32)
__declspec (dllexport) void MQENTRY CMX(PMQCXP pCXP,
PMQCD pCD,
PMQLONG pDataLen,
PMQLONG pAgentBufferLen,
PMQBYTE pAgentBuffer,
PMQLONG pExitBufferLen,
PMQPTR pExitBufferAddr);
#endif
extern void MQENTRY CMX(PMQCXP pCXP,
PMQCD pCD,
PMQLONG pDataLen,
PMQLONG pAgentBufferLen,
PMQBYTE pAgentBuffer,
PMQLONG pExitBufferLen,
PMQPTR pExitBufferAddr)
{
/* --------------------------------------------
* Variable declarations.
* --------------------------------------------
*/
FILE* hLog;
char currentDateTime[100];
/* --------------------------------------------
* Code section
* --------------------------------------------
*/
pCXP->ExitResponse = MQXCC_OK;
hLog = fopen(LOG_FILE_NAME, "a+");
/* switch on ExitReason to see why exit was invoked */
switch(pCXP->ExitReason)
{
case MQXR_INIT: /* Initialization */
{
fprintf(hLog,"%s MQXR_INIT\n", SetTimeStamp(currentDateTime));
/* clear the user area */
memset(pCXP->ExitUserArea, '\0', sizeof(pCXP->ExitUserArea));
break;
}
case MQXR_TERM: /* Termination */
{
fprintf(hLog,"%s MQXR_TERM\n", SetTimeStamp(currentDateTime));
break;
}
case MQXR_MSG: /* QMgr to QMgr */
{
fprintf(hLog,"%s MQXR_MSG\n", SetTimeStamp(currentDateTime));
/**
* Do whatever you want to the message data.
*
*/
break;
}
case MQXR_XMIT:
{ /* SVRCONN Chl */
fprintf(hLog,"%s MQXR_XMIT\n", SetTimeStamp(currentDateTime));
break;
}
/*
* Unsupported exit reason - abort
*/
default:
{
fprintf(hLog,"%s Unknown ExitReason=%d\n", SetTimeStamp(currentDateTime), pCXP->ExitReason);
pCXP->ExitResponse = MQXCC_CLOSE_CHANNEL;
pCXP->ExitResponse2 = MQXR2_USE_AGENT_BUFFER;
break;
}
} /* switch - ExitReason */
fclose(hLog);
return;
} /* CMX */
/**
* ==================================================================
*
* Function Name
* SetTimeStamp
*
* Description
* This function will set the current date/time.
*
* Input parameters
* pBuf - Output buffer
*
* Output
* pBuf - Output buffer
*
* Return Value
* None.
* ------------------------------------------------------------------
*/
char * SetTimeStamp( char *pBuf )
{
/* --------------------------------------------
* Variable declarations.
* --------------------------------------------
*/
struct timeb ftBuf;
#if defined(WIN32) || defined(MVS)
struct tm* pCurrentTime;
#else
struct tm CurrentTime;
struct tm* pCurrentTime = &CurrentTime;
#endif
/* --------------------------------------------
* Code section
* --------------------------------------------
*/
ftime( &ftBuf ); /* Get the current (local) time. */
#if defined(WIN32) || defined(MVS)
pCurrentTime = localtime(&(ftBuf.time));
#else
localtime_r(&(ftBuf.time), pCurrentTime);
#endif
sprintf( pBuf,
"%d/%02d/%02d %02d:%02d:%02d.%0.3hu",
(pCurrentTime->tm_year + 1900),
(pCurrentTime->tm_mon + 1),
pCurrentTime->tm_mday,
pCurrentTime->tm_hour,
pCurrentTime->tm_min,
pCurrentTime->tm_sec,
ftBuf.millitm);
return pBuf;
}
/* End of file */ |
And here is a link to MQ Knowledge Center page on compiling a channel exit:
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.dev.doc/q028160_.htm
Regards,
Roger Lacroix
Capitalware Inc. _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
Vitor |
Posted: Fri Apr 05, 2019 4:47 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
RogerLacroix wrote: |
If you don't know C nor have you worked with MQ exits then I really don't think you should be messing around with it because you can potentially make your queue manager very unstable. |
     
Be aware that the C exits run in-line with the queue manager process as if they had been supplied by IBM; there's no error checking, no sandboxing, no defences. As my worthy associate points out, a poorly written exit will make your queue manager unstable, a badly written exit will bring it down in flames and a well written but inefficient exit (such as the first piece of C you've written) will significantly impact queue manager performance. Never mind what's going to happen if you corrupt the MQXQH header.
Consider very carefully what you're doing. If all you're trying to do is route messages based on existence or not of a correlation id, is an exit the best way? What's the actual requirement?
And if the actual requirement is "my manager told me to write an MQ exit to do this", that's not a requirement. It's a practicle joke. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
gbaddeley |
Posted: Sun Apr 07, 2019 3:30 pm Post subject: Re: Channel Message exit program sample |
|
|
 Jedi Knight
Joined: 25 Mar 2003 Posts: 2538 Location: Melbourne, Australia
|
fernando2867 wrote: |
Hi!!!
- If correlation id field is not null (has some value), exit does nothing and let channel put msg at destination queue;
- If correlation id field in null, exit changes name of destination queue at MQXQH |
It would make more sense to change the source application to use the correct queue names, or change the destination consumer app to do this. You are suggesting that app message routing and decision logic is to be done inside in MQ, rather than in the apps (where it belongs).
Push back hard on this requirement. Very hard. _________________ Glenn |
|
Back to top |
|
 |
fernando2867 |
Posted: Tue Apr 09, 2019 4:16 pm Post subject: |
|
|
Newbie
Joined: 04 Apr 2019 Posts: 5
|
Hi guys!!! Thanks for the answers!! I am trying to make customer change his application, instead of write an exit.
Roger, thanks for the sample.
Kind regards!!! Fernando |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|