|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
MQRC 3014 on MQCMD_SET_AUTH_REC |
« View previous topic :: View next topic » |
Author |
Message
|
vignesh1988 |
Posted: Fri Apr 11, 2014 4:58 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
No i dont know whey they need.. No logical reason i can give from my side..
But changing the order PROFILE followed by OBJECT type recovered the 3014 error. That i can say.. |
|
Back to top |
|
 |
mqjeff |
Posted: Fri Apr 11, 2014 5:51 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
vignesh1988 wrote: |
No i dont know whey they need.. No logical reason i can give from my side..
But changing the order PROFILE followed by OBJECT type recovered the 3014 error. That i can say.. |
PCF messages can be a bit order-dependent, since MQSC can be a bit order-dependent. That's one of the reasons the Java classes are nice - it handles the serialization order for you.
The perl modules are pretty good at this, too. |
|
Back to top |
|
 |
vignesh1988 |
Posted: Fri Apr 11, 2014 5:55 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
oh, Great.. But Unfortunately i am not familiar with Java or Perl.
So i am going to re-write this code in C Once again with proper headers and Variable names as you will understand , Also i will be following the IBM manual says.
I will give it in next 1 hr so that you can validate and if possible find any error. |
|
Back to top |
|
 |
vignesh1988 |
Posted: Fri Apr 11, 2014 7:25 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
PIIIIINNNGGOOO...
I got it... Thankssss alot for helping and assisting me here JCV and all others..
I re-wrote my code "very" "very" carefully seeing each and every line of the IBM manual. and i was able to see the auths
Code: |
/* Include standard libraries */
#include <memory.h>
#include <stdio.h>
/* Include MQSeries headers */
#include <cmqc.h>
#include <cmqcfc.h>
#include <cmqxc.h>
MQOD ObjDesc = { MQOD_DEFAULT };
MQMD md = { MQMD_DEFAULT };
MQPMO pmo = { MQPMO_DEFAULT };
MQGMO gmo = { MQGMO_DEFAULT };
void PutMsg( MQHCONN hConn /* Connection to queue manager */
, MQCHAR8 MsgFormat /* Format of user data to be put in msg */
, MQHOBJ hQName /* handle of queue to put the message to */
, MQCHAR48 QName /* name of queue to put the message to */
, MQBYTE *UserMsg /* The user data to be put in the message */
, MQLONG UserMsgLen /* */
);
void GetMsg( MQHCONN hConn /* handle of queue manager */
, MQLONG MQParm /* Options to specify nature of get */
, MQHOBJ hQName /* handle of queue to read from */
, MQBYTE *UserMsg /* Input/Output buffer containing msg */
, MQLONG ReadBufferLen /* Length of supplied buffer */
);
MQHOBJ OpenQ( MQHCONN hConn
, MQCHAR48 QName
, MQLONG OpenOpts
);
MQLONG iqmCompCode; /* Completion code */
MQLONG iqmReason; /* Reason code */
int main( int argc, char *argv[] )
{
MQCHAR48 QMgrName; /* Name of connected queue mgr */
MQHCONN hConn; /* handle to connected queue mgr */
MQOD ObjDesc; /* */
MQLONG OpenOpts; /* */
MQLONG CompCode; /* MQ API completion code */
MQLONG Reason; /* Reason qualifying above */
/* */
MQHOBJ hAdminQ; /* handle to output queue */
MQHOBJ hReplyQ; /* handle to input queue */
/* */
MQLONG AdminMsgLen; /* Length of user message buffer */
MQBYTE *pAdminMsg; /* Ptr to outbound data buffer */
MQCFH *pPCFHeader; /* Ptr to PCF header structure */
MQCFST *pPCFString; /* Ptr to PCF string parm block */
MQCFIN *pPCFInteger; /* Ptr to PCF integer parm block */
MQCFIL *pPCFIntegerList;
MQCFSL *pPCFStringList;
MQLONG *pPCFType; /* Type field of PCF message parm */
/* */
char ErrorReport[40]; /* */
MQCHAR8 MsgFormat; /* Format of inbound message */
short Index; /* Loop counter */
char Profile_Name[MQ_AUTH_PROFILE_NAME_LENGTH + 1]="XBBJ605.TEST.LOCAL";
int ADD_AUTHS_LENGTH = 4; // As of now only 1 Authority
char Group_Entitity[MQ_ENTITY_NAME_LENGTH + 1]="dsmd";
MQCNO mqcno = {MQCNO_DEFAULT} ; /* Connection options , Initial Values */
MQCD mqcd = {MQCD_CLIENT_CONN_DEFAULT}; /* Channel Defs , Initializing */
strcpy(QMgrName,"TEST");
if ( argc > 1 )
strcpy(QMgrName, argv[1]);
strcpy(mqcd.ConnectionName,"a080n00(1416)");
strcpy(mqcd.ChannelName,"SYSTEM.DEF.SVRCONN");
mqcno.ClientConnPtr = &mqcd;
mqcno.Version = MQCNO_VERSION_2;
MQCONNX(QMgrName,
&mqcno,
&hConn,
&iqmCompCode,
&iqmReason);
if (iqmCompCode == MQCC_FAILED)
{
printf("The Queue Manager %s says :|",QMgrName);
printf("Failed:MQCONNX:Code-%ld|", iqmReason);
return(iqmReason);
}
/* Open all the required queues */
hAdminQ = OpenQ( hConn, "SYSTEM.ADMIN.COMMAND.QUEUE\0", MQOO_OUTPUT );
hReplyQ = OpenQ( hConn, "XBBJ605.MODEL.QUEUE\0", MQOO_INPUT_EXCLUSIVE );
AdminMsgLen = MQCFH_STRUC_LENGTH + MQCFST_STRUC_LENGTH_FIXED + MQ_AUTH_PROFILE_NAME_LENGTH
+ MQCFIN_STRUC_LENGTH + MQCFIL_STRUC_LENGTH_FIXED + ADD_AUTHS_LENGTH
+ MQCFSL_STRUC_LENGTH_FIXED + MQ_ENTITY_NAME_LENGTH ;
printf("AdminMsgLen = %d bytes\n",AdminMsgLen);
pAdminMsg = (MQBYTE *)malloc( AdminMsgLen ); // pAdminMsg Will have the base Address block returned from the MALLOC Function
pPCFHeader = (MQCFH *)pAdminMsg; // Making pPCFHeader Structure Pointer to point to the starting index of the Memory Block
/* Setup request header */
pPCFHeader->Type = MQCFT_COMMAND;
pPCFHeader->StrucLength = MQCFH_STRUC_LENGTH;
pPCFHeader->Version = MQCFH_CURRENT_VERSION;
pPCFHeader->Command = MQCMD_SET_AUTH_REC;
pPCFHeader->MsgSeqNumber = MQCFC_LAST;
pPCFHeader->Control = MQCFC_LAST;
pPCFHeader->ParameterCount = 4;
pPCFString = (MQCFST *)(pAdminMsg + MQCFH_STRUC_LENGTH ); // Making pPCFString Structure Pointer to point to the starting Index after pPCF Header memory block
/* set the ObjectType field */
pPCFString->Type = MQCFT_STRING;
pPCFString->StrucLength = MQCFST_STRUC_LENGTH_FIXED + MQ_AUTH_PROFILE_NAME_LENGTH;
pPCFString->Parameter = MQCACF_AUTH_PROFILE_NAME;
pPCFString->CodedCharSetId = MQCCSI_DEFAULT;
pPCFString->StringLength = MQ_AUTH_PROFILE_NAME_LENGTH;
memset(pPCFString->String, ' ', MQ_AUTH_PROFILE_NAME_LENGTH);
strcpy(pPCFString->String,Profile_Name);
printf("pPCFString-> String : %s\n",pPCFString->String);
pPCFInteger = (MQCFIN *)(pAdminMsg + MQCFH_STRUC_LENGTH + MQCFST_STRUC_LENGTH_FIXED + MQ_AUTH_PROFILE_NAME_LENGTH);
pPCFInteger->Type = MQCFT_INTEGER;
pPCFInteger->StrucLength = MQCFIN_STRUC_LENGTH;
pPCFInteger->Parameter = MQIACF_OBJECT_TYPE;
pPCFInteger->Value = MQOT_Q;
printf("pPCFInteger->Value : %d\n",pPCFInteger->Value);
/* indicate required attributes */
pPCFIntegerList = (MQCFIL *)(pAdminMsg + MQCFH_STRUC_LENGTH + MQCFST_STRUC_LENGTH_FIXED + MQ_AUTH_PROFILE_NAME_LENGTH + MQCFIN_STRUC_LENGTH);
pPCFIntegerList->Type = MQCFT_INTEGER_LIST;
pPCFIntegerList->StrucLength = MQCFIL_STRUC_LENGTH_FIXED + ADD_AUTHS_LENGTH;
pPCFIntegerList->Parameter = MQIACF_AUTH_ADD_AUTHS;
pPCFIntegerList->Count = 1;
pPCFIntegerList->Values[0] = MQAUTH_INQUIRE;
pPCFStringList = (MQCFSL *) (pAdminMsg + MQCFH_STRUC_LENGTH + MQCFST_STRUC_LENGTH_FIXED + MQ_AUTH_PROFILE_NAME_LENGTH + MQCFIN_STRUC_LENGTH + MQCFIL_STRUC_LENGTH_FIXED + ADD_AUTHS_LENGTH);
/* indicate required attributes */
pPCFStringList->Type = MQCFT_STRING_LIST;
pPCFStringList->StrucLength = MQCFSL_STRUC_LENGTH_FIXED + MQ_ENTITY_NAME_LENGTH;
pPCFStringList->Parameter = MQCACF_GROUP_ENTITY_NAMES;
pPCFStringList->CodedCharSetId = MQCCSI_DEFAULT;
pPCFStringList->Count = 1;
pPCFStringList->StringLength = MQ_ENTITY_NAME_LENGTH;
memset(pPCFStringList->Strings, ' ', MQ_ENTITY_NAME_LENGTH);
strcpy(pPCFStringList->Strings,Group_Entitity);
printf("pPCFStringList->Strings : %s\n",pPCFStringList->Strings);
printf("All Values are set, MQPUT is going to Happen\n");
printf("*********************************************\n");
PutMsg( hConn /* Queue manager handle */
, MQFMT_ADMIN /* Format of message */
, hAdminQ /* Handle of command queue */
, "XBBJ605.MODEL.QUEUE\0" /* reply to queue */
, (MQBYTE *)pAdminMsg /* Data part of message to put */
, AdminMsgLen
);
free( pAdminMsg );
AdminMsgLen = MQCFH_STRUC_LENGTH + MQCFST_STRUC_LENGTH_FIXED + MQ_AUTH_PROFILE_NAME_LENGTH
+ MQCFIN_STRUC_LENGTH + MQCFIL_STRUC_LENGTH_FIXED + ADD_AUTHS_LENGTH
+ MQCFSL_STRUC_LENGTH_FIXED + MQ_ENTITY_NAME_LENGTH + 1000; // 1000 for extra Buffer Space.
/* Set pointers to message data buffers */
pAdminMsg = (MQBYTE *)malloc( AdminMsgLen );
gmo.Options = MQGMO_WAIT /* wait for new messages */
| MQGMO_NO_SYNCPOINT /* no transaction */
| MQGMO_CONVERT; /* convert if necessary */
do {
GetMsg( hConn /* Queue manager handle */
, gmo.Options
, hReplyQ /* Get queue handle */
, (MQBYTE *)pAdminMsg /* pointer to message area */
, AdminMsgLen /* length of get buffer */
);
/* Examine Header */
pPCFHeader = (MQCFH *)pAdminMsg;
printf("pPCFHeader->ParameterCount : %d\n",pPCFHeader->ParameterCount);
pPCFType = (MQLONG *)(pAdminMsg + MQCFH_STRUC_LENGTH);
printf("pPCFType = %d , MQCFT_INTEGER = %d , MQCFT_STRING = %d\n",*pPCFType,MQCFT_INTEGER,MQCFT_STRING);
printf("pPCFHeader->Reason: %d pPCFHeader->CompCode: %d\n",pPCFHeader->Reason,pPCFHeader->CompCode);
} while ( pPCFHeader->Control == MQCFC_NOT_LAST ); /* enddo */
free( pAdminMsg );
if (iqmReason != MQRC_ALREADY_CONNECTED)
{
MQDISC(&hConn,
&iqmCompCode,
&iqmReason);
if (iqmReason != MQRC_NONE)
printf("MQDISC ended with reason code %d\n", iqmReason);
}
return 0;
}
MQHOBJ OpenQ( MQHCONN hConn, MQCHAR48 QName, MQLONG OpenOpts)
{
MQHOBJ Hobj;
MQLONG CompCode, Reason;
ObjDesc.ObjectType = MQOT_Q;
strncpy(ObjDesc.ObjectName, QName, MQ_Q_NAME_LENGTH);
MQOPEN(hConn, /* connection handle */
&ObjDesc, /* object descriptor for queue */
OpenOpts, /* open options */
&Hobj, /* object handle */
&CompCode, /* MQOPEN completion code */
&Reason); /* reason code */
/* report reason, if any; stop if failed */
if (Reason != MQRC_NONE)
{
printf("MQOPEN for %s ended with Reason Code %d and Comp Code %d\n",
QName,
Reason,
CompCode);
if (iqmReason != MQRC_ALREADY_CONNECTED)
{
MQDISC(&hConn,
&iqmCompCode,
&iqmReason);
if (iqmReason != MQRC_NONE)
printf("MQDISC ended with reason code %d\n", iqmReason);
}
exit( -1 );
}
return Hobj;
}
void PutMsg(MQHCONN hConn,
MQCHAR8 MsgFormat,
MQHOBJ hQName,
MQCHAR48 QName,
MQBYTE *UserMsg,
MQLONG UserMsgLen)
{
MQLONG CompCode, Reason;
/* setup the message descriptor prior to putting the message */
md.Report = MQRO_NONE;
md.MsgType = MQMT_REQUEST;
md.Expiry = MQEI_UNLIMITED;
md.Feedback = MQFB_NONE;
md.Encoding = MQENC_NATIVE;
md.Priority = MQPRI_PRIORITY_AS_Q_DEF;
md.Persistence = MQPER_PERSISTENCE_AS_Q_DEF;
md.MsgSeqNumber = 1;
md.Offset = 0;
md.MsgFlags = MQMF_NONE;
md.OriginalLength = MQOL_UNDEFINED;
memcpy(md.GroupId, MQGI_NONE, sizeof(md.GroupId));
memcpy(md.Format, MsgFormat, sizeof(md.Format) );
memcpy(md.ReplyToQ, QName, sizeof(md.ReplyToQ) );
/* reset MsgId and CorrelId to get a new one */
memcpy(md.MsgId, MQMI_NONE, sizeof(md.MsgId) );
memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId) );
MQPUT(hConn, /* connection handle */
hQName, /* object handle */
&md, /* message descriptor */
&pmo, /* default options */
UserMsgLen, /* message length */
(MQBYTE *)UserMsg, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
if (Reason != MQRC_NONE) {
printf("MQPUT ended with with Reason Code %d and Comp Code %d\n",
Reason, CompCode);
if (iqmReason != MQRC_ALREADY_CONNECTED)
{
MQDISC(&hConn,
&iqmCompCode,
&iqmReason);
if (iqmReason != MQRC_NONE)
printf("MQDISC ended with reason code %d\n", iqmReason);
}
exit( -1 );
}
printf("MQPUT Call Reason = %d, CC = %d\n",Reason,CompCode);
printf("***********************************************************************\n");
}
void GetMsg(MQHCONN hConn, MQLONG MQParm, MQHOBJ hQName,
MQBYTE *UserMsg, MQLONG ReadBufferLen)
{
MQLONG CompCode, Reason, msglen;
gmo.Options = MQParm;
gmo.WaitInterval = 9000000;
/* reset MsgId and CorrelId to get a new one */
memcpy(md.MsgId, MQMI_NONE, sizeof(md.MsgId) );
memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId) );
MQGET(hConn, /* connection handle */
hQName, /* object handle */
&md, /* message descriptor */
&gmo, /* get message options */
ReadBufferLen, /* Buffer length */
(MQBYTE *)UserMsg, /* message buffer */
&msglen, /* message length */
&CompCode, /* completion code */
&Reason); /* reason code */
if (Reason != MQRC_NONE) {
printf("MQGET ended with Reason Code %d and Comp Code %d\n",
Reason, CompCode);
if (iqmReason != MQRC_ALREADY_CONNECTED)
{
MQDISC(&hConn,
&iqmCompCode,
&iqmReason);
if (iqmReason != MQRC_NONE)
printf("MQDISC ended with reason code %d\n", iqmReason);
}
exit( -1 );
}
printf("MQGET Call Reason = %d, CC = %d\n",Reason,CompCode);
printf("***********************************************************************\n");
}
|
|
|
Back to top |
|
 |
mqjeff |
Posted: Fri Apr 11, 2014 8:17 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
vignesh1988 wrote: |
I re-wrote my code "very" "very" carefully seeing each and every line of the IBM manual. |
Welcome to PCF messages...  |
|
Back to top |
|
 |
vignesh1988 |
Posted: Fri Apr 11, 2014 8:23 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
Thanks Jeff... But more way to go..
Isn't MQCMD_SET_AUTH_REC supported to OPENVMS?
I got 3007 0x00000bbf MQRCCF_CFH_COMMAND_ERROR when tried upon VMS Platforms.. |
|
Back to top |
|
 |
jcv |
Posted: Mon Apr 14, 2014 2:21 am Post subject: |
|
|
 Chevalier
Joined: 07 May 2007 Posts: 411 Location: Zagreb
|
Bravo Vignesh, but this still doesn't work quite OK. You can make it easier to spot the problem if you add another command line argument for passing group name to your program. Now, if you alter the input for the group name between existing and non existing group, response will alter between RC=0 and RC=2292. But I notice that response is always one execution behind. For example if you start with non existing group name, and you submit it two times, first you will receive RC=0 and then RC=2292. Then submit the group name that exists two times, first you will receive RC=2292 and then RC=0, and so on. At least that's what I see on my machine. |
|
Back to top |
|
 |
vignesh1988 |
Posted: Mon Apr 14, 2014 2:28 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
Thanks JCV,
I have modified the Code to accept the command line arguments and i receive 2292 (Unknown Entity) for incorrect group , 2085 (for Unknown Profile) etc.. I receiver min. of 2 responses (1 for Actual Response Return Code, 2nd is the General PCF return code (3008 -> Command Failed))
As of now i am checking this code on several environments and testing it.. As of now it works good.
Let me know your comments on it.
But bottom of my heart, I personally thank you for taking your time to help me. |
|
Back to top |
|
 |
jcv |
Posted: Mon Apr 14, 2014 4:26 am Post subject: |
|
|
 Chevalier
Joined: 07 May 2007 Posts: 411 Location: Zagreb
|
Vignesh, no problem, you are wellcome. In fact, thank you for posting on this forum, because your problem made me to enter the world of pcf messages, which is also new to me.
When I get 2292, I get also 3008, of course, and when I get 0, there is only one response message, as we noticed earlier, nothing is changed there. When all input is correct, command is executed (I see auth rec added every time, although I delete it between executions). When input is not correct, auth rec doesn't get added, which is normal. What's not normal, is that response is not always adequate, as if it were from previous execution, and I don't know what causes that delay, so I still get RC 0 on unsuccessful completion (for incorrect group name), and RC>0 for a successful completion. |
|
Back to top |
|
 |
jcv |
Posted: Mon Apr 14, 2014 4:30 am Post subject: |
|
|
 Chevalier
Joined: 07 May 2007 Posts: 411 Location: Zagreb
|
... and maybe it's not about response, probably it's about receiving and printing that response. |
|
Back to top |
|
 |
vignesh1988 |
Posted: Mon Apr 14, 2014 5:03 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
I filtered the Response messages .. I see the 1st response is the Orginal Return Code of "WHY" the Command Failed.
2nd is usually 3008 for me.
So i show only 1st one for the users... |
|
Back to top |
|
 |
jcv |
Posted: Mon Apr 14, 2014 7:33 am Post subject: |
|
|
 Chevalier
Joined: 07 May 2007 Posts: 411 Location: Zagreb
|
OK, inappropriate response was caused by two stale messages in a reply queue, that was about the only possible explanation anyway. So, after I deleted them, it works as I would expect.
Only, to me, this is not robust enough, in order to avoid such things, you should probably implement request/reply correlation, because if it breaks again, it will leave unconsumed messages that will cause you a problem, that you too saw a few days ago, and had no explanation for this behaviour. |
|
Back to top |
|
 |
jcv |
Posted: Mon Apr 14, 2014 7:38 am Post subject: |
|
|
 Chevalier
Joined: 07 May 2007 Posts: 411 Location: Zagreb
|
... and that means you should set the correlation id of a response message to a message id of a request message. |
|
Back to top |
|
 |
vignesh1988 |
Posted: Mon Apr 14, 2014 7:40 am Post subject: |
|
|
Acolyte
Joined: 13 Apr 2013 Posts: 62 Location: Chennai
|
So should i check
md.MsgId == md.CorrelId using if statements after get??? |
|
Back to top |
|
 |
jcv |
Posted: Mon Apr 14, 2014 7:49 am Post subject: |
|
|
 Chevalier
Joined: 07 May 2007 Posts: 411 Location: Zagreb
|
No, pass the message id of a request message to GetMsg function and use memcpy there to initialize correl id prior to get. That will ensure that you get proper response. Look at Q or MS03, they must have such logic there. |
|
Back to top |
|
 |
|
|
|
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
|
|
|
|