|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Help, one question about MQ Distribution List |
« View previous topic :: View next topic » |
Author |
Message
|
tiangl |
Posted: Thu Feb 03, 2005 12:19 am Post subject: Help, one question about MQ Distribution List |
|
|
Apprentice
Joined: 19 Nov 2004 Posts: 48
|
I'm wondering if MQ distribution list can support multiple queues among multiple Queue manager or MQ distribution list must be used in cluster environment? I used examples in "MQ programming example.pdf" to validate this function and found distribution list only support to distribute messages to multiple queues in one queue manager.
thanks for any response ro comments! |
|
Back to top |
|
 |
mqmhr |
Posted: Thu Feb 03, 2005 12:34 am Post subject: |
|
|
Centurion
Joined: 28 Dec 2004 Posts: 105
|
A distribution list can be used to send messages to queues in more than one queue manager, the queue managers not being in a cluster. Have verified the same using an application. |
|
Back to top |
|
 |
zpat |
Posted: Thu Feb 03, 2005 12:52 am Post subject: |
|
|
 Jedi Council
Joined: 19 May 2001 Posts: 5866 Location: UK
|
Can some of these queues be defined as remote queues? |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Feb 03, 2005 5:58 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
I would think that a distribution list could include the names of any queues that are resolvable according to normal name resolution rules on the queue manager the application is connected to. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
tiangl |
Posted: Thu Feb 03, 2005 11:39 pm Post subject: |
|
|
Apprentice
Joined: 19 Nov 2004 Posts: 48
|
mqmhr wrote: |
A distribution list can be used to send messages to queues in more than one queue manager, the queue managers not being in a cluster. Have verified the same using an application. |
Do i need to define remote queue for this? i mean ,there's local queue named QL.B on QMB, my distribution app connected to QMA, do i have to define remote queue definition of QL.B on QMA?
thanks! |
|
Back to top |
|
 |
mqmhr |
Posted: Fri Feb 04, 2005 12:18 am Post subject: |
|
|
Centurion
Joined: 28 Dec 2004 Posts: 105
|
The application could put message to queues in different queue managers without the need to define remote queue definitions. However, I think that sender/receiver channel pair needs to be created and started. |
|
Back to top |
|
 |
tiangl |
Posted: Fri Feb 04, 2005 1:38 am Post subject: |
|
|
Apprentice
Joined: 19 Nov 2004 Posts: 48
|
mqmhr wrote: |
The application could put message to queues in different queue managers without the need to define remote queue definitions. However, I think that sender/receiver channel pair needs to be created and started. |
i don't know where my problem is. below is my configuration. pls help me to chech if any problem about configuration.
QMA(Queue Manager,Distribution Lists enabled in default)
QL1.A(Local Queue, Distribution Lists enabled. default is disabled)
QL2.A(Local Queue, Distribution Lists enabled)
Trans.Q(Transmission Queue,Distribution lists enabled)
To.QMB(SDR channel)
To.QMa(RCVR channel)
QMB(Queue Manager,Distribution lists enabled in default)
QL1.B(Local Queue, Distribution Lists enabled. default is disabled)
QL2.B(Local Queue, Distribution Lists enabled)
Trans.Q(Transmission Queue,Distribution lists enabled)
To.QMB(RCVR channel)
To.QMA(SDR channel)
Listeners and channels are running, all are fine.
use dist.exe to test distribution lists , result is message only be put into QL1.A and QL2.A,no message is put in QL1.B and QL2.B
distlist.txt
QL1.A
QMA
QL2.A
QMA
QL1.B
QMB
QL2.B
QMB |
|
Back to top |
|
 |
EddieA |
Posted: Fri Feb 04, 2005 9:26 am Post subject: |
|
|
 Jedi
Joined: 28 Jun 2001 Posts: 2453 Location: Los Angeles
|
Quote: |
no message is put in QL1.B and QL2.B |
For each of these queues, did you specify which QM they are on.
Distribution lists use the same queue resolution methods as "regular" MQ. So, if you can put to that Q with an application, it can be put to in a distribution list.
Quote: |
Trans.Q(Transmission Queue,Distribution lists enabled) |
And if you did specify the QM, and this is the actual name of the Trans Q, then MQ cannot resolve where to send the message.
Cheers, _________________ Eddie Atherton
IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Message Broker V7.0 |
|
Back to top |
|
 |
tiangl |
Posted: Fri Feb 04, 2005 8:09 pm Post subject: |
|
|
Apprentice
Joined: 19 Nov 2004 Posts: 48
|
EddieA wrote: |
Quote: |
no message is put in QL1.B and QL2.B |
For each of these queues, did you specify which QM they are on.
Distribution lists use the same queue resolution methods as "regular" MQ. So, if you can put to that Q with an application, it can be put to in a distribution list.
Quote: |
Trans.Q(Transmission Queue,Distribution lists enabled) |
And if you did specify the QM, and this is the actual name of the Trans Q, then MQ cannot resolve where to send the message.
Cheers, |
EddieA, i had a test as you said, defined the name of transmission queue same as remote queue manager. but result was still failed. i checked sdr channel status and found message count is zero, that means QMA which my app connected didn't send anything through channel. also transmission queue was empty. where's problem? let me paste my app code here.
distl.c
/*------------------------------------------------------------------*/
/* */
/* Program Name : Distl.c */
/* */
/* Description : A C program that puts messages to a list of queues*/
/* using MQPUT */
/* */
/* Function: */
/* */
/* Distl is ANSI C program to put messages on a list of message */
/* queues using distribution lists. */
/* */
/* -- messages are sent to the queues specified in the */
/* Distl.txt file. */
/* */
/* -- gets lines from StdIn, and adds each to each target */
/* queue, taking each line of text as the content */
/* of a datagram message; the sample stops when a null */
/* line (or EOF) is read. */
/* New-line characters are removed. */
/* If a line is longer than 99 characters it is broken up */
/* into 99-character pieces. Each piece becomes the */
/* content of a datagram message. */
/* If the length of a line is a multiple of 99 plus 1 */
/* e.g. 199, the last piece will only contain a new-line */
/* character so will terminate the input. */
/* */
/* -- writes a message for each MQI reason other than */
/* MQRC_NONE; stops if there is a MQI completion code */
/* of MQCC_FAILED */
/* */
/* Program logic: */
/* Read the target queues from a text file */
/* MQOPEN target queues for OUTPUT */
/* while end of input file not reached, */
/* . read next line of text */
/* . MQPUT datagram message with text line as data */
/* MQCLOSE target queues */
/* */
/*------------------------------------------------------------------*/
/* -------------------------------------------------------------------------
Include Header Files.
------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cmqc.h> /* includes for MQI */
/* -------------------------------------------------------------------------
Constant value definitions
------------------------------------------------------------------------- */
#define DIST_LIST_LENGTH 10
#define MAX_NAME_LENGTH 40
/* -------------------------------------------------------------------------
Function Prototypes
------------------------------------------------------------------------- */
static int ReadDistList(void);
static void print_usage(void);
static void print_responses( char * comment
, PMQRR pRR
, MQLONG NumQueues
, PMQOR pOR);
/* -------------------------------------------------------------------------
Global variable definitions.
------------------------------------------------------------------------- */
static struct ObjectInfoType{ /* struct to hold the queue and */
char ObjName[MAX_NAME_LENGTH]; /* the queue manager name */
char ObjQMgrName[MAX_NAME_LENGTH];
};
struct ObjectInfoType DistList[DIST_LIST_LENGTH];
/* array to hold the dist. list */
/*------------------------------------------------------------------*/
/* This function is to read the target queue and queue manager */
/* names from the distlist.txt file and place them into the array */
/*------------------------------------------------------------------*/
static int ReadDistList()
{
int i=0;
FILE *dl; /* Distribution List */
if (NULL == (dl = fopen("DistList.txt","r")))
printf("\n Unable to open the data file !!");
else
{
while (!feof(dl)) {
fgets(DistList[i].ObjName,MAX_NAME_LENGTH,dl);
DistList[i].ObjName[strlen(DistList[i].ObjName)-1] = '\0';
fgets(DistList[i].ObjQMgrName,MAX_NAME_LENGTH,dl);
DistList[i].ObjQMgrName[strlen(DistList[i].ObjQMgrName)-1] = '\0';
i += 1;
}
i -= 1;
fclose(dl);
}
return(i);
}
/* -------------------------------------------------------------------------
Main C function
------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
typedef enum {False, True} Bool;
/* Declare file and character for sample input */
FILE *fp;
/* Declare MQI structures needed */
MQOD od = {MQOD_DEFAULT}; /* Object Descriptor */
MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */
MQPMO pmo = {MQPMO_DEFAULT}; /* put message options */
/** note, the program uses defaults where it can **/
MQHCONN Hcon; /* connection handle */
MQHOBJ Hobj; /* object handle */
MQLONG O_options; /* MQOPEN options */
MQLONG C_options; /* MQCLOSE options */
MQLONG CompCode; /* completion code */
MQLONG OpenCode; /* MQOPEN completion code */
MQLONG Reason; /* reason code */
MQLONG buflen; /* buffer length */
char buffer[100]; /* message buffer */
MQLONG Index ; /* Index into list of queues */
MQLONG NumQueues ; /* Number of queues */
PMQRR pRR=NULL; /* Pointer to response records */
PMQOR pOR=NULL; /* Pointer to object records */
Bool DisconnectRequired=False;/* Already connected switch */
Bool Connected=False; /* Connect succeeded switch */
/*----------------------------------------------------------------*/
/* The use of Put Message Records (PMR's) allows some message */
/* attributes to be specified on a per destination basis. These */
/* attributes then override the values in the MD for a particular */
/* destination. */
/* The function provided by this program does not require */
/* the use of PMR's but they are used by the program simply to */
/* demonstrate their use. */
/* The program chooses to provide values for MsgId and CorrelId */
/* on a per destination basis. */
/*----------------------------------------------------------------*/
typedef struct
{
MQBYTE24 MsgId;
MQBYTE24 CorrelId;
} PutMsgRec, *pPutMsgRec;
pPutMsgRec pPMR=NULL; /* Pointer to put msg records */
/*----------------------------------------------------------------*/
/* The PutMsgRecFields in the PMO indicates what fields are in */
/* the array addressed by PutMsgRecPtr in the PMO. */
/* In our example we have provided the MsgId and CorrelId and so */
/* we must set the corresponding MQPMRF_... bits. */
/*----------------------------------------------------------------*/
MQLONG PutMsgRecFields=MQPMRF_MSG_ID | MQPMRF_CORREL_ID;
/* Read the targer queues from the text file. */
/* Number of Queue/QueueMgr name pairs */
NumQueues = ReadDistList();
/*----------------------------------------------------------------*/
/* Allocate response records, object records and put message */
/* records. (new MQSeries structures) */
/*----------------------------------------------------------------*/
pRR = (PMQRR)malloc( NumQueues * sizeof(MQRR));
pOR = (PMQOR)malloc( NumQueues * sizeof(MQOR));
pPMR = (pPutMsgRec)malloc( NumQueues * sizeof(PutMsgRec));
if((NULL == pRR) || (NULL == pOR) || (NULL == pPMR))
{
printf("%s(%d) malloc failed\n", __FILE__, __LINE__);
exit(99);
}
/*----------------------------------------------------------------*/
/* */
/* Copy the queue list into the MQOR structure */
/* */
/*----------------------------------------------------------------*/
for( Index = 0 ; Index < NumQueues ; Index ++)
{
strncpy( (pOR+Index)->ObjectName
, DistList[Index].ObjName
, (size_t)MQ_Q_NAME_LENGTH);
strncpy( (pOR+Index)->ObjectQMgrName
, DistList[Index].ObjQMgrName
, (size_t)MQ_Q_MGR_NAME_LENGTH);
}
/*----------------------------------------------------------------*/
/* Connect to queue manager */
/* */
/* Try to connect to the queue manager associated with the */
/* first queue, if that fails then try each of the other */
/* queue managers in turn. */
/* */
/*----------------------------------------------------------------*/
for( Index = 0 ; Index < NumQueues ; Index ++)
{
MQCONN((pOR+Index)->ObjectQMgrName, /* queue manager */
&Hcon, /* connection handle */
&((pRR+Index)->CompCode),/* completion code */
&((pRR+Index)->Reason)); /* reason code */
if ((pRR+Index)->CompCode == MQCC_FAILED)
{
continue;
}
if ((pRR+Index)->CompCode == MQCC_OK)
{
DisconnectRequired = True ;
}
Connected = True;
break ;
}
/*----------------------------------------------------------------*/
/* Print any non zero responses */
/*----------------------------------------------------------------*/
print_responses("MQCONN", pRR, Index, pOR);
/*----------------------------------------------------------------*/
/* If we failed to connect to any queue manager then exit. */
/*----------------------------------------------------------------*/
if( False == Connected )
{
printf("unable to connect to any queue manager\n");
exit(99) ;
}
/*----------------------------------------------------------------*/
/* */
/* Open the target message queue for output */
/* */
/*----------------------------------------------------------------*/
od.Version = MQOD_VERSION_2 ;
od.RecsPresent = NumQueues ; /* number of object/resp recs */
od.ObjectRecPtr = pOR; /* address of object records */
od.ResponseRecPtr = pRR ; /* Number of object records */
O_options = MQOO_OUTPUT /* open queue for output */
+ MQOO_FAIL_IF_QUIESCING; /* but not if MQM stopping */
MQOPEN(Hcon, /* connection handle */
&od, /* object descriptor for queue */
O_options, /* open options */
&Hobj, /* object handle */
&OpenCode, /* MQOPEN completion code */
&Reason); /* reason code */
/*----------------------------------------------------------------*/
/* report reason(s) if any; stop if failed. */
/* */
/* Note: The reasons in the response records are only valid if */
/* the MQI Reason is MQRC_MULTIPLE_REASONS. If any other */
/* reason is reported then all destinations in the list */
/* completed/failed with the same reason. */
/* If the MQI CompCode is MQCC_FAILED then all of the */
/* destinations in the list failed to open. If some */
/* destinations opened and others failed to open then */
/* the response will be set to MQCC_WARNING. */
/* */
/*----------------------------------------------------------------*/
if (Reason == MQRC_MULTIPLE_REASONS)
{
print_responses("MQOPEN", pRR, NumQueues, pOR);
}
else
{
if (Reason != MQRC_NONE)
{
printf("MQOPEN returned CompCode=%ld, Reason=%ld\n"
, OpenCode
, Reason);
}
}
if (OpenCode == MQCC_FAILED)
{
printf("unable to open any queue for output\n");
}
/*----------------------------------------------------------------*/
/* */
/* Read lines from the file and put them to the message queue */
/* Loop until null line or end of file, or there is a failure */
/* */
/*----------------------------------------------------------------*/
CompCode = OpenCode; /* use MQOPEN result for initial test */
fp = stdin;
pmo.Version = MQPMO_VERSION_2 ;
pmo.RecsPresent = NumQueues ;
pmo.PutMsgRecPtr = pPMR ;
pmo.PutMsgRecFields = PutMsgRecFields ;
pmo.ResponseRecPtr = pRR ;
while (CompCode != MQCC_FAILED)
{
if (fgets(buffer, sizeof(buffer), fp) != NULL)
{
buflen = strlen(buffer); /* length without null */
if (buffer[buflen-1] == '\n') /* last char is a new-line */
{
buffer[buflen-1] = '\0'; /* replace new-line with null */
--buflen; /* reduce buffer length */
}
}
else buflen = 0; /* treat EOF same as null line */
/*--------------------------------------------------------------*/
/* */
/* Put each buffer to the message queue */
/* */
/*--------------------------------------------------------------*/
if (buflen > 0)
{
for( Index = 0 ; Index < NumQueues ; Index ++)
{
memcpy( (pPMR+Index)->MsgId
, MQMI_NONE
, sizeof((pPMR+Index)->MsgId));
memcpy( (pPMR+Index)->CorrelId
, MQCI_NONE
, sizeof((pPMR+Index)->CorrelId));
}
memcpy(md.Format, /* character string format */
MQFMT_STRING, (size_t)MQ_FORMAT_LENGTH);
MQPUT(Hcon, /* connection handle */
Hobj, /* object handle */
&md, /* message descriptor */
&pmo, /* default options (datagram) */
buflen, /* buffer length */
buffer, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
/*----------------------------------------------------------------*/
/* report reason(s) if any; stop if failed. */
/*----------------------------------------------------------------*/
if (Reason == MQRC_MULTIPLE_REASONS)
{
print_responses("MQPUT", pRR, NumQueues, pOR);
}
else
{
if (Reason != MQRC_NONE)
{
printf("MQPUT returned CompCode=%ld, Reason=%ld\n"
, OpenCode
, Reason);
}
}
}
else /* satisfy end condition when empty line is read */
CompCode = MQCC_FAILED;
}
/*----------------------------------------------------------------*/
/* */
/* Close the target queue (if it was opened) */
/* */
/*----------------------------------------------------------------*/
if (OpenCode != MQCC_FAILED)
{
C_options = 0; /* no close options */
MQCLOSE(Hcon, /* connection handle */
&Hobj, /* object handle */
C_options,
&CompCode, /* completion code */
&Reason); /* reason code */
/* report reason, if any */
if (Reason != MQRC_NONE)
{
printf("MQCLOSE ended with reason code %ld\n", Reason);
}
}
/*----------------------------------------------------------------*/
/* */
/* Disconnect from MQM if not already connected */
/* */
/*----------------------------------------------------------------*/
if (DisconnectRequired==True)
{
MQDISC(&Hcon, /* connection handle */
&CompCode, /* completion code */
&Reason); /* reason code */
/* report reason, if any */
if (Reason != MQRC_NONE)
{
printf("MQDISC ended with reason code %ld\n", Reason);
}
}
/*----------------------------------------------------------------*/
/* */
/* END OF PROGRAM */
/* */
/*----------------------------------------------------------------*/
if( NULL != pOR )
{
free( pOR ) ;
}
if( NULL != pRR )
{
free( pRR ) ;
}
if( NULL != pPMR )
{
free( pPMR ) ;
}
return(0);
}
/*------------------------------------------------------------------*/
/* */
/* Function: Print MQI responses from the ResponseRecord array. */
/* */
/* Notes: This function is typically called when a reason of */
/* MQRC_MULTIPLE_REASONS is received. */
/* The reasons relate to the queue at the equivalent */
/* ordinal position in the MQOR array. */
/*------------------------------------------------------------------*/
static void print_responses( char * comment
, PMQRR pRR
, MQLONG NumQueues
, PMQOR pOR)
{
MQLONG Index;
for( Index = 0 ; Index < NumQueues ; Index ++ )
{
if( MQCC_OK != (pRR+Index)->CompCode )
{
printf("%s for %.48s( %.48s) returned CompCode=%ld, Reason=%ld\n"
, comment
, (pOR+Index)->ObjectName
, (pOR+Index)->ObjectQMgrName
, (pRR+Index)->CompCode
, (pRR+Index)->Reason);
}
}
}
distlist.txt
QL1.A
QMA
QL1.B
QMB |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Feb 05, 2005 1:49 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
I believe it's time to hit the books again. Especially the intercommunication manual. It will clarify all those problems that you are facing.
Check as well the naming conventions as advertized in the manual.
The incidence of naming is not trivial.
Enjoy  |
|
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
|
|
|
|