|
home /
infca /
mq_api
(navigation links)
|
In the End, we will remember not the words of our enemies, but the silence of our friends.
|
MQ API
| MQBACK | back out changes
The MQBACK call indicates to the queue manager
that all of the message gets and puts
that have occurred since the last syncpoint
are to be backed out.
Messages put as part of a unit of work are deleted;
messages retrieved as part of a unit of work are reinstated on the queue.
|
| MQBEGIN | start a global unit of work
To start a global unit of work, the application issues the MQBEGIN call.
|
| MQCLOSE | close object
|
| MQCMIT | commit changes
|
| MQCONN | connect queue manager -
MQCONN ( QMgrName, & Hconn, & CompCode, & Reason ) ;
|
| MQCONNX | connect queue manager (extended)
|
| MQDISC | disconnect queue manager
|
| MQGET | get message
|
| MQINQ | inquire object attributes
|
| MQOPEN | open object -
MQOPEN ( Hconn, & ObjDesc, Options, & Hobj, & CompCode, & Reason ) ;
|
| MQPUT | put message
|
| MQPUT1 | put one message
|
| MQSET | set object attributes
|
Usual sequence is :
MQ Connect (queue manager name)
MQ Open (queue name)
MQ Put / Get (message)
MQ Close (q)
MQ Disconnect (qm)
Complete (including BackOut) sequence is :
MQ Connect (queue manager name)
MQ Open (queue name)
MQ Inquiry(Backout Threshold, Backout Requeue Queue Name)
Get (message)
if ( MD.BackOutCount <= QueueThreshold )
then MQ_BACK()
else begin
MQ Open (Backout Requeue Queue)
MQ Put (msg)
MQ Close()
MQ Commit()
end
MQ Close (q)
MQ Disconnect (qm)
Pub/Sub sequence:
MQ Connect (queue manager name)
MQ Subscribe (topic / managed queue)
MQ Get (message)
MQ Close (q)
MQ Disconnect (qm)
Mind amqapi.exe = MQ API Exerciser.
Putting messages on remote queues
When an application puts a message on a remote queue
(either by specifying the name of the remote queue directly,
or by using a local definition of the remote queue),
the local queue manager:
- creates an MQXQH structure containing the embedded message descriptor
- appends an MQMDE if one is needed and is not already present
- appends the application message data
- places the message on an appropriate transmission queue
Putting messages directly on transmission queues
An application can also put a message directly on a transmission queue.
In this case the application must prefix the application message data with an MQXQH structure,
and initialize the fields with appropriate values.
In addition,
the Format field in the MsgDesc parameter of the MQPUT or MQPUT1 call must have the value MQFMT_XMIT_Q_HEADER.
MQ v 6.0,
Application Programming Reference,
SC34-6596-00,
page 311 [335/665]
API call parameters
Few constants, few vars and how to display them
#define MQ_Q_MGR_NAME_LENGTH 48
#define MQ_Q_NAME_LENGTH 48
MQCHAR Q_Mgr_Name [ MQ_Q_MGR_NAME_LENGTH ] ; /* name of connection q manager */
printf ( "Messages for QMN [%-48.48s].\n", Q_Mgr_Name ) ;
printf ( "Q name (%.48s).", mqmd.ReplyToQ ) ; // display Queue Name
printf ( "Message PutDate: [%.*s].\n", MQ_PUT_DATE_LENGTH, md.PutDate ) ; // display MQMD field
printf ( "MQ CC/RC [0x%2.2X/0x%4.4X].\n", CC, RC ) ;
MQConnect()
First we set some vars :
int iLng ; // a string length
char QMName [ MQ_Q_MGR_NAME_LENGTH ] ; // queue manager name
MQHCONN Hcon ; // connection handle
Queue_Manager_Name [0] = 0 ; /* use the default qmgr if none provided */
if ( argc > 1 ) {
iLng = strlen ( argv [1] ) ;
if ( iLng <= MQ_Q_MGR_NAME_LENGTH ) {
strcpy ( Queue_Manager_Name, argv [1] ) ;
} else {
printf ( "--- Error - queue manager name too large [%i]. Max is (%i).\n", iLng, MQ_Q_MGR_NAME_LENGTH ) ;
exit ( -1 ) ;
} ; /* endif */
} ; /* endif */
Then we call the API:
printf ( ">>> MQCONN() to queue manager [%-48.48s].\n", QMgrName ) ;
MQCONN ( QMgrName, /* in : queue manager name */
& Hcon, /* out : connection handle */
& Conn_CC, /* out : completion code */
& Conn_RC ) ; /* out : reason code */
if ( ( Conn_CC == MQCC_OK ) && ( Conn_RC == MQRC_NONE ) )
{
printf ( "+++ MQCONN() ended OK. Handle is [%ld/0x%8.8X].\n", Hcon, Hcon ) ;
}
else /* report reason and exit */
{
printf ( "--- MQCONN() ended with Completion Code [%ld/0x2.2X], Reason Code [%ld/0x%4.4X].\n", Conn_CC, Conn_CC, Conn_RC, Conn_RC ) ;
exit ( 0 ) ;
} ; // MQCONN() error
On WebSphere MQ platforms other than WebSphere MQ for z/OS,
a connection made with MQCONN is available only to the thread that made the connection.
Options on the MQCONNX call allow you to create a connection that can be shared by all the threads in a process.
Application Programming Guide, MQ v6.0, SC34-6595-01, page 88 [108/601].
Scope of MQCONN or MQCONNX.
Within WebSphere MQ for iSeries, WebSphere MQ on UNIX systems, and WebSphere MQ for Windows,
the scope of an MQCONN or MQCONNX call is usually the thread that issued it.
That is, the connection handle returned from the call is valid only within the thread that issued the call.
Only one call can be made at any one time using the handle.
If it is used from a different thread, it is rejected as invalid.
If you have multiple threads in your application and each wants to use WebSphere MQ calls,
each one must issue MQCONN or MQCONNX.
Application Programming Guide, MQ v6.0, SC34-6595-01, page 85 [106/601].
MQConnX()
See sample at
\\MQ\Eines\AMQSCNXC_proves_Conexio_Client\amqscnxc.c
and
\\MQ\Eines\Default_QmgrName\codiX.c
MQCHAR QMName [ MQ_Q_MGR_NAME_LENGTH ] ; /* name of q manager we connect to */
MQCNO Connect_options = { MQCNO_DEFAULT } ; /* connect options */
MQCD ClientConn = { MQCD_CLIENT_CONN_DEFAULT } ; /* client Connection channel Definition */
strncpy ( QMName, "MYQMGR", MQ_Q_MGR_NAME_LENGTH ) ;
strncpy ( ClientConn.ConnectionName, "localhost(1415)", MQ_CONN_NAME_LENGTH ) ;
strncpy ( ClientConn.ChannelName, "MY.SVRCONN", MQ_CHANNEL_NAME_LENGTH ) ;
Connect_options.ClientConnPtr = & ClientConn ;
Connect_options.Version = MQCNO_VERSION_2 ;
MQCONNX ( QMName, /* queue manager */
& Connect_options, /* options for connection */
& Hcon, /* connection handle */
& CompCode, /* completion code */
& CReason ) ; /* reason code */
Now, Delphi-stype, from \\Delphi\MQ\Put1\doPut1.pas :
procedure TfDoMQput1.bConnectClick(Sender: TObject);
var
qmn : MQCHAR48 ;
Connect_Options : MQCNO ;
Client_Connection_Definition : MQCD ;
Cnx_CC, Cnx_RC : integer ;
begin
hConnect := 0 ;
move ( MQCNO_DEFAULT, Connect_Options, sizeof (MQCNO_DEFAULT) ) ; // source, destination, count.
move ( MQCD_CLIENT_CONN_DEFAULT, Client_Connection_Definition, sizeof (MQCD_CLIENT_CONN_DEFAULT) ) ;
StrPCopy ( qmn, eQmgr.Text ) ; // destination(array), origin(string).
StrPCopy ( Client_Connection_Definition.ConnectionName, eConnectName.Text ) ; // NOM.SVRCONN
StrPCopy ( Client_Connection_Definition.ChannelName, eConnectName.Text ) ; // 1.2.3.4(1415)
Connect_Options.Version := MQCNO_VERSION_2 ;
Connect_Options.ClientConnPtr := @ Client_Connection_Definition ;
MQCONNX ( @ qmn, // queue manager
@ Connect_Options, // options for connection
@ hConnect, // out : connection handle
@ Cnx_CC, // out : completion code
@ Cnx_RC ) ; // out : reason code
if ( Cnx_CC <> MQCC_OK ) then begin
hConnect := 0 ;
end ;
eHandleConexion.Text := IntToStr( hConnect ) ;
end; // Connect_Click()
MQCONNX() timeout
When a client issues a MQCONNX to connect to a queue manager, this makes a tcpip connect() call.
If the tcpip connect() can not complete because the remote host is not available,
then it will eventually timeout and return a tcpip reason code x'91' (145, ETIMEDOUT).
The amount of time it takes for the timeout to occur is set by parameters in TCP/IP.
The Solaris ndd settable parameter tcp_ip_abort_cinterval defaults to a setting of 180000 milliseconds (3 minutes).
The corresponding Windows registry parameters should be:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpMaxConnectRetransmissions
and
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\interface-name\TcpInitialRTT
url, by Peter
TCP connect timeout
You can also tell MQ how long to wait for a TCP connect using the environment variable MQTCPTIMEOUT.
If this variable is set then MQ will issue a non-blocking version of connect()
and give up waiting for TCP after so many seconds.
MQOpen()
Var declaration, initialization, display and API call:
MQLONG Open_Options; /* MQOPEN options */
MQOD od = {MQOD_DEFAULT}; /* Object Descriptor */
od.ObjectType = MQOT_Q_MGR ; /* open the queue manager object */
Open_Options = MQOO_INQUIRE + MQOO_FAIL_IF_QUIESCING ; /* open it for inquire, but not if MQM stopping */
printf (">>> MQOPEN(). Object Type = (0x%2.2X). Open Options = (0x%2.2X).\n", od.ObjectType, Open_Options ) ;
MQOPEN ( Hcon, /* in : connection handle */
& od, /* in/out : object (queue) descriptor */
Open_Options, /* in : open options */
& Hinq, /* out : object handle */
& Open_CompCode, /* out : completion code */
& Open_Reason ) ; /* out : reason code */
MQPut()
MQPUT ( Hcon, /* in : connection handle */
Hobj, /* in : object handle */
& md, /* in/out : message descriptor */
& pmo, /* in/out : put msg options */
messlen, /* in : message length */
buffer, /* in : message buffer */
& CompCode, /* out : completion code */
& Reason ) ; /* out : reason code */
If the message is too big for the queue, MQRC_MSG_TOO_BIG_FOR_Q is returned.
{ 2030 0x000007ee MQRC_MSG_TOO_BIG_FOR_Q }
Similarly, if the message is too big for the queue manager, MQRC_MSG_TOO_BIG_FOR_Q_MGR is returned.
MQGet()
MQGET ( Hcon, // input : connection handle
Hobj, // input : object handle
& md, // int/out : message descriptor = attributes of the message required
& gmo, // int/out : get message options = control the action of MQGET().
buffer_length, // input : buffer length
p_msg_text, // output : message buffer
& msg_length, // output : message length
& Completion_Code, // out : completion code
& Reason_Code ) ; // out : reason code
BufferLength (MQLONG) input
Specify zero for messages that have no data,
or if the message is to be removed from the queue and the data discarded (you must specify MQGMO_ACCEPT_TRUNCATED_MSG in this case).
If BufferLength is less than the message length,
as much of the message as possible is moved into Buffer;
this happens whether or not MQGMO_ACCEPT_TRUNCATED_MSG is specified on the GetMsgOpts parameter
To get the received msg length :
Specify a size of zero bytes and do not use the MQGMO_ACCEPT_TRUNCATED_MSG option.
If the MQGET call fails (for example, because the buffer is too small),
the length of the message is returned in the DataLength parameter of the call.
(The buffer is still filled with as much of the message as it can hold, but the processing of the call is not completed)
Store the MsgId of this message, then repeat the MQGET call,
specifying a buffer area of the correct size, and the MsgId that you noted from the first call.
MQInq()
Quins tipus de MQ_Inquiry() podem fer ? {see cmqc.h}
- Character-Attribute Selectors :
- queue manager name : "Selector = MQCA_Q_MGR_NAME ;" ( \\MQ\Eines\Default_QmgrName\codi.c )
- dead-letter-q name : "Selector = MQCA_DEAD_LETTER_Q_NAME ;" ( \\cpp\mvqat\cmemqdlq.c or \\cpp\mqi\dlq\readdlq.c )
MQLONG Selector ; /* one selector */
char QMName [ MQ_Q_MGR_NAME_LENGTH ] ; /* queue manager name */
Selector = MQCA_Q_MGR_NAME ;
MQINQ ( Hcon, /* input : this handle represents the connection to the queue manager */
Hobj, /* input : object of any type whose attributes are required, returned by MQOPEN with MQOO_INQUIRE */
1, /* input : count of selectors supplied in the Selectors array : inquire only one selector */
& Selector, /* input : array of attribute selectors, this is, the selector to inquire */
0, /* input : count of integer attributes : no integer attributes needed */
NULL, /* output : array of integer attributes : so no buffer supplied */
MQ_Q_MGR_NAME_LENGTH, /* input : length of character attributes buffer : inquiring a q manager name */
QMName, /* output : buffer in which the character attributes are returned : the buffer for the name */
& CompCode, /* output : MQINQ completion code */
& Reason ) ; /* output : MQINQ reason code */
- Integer-Attribute Selectors, as
- queue depth : "Selector = MQIA_CURRENT_Q_DEPTH ; " ( \\MQ\Eines\AMQSINQ_inquiry_one_queue_depth\inqqd.c or AMQSINQA.c or \\MQ\Eines\Dead_LQ\DLQ_read.c )
MQLONG Select [3] ; /* attribute selectors */
MQLONG IAV [3] ; /* integer attribute values */
Select [0] = MQIA_CURRENT_Q_DEPTH ;
MQINQ ( Hcon, /* in : connection handle */
Hinq, /* in : object handle */
1, /* in : Selector count 3 */
Select, /* in : Selector array */
1, /* in : integer attribute count 3 */
IAV, /* out : integer attribute array */
0, /* in : character attribute count */
NULL, /* out : character attribute array */
& CC_inq, /* out : completion code */
& RC_inq ) ; /* out : reason code */
MQClose()
if ( Hobj != (MQHOBJ) NULL ) {
printf (">>> MQCLOSE() - handle (0x%8.8X).\n", Hobj ) ;
MQCLOSE ( Hcon,
& Hobj, // i/o : on successful completion, queue manager sets it to an invalid value for the environment : MQHO_UNUSABLE_HOBJ
0, // i : options - this parameter controls how the object is closed
& iCC_Close,
& iRC_Close ) ;
Hobj = 0 ; // indicate we dont have a handle anymore
} ; // we have a handle
In Close_Options you must specify one option only from the following :
- MQCO_DELETE
- MQCO_DELETE_PURGE
- MQCO_KEEP_SUB
- MQCO_REMOVE_SUB
- MQCO_IMMEDIATE
- MQCO_NONE
MQCO_NONE
No optional close processing required.
This must be specified for:
- objects other than queues
- predefined queues
- temporary dynamic queues (but only in those cases where Hobj is not the handle returned by the MQOPEN call that created the queue)
- distribution lists
In all the above cases, the object is retained and not deleted.
If this option is specified for a temporary dynamic queue:
- the queue is deleted, if it was created by the MQOPEN call that returned Hobj; any messages that are on the queue are purged
- in all other cases the queue (and any messages on it) are retained.
If this option is specified for a permanent dynamic queue, the queue is retained and not deleted.
Here we have a complete
table !
MQDisc()
if ( Hcon != (MQHCONN) NULL ) {
printf (">>> MQDISC() - handle (0x%8.8X).\n", Hcon ) ;
MQDISC ( & Hcon,
& CC_Disc,
& RC_Disc ) ;
Hcon = 0 ;
} ;
MQOD - Object Descriptor
struct tagMQOD {
MQCHAR4 StrucId ; // in : Structure identifier x'00
MQLONG Version ; // in : Structure version number x'04
MQLONG ObjectType ; // in : Object type x'08
MQCHAR48 ObjectName ; // in/out : Object name x'0C
MQCHAR48 ObjectQMgrName ; // in/out : Object queue manager name x'3C
MQCHAR48 DynamicQName ; // in : Dynamic queue name x'6C
MQCHAR12 AlternateUserId ; // in : Alternate user identifier x'9C
/* Ver:1 */ x'A8
MQLONG RecsPresent ; // in : Number of object records present x'A8
MQLONG KnownDestCount ; // out : Number of local queues opened successfully x'AC
MQLONG UnknownDestCount ; // out : Number of remote queues opened successfully x'B0
MQLONG InvalidDestCount ; // out : Number of queues that failed to open x'B4
MQLONG ObjectRecOffset ; // in : Offset of first object record from start of MQOD x'B8
MQLONG ResponseRecOffset ; // in : Offset of first response record from start of MQOD x'BC
MQPTR ObjectRecPtr ; // in : Address of first object record x'C0
MQPTR ResponseRecPtr ; // in : Address of first response record x'C4
/* Ver:2 */ x'C8 = d'200
MQBYTE40 AlternateSecurityId ; // in : Alternate security identifier x'C8
MQCHAR48 ResolvedQName ; // out : Resolved queue name x'F0
MQCHAR48 ResolvedQMgrName ; // out : Resolved queue manager name x'120
/* Ver:3 */ x'150
MQCHARV ObjectString ; // Object long name x'150
MQCHARV SelectionString ; // Message Selector x'164
MQCHARV ResObjectString ; // Resolved long object name x'178
MQLONG ResolvedType ; // Alias queue resolved object type x'18C
/* Ver:4 */ x'190 = d'400
} ;
url
url
Here ObjectType can be :
#define MQOT_Q 1
#define MQOT_Q_MGR 5
#define MQOT_CHANNEL 6
#define MQOT_AUTH_INFO 7
#define MQOT_LISTENER 11
#define MQOT_SERVICE 12
Mind in CMQC.H we have
/* Structure Length */
#if defined(MQ_64_BIT)
#define MQOD_CURRENT_LENGTH 424
#else
#define MQOD_CURRENT_LENGTH 400
#endif
Dynamic queue name
This is the name of a dynamic queue that is to be created by the MQOPEN call.
This is of relevance only when ObjectName specifies the name of a model queue; in all other cases DynamicQName is ignored.
MQOO - Open Options
In the Options parameter of the MQOPEN call,
you must choose one or more options
to control the access that you are given to the object that you are opening.
V 6.0 Programming Guide,
page 95 [115/601]
MQOO_INPUT_AS_Q_DEF 1 X'00000001'
MQOO_INPUT_SHARED 2 X'00000002'
MQOO_INPUT_EXCLUSIVE 4 X'00000004'
MQOO_BROWSE 8 X'00000008'
MQOO_OUTPUT 16 X'00000010'
MQOO_INQUIRE 32 X'00000020'
MQOO_SET 64 X'00000040'
MQOO_SAVE_ALL_CONTEXT 128 X'00000080'
MQOO_PASS_IDENTITY_CONTEXT 256 X'00000100'
MQOO_PASS_ALL_CONTEXT 512 X'00000200'
MQOO_SET_IDENTITY_CONTEXT 1024 X'00000400'
MQOO_SET_ALL_CONTEXT 2048 X'00000800'
MQOO_ALTERNATE_USER_AUTHORITY 4096 X'00001000'
MQOO_FAIL_IF_QUIESCING 8192 X'00002000'
MQOO_BIND_ON_OPEN 16384 X'00004000'
MQOO_BIND_NOT_FIXED 32768 X'00008000'
MQOO_BIND_AS_Q_DEF 0 X'00000000'
MQOO_RESOLVE_NAMES 65536 X'00010000'
MQOO_RESOLVE_LOCAL_Q 262144 X'00040000'
MQMD - Message descriptor
Every message that passes through a MQ infrastructure
has a message descriptor associated with that message.
The message descriptor contains the meta information about the message.
This information describes the message,
but does not constitute part of the data that the message contains.
Fundamentals 6.0, page 55 [79/446]
The message descriptor structure (MQMD)
is an input/output parameter for the MQPUT and MQPUT1 calls.
Use it to define the message you are putting on a queue.
Programming Guide 6.0, page 102 [122/601]
struct tagMQMD {
MQCHAR4 StrucId ; // 0x00 Structure identifier
MQLONG Version ; // 0x04 Structure version number
MQLONG Report ; // 0x08 Options for report messages
MQLONG MsgType ; // 0x0C Message type
MQLONG Expiry ; // 0x10 Message lifetime
MQLONG Feedback ; // 0x14 Feedback or reason code
MQLONG Encoding ; // 0x18 Numeric encoding of message data
MQLONG CodedCharSetId ; // 0x1C Character set identifier of message data
MQCHAR8 Format ; // 0x20 Format name of message data
MQLONG Priority ; // 0x28 Message priority
MQLONG Persistence ; // 0x2C Message persistence
MQBYTE24 MsgId ; // 0x30 Message identifier
MQBYTE24 CorrelId ; // 0x48 Correlation identifier
MQLONG BackoutCount ; // 0x60 Backout counter
MQCHAR48 ReplyToQ ; // 0x64 Name of reply queue
MQCHAR48 ReplyToQMgr ; // 0x94 Name of reply queue manager
MQCHAR12 UserIdentifier ; // 0xC4 User identifier
MQBYTE32 AccountingToken ; // 0xD0 Accounting token
MQCHAR32 ApplIdentityData ; // 0xF0 Application data relating to identity
MQLONG PutApplType ; // 0x110 Type of application that put the message
MQCHAR28 PutApplName ; // 0x114 Name of application that put the message
MQCHAR8 PutDate ; // 0x128 Date when message was put
MQCHAR8 PutTime ; // 0x130 Time when message was put
MQCHAR4 ApplOriginData ; // 0x138 Application data relating to origin
MQBYTE24 GroupId ; // 0x13C Group identifier
MQLONG MsgSeqNumber ; // 0x154 Sequence number of logical message within group
MQLONG Offset ; // 0x158 Offset of data in physical message from start of logical message
MQLONG MsgFlags ; // 0x15C Message flags
MQLONG OriginalLength ; // 0x160 Length of original message
// 0x164 = d'356
} ;
MQMD.Encoding
/* Encoding */
#define MQENC_NATIVE 0x00000222
/* Encoding Masks */
#define MQENC_INTEGER_MASK 0x0000000f
#define MQENC_DECIMAL_MASK 0x000000f0
#define MQENC_FLOAT_MASK 0x00000f00
#define MQENC_RESERVED_MASK 0xfffff000
/* Encodings for Binary Integers */
#define MQENC_INTEGER_UNDEFINED 0x00000000
#define MQENC_INTEGER_NORMAL 0x00000001
#define MQENC_INTEGER_REVERSED 0x00000002
/* Encodings for Packed-Decimal Integers */
#define MQENC_DECIMAL_UNDEFINED 0x00000000
#define MQENC_DECIMAL_NORMAL 0x00000010
#define MQENC_DECIMAL_REVERSED 0x00000020
/* Encodings for Floating-Point Numbers */
#define MQENC_FLOAT_UNDEFINED 0x00000000
#define MQENC_FLOAT_IEEE_NORMAL 0x00000100
#define MQENC_FLOAT_IEEE_REVERSED 0x00000200
#define MQENC_FLOAT_S390 0x00000300
0x222 = d'546
MQMD.Report
The Report field is very interesting :
/* Report Options */
#define MQRO_EXCEPTION 0x01000000
#define MQRO_EXCEPTION_WITH_DATA 0x03000000
#define MQRO_EXCEPTION_WITH_FULL_DATA 0x07000000
#define MQRO_EXPIRATION 0x00200000
#define MQRO_EXPIRATION_WITH_DATA 0x00600000
#define MQRO_EXPIRATION_WITH_FULL_DATA 0x00E00000
#define MQRO_COA 0x00000100
#define MQRO_COA_WITH_DATA 0x00000300
#define MQRO_COA_WITH_FULL_DATA 0x00000700
#define MQRO_COD 0x00000800
#define MQRO_COD_WITH_DATA 0x00001800
#define MQRO_COD_WITH_FULL_DATA 0x00003800
#define MQRO_PAN 0x00000001
#define MQRO_NAN 0x00000002
#define MQRO_ACTIVITY 0x00000004
#define MQRO_NEW_MSG_ID 0x00000000
#define MQRO_PASS_MSG_ID 0x00000080
#define MQRO_COPY_MSG_ID_TO_CORREL_ID 0x00000000
#define MQRO_PASS_CORREL_ID 0x00000040
#define MQRO_DEAD_LETTER_Q 0x00000000
#define MQRO_DISCARD_MSG 0x08000000
#define MQRO_PASS_DISCARD_AND_EXPIRY 0x00004000
#define MQRO_NONE 0x00000000
Use RFHutil to send a Request message requesting
specifying REPLY_TO_QUEUE and REPLY_TO_QUEUE_MANAGER !
MQGMO - Get() options
/* Get-Message Options */
#define MQGMO_WAIT 0x00000001
#define MQGMO_NO_WAIT 0x00000000
#define MQGMO_SET_SIGNAL 0x00000008
#define MQGMO_FAIL_IF_QUIESCING 0x00002000
#define MQGMO_SYNCPOINT 0x00000002
#define MQGMO_SYNCPOINT_IF_PERSISTENT 0x00001000
#define MQGMO_NO_SYNCPOINT 0x00000004
#define MQGMO_MARK_SKIP_BACKOUT 0x00000080
#define MQGMO_BROWSE_FIRST 0x00000010
#define MQGMO_BROWSE_NEXT 0x00000020
#define MQGMO_BROWSE_MSG_UNDER_CURSOR 0x00000800
#define MQGMO_MSG_UNDER_CURSOR 0x00000100
#define MQGMO_LOCK 0x00000200
#define MQGMO_UNLOCK 0x00000400
#define MQGMO_ACCEPT_TRUNCATED_MSG 0x00000040
#define MQGMO_CONVERT 0x00004000
#define MQGMO_LOGICAL_ORDER 0x00008000
#define MQGMO_COMPLETE_MSG 0x00010000
#define MQGMO_ALL_MSGS_AVAILABLE 0x00020000
#define MQGMO_ALL_SEGMENTS_AVAILABLE 0x00040000
#define MQGMO_NONE 0x00000000
MQPMO - Put() options
Use the MQPMO (Put Message Option) structure
to pass options to the MQPUT and MQPUT1 calls.
Programming Guide 6.0,
page 102 [122/601]
MQPMO_NONE 0 X'00000000'
MQPMO_SYNCPOINT 2 X'00000002'
MQPMO_NO_SYNCPOINT 4 X'00000004'
MQPMO_DEFAULT_CONTEXT 32 X'00000020'
MQPMO_NEW_MSG_ID 64 X'00000040'
MQPMO_NEW_CORREL_ID 128 X'00000080'
MQPMO_PASS_IDENTITY_CONTEXT 256 X'00000100'
MQPMO_PASS_ALL_CONTEXT 512 X'00000200'
MQPMO_SET_IDENTITY_CONTEXT 1024 X'00000400'
MQPMO_SET_ALL_CONTEXT 2048 X'00000800'
MQPMO_ALTERNATE_USER_AUTHORITY 4096 X'00001000'
MQPMO_FAIL_IF_QUIESCING 8192 X'00002000'
MQPMO_NO_CONTEXT 16384 X'00004000'
MQPMO_LOGICAL_ORDER 32768 X'00008000'
MQPMO_RESOLVE_LOCAL_Q 262144 X'00040000'
See chapter 16, MQPMO of MQ Application Programming Reference.
MQPUT1
MQPUT1 is functionally equivalent
to calling MQOPEN followed by MQPUT, followed by MQCLOSE.
The only difference in the syntax for the MQPUT and MQPUT1 calls
is that for MQPUT you must specify an object handle,
whereas for MQPUT1 you must specify an object descriptor structure (MQOD)
as defined in MQOPEN.
So, the sequence now is : MQCONN() + MQPUT1() + MQDISC().
MQPUT1 syntax
MQPUT1 ( Hconn, // in : connection handle
& ObjDesc, // in/out : object descriptor - identifies the queue to which the message is added, or the topic to which the message is published.
& MsgDesc, // in/out : message descriptor
& PutMsgOpts, // in/out : put msg options
MsgLength, // in : message length - zero is valid.
MsgBuffer, // in : message buffer containingthe application message data to be sent
& CompCode, // out : completion code
& Reason ) ; // out : reason code
MQPUT1 vars declaration
MQHCONN Hconn ; /* Connection handle */
MQOD ObjDesc ; /* Object descriptor */
MQMD MsgDesc ; /* Message descriptor */
MQPMO PutMsgOpts ; /* Options that control the action of MQPUT1 */
MQLONG BufferLength ; /* Length of the message in Buffer */
MQBYTE Buffer[n] ; /* Message data */
MQLONG CompCode ; /* Completion code */
MQLONG Reason ; /* Reason code qualifying CompCode */
MQCD = Channel Descriptor
Mind MQCD is located in CMQXC.H !
struct tagMQCD {
MQCHAR ChannelName[20]; // Channel definition name
MQLONG Version; // Structure version number
MQLONG ChannelType; // Channel type
MQLONG TransportType; // Transport type
MQCHAR Desc[64]; // Channel description
MQCHAR QMgrName[48]; // Queue-manager name
MQCHAR XmitQName[48]; // Transmission queue name
MQCHAR ShortConnectionName[20]; // First 20 bytes of connection name
MQCHAR MCAName[20]; // Reserved
MQCHAR ModeName[8]; // LU 6.2 Mode name
MQCHAR TpName[64]; // LU 6.2 transaction program name
MQLONG BatchSize; // Batch size
MQLONG DiscInterval; // Disconnect interval
MQLONG ShortRetryCount; // Short retry count
MQLONG ShortRetryInterval; // Short retry wait interval
MQLONG LongRetryCount; // Long retry count
MQLONG LongRetryInterval; // Long retry wait interval
MQCHAR SecurityExit[128]; // Channel security exit name
MQCHAR MsgExit[128]; // Channel message exit name
MQCHAR SendExit[128]; // Channel send exit name
MQCHAR ReceiveExit[128]; // Channel receive exit name
MQLONG SeqNumberWrap; // Highest allowable message sequence number
MQLONG MaxMsgLength; // Maximum message length
MQLONG PutAuthority; // Put authority
MQLONG DataConversion; // Data conversion
MQCHAR SecurityUserData[32]; // Channel security exit user data
MQCHAR MsgUserData[32]; // Channel message exit user data
MQCHAR SendUserData[32]; // Channel send exit user data
MQCHAR ReceiveUserData[32]; // Channel receive exit user data
/* Ver:1 */
MQCHAR UserIdentifier[12]; // User identifier
MQCHAR Password[12]; // Password
MQCHAR MCAUserIdentifier[12]; // First 12 bytes of MCA user identifier
MQLONG MCAType; // Message channel agent type
MQCHAR ConnectionName[264]; // Connection name
MQCHAR RemoteUserIdentifier[12]; // First 12 bytes of user identifier from partner
MQCHAR RemotePassword[12]; // Password from partner
/* Ver:2 */
MQCHAR MsgRetryExit[128]; // Channel message retry exit name
MQCHAR MsgRetryUserData[32]; // Channel message retry exit user data
MQLONG MsgRetryCount; // Number of times MCA will try to put the message, after first attempt has failed
MQLONG MsgRetryInterval; // Minimum interval in milliseconds after which the open or put operation will be retried
/* Ver:3 */
MQLONG HeartbeatInterval; // Time in seconds between heartbeat flows
MQLONG BatchInterval; // Batch duration
MQLONG NonPersistentMsgSpeed; // Speed at which nonpersistent messages are sent
MQLONG StrucLength; // Length of MQCD structure
MQLONG ExitNameLength; // Length of exit name
MQLONG ExitDataLength; // Length of exit user data
MQLONG MsgExitsDefined; // Number of message exits defined
MQLONG SendExitsDefined; // Number of send exits defined
MQLONG ReceiveExitsDefined; // Number of receive exits defined
MQPTR MsgExitPtr; // Address of first MsgExit field
MQPTR MsgUserDataPtr; // Address of first MsgUserData field
MQPTR SendExitPtr; // Address of first SendExit field
MQPTR SendUserDataPtr; // Address of first SendUserData field
MQPTR ReceiveExitPtr; // Address of first ReceiveExit field
MQPTR ReceiveUserDataPtr; // Address of first ReceiveUserData field
/* Ver:4 */
MQPTR ClusterPtr; // Address of a list of cluster names
MQLONG ClustersDefined; // Number of clusters to which the channel belongs
MQLONG NetworkPriority; // Network priority
/* Ver:5 */
MQLONG LongMCAUserIdLength; // Length of long MCA user identifier
MQLONG LongRemoteUserIdLength; // Length of long remote user identifier
MQPTR LongMCAUserIdPtr; // Address of long MCA user identifier
MQPTR LongRemoteUserIdPtr; // Address of long remote user identifier
MQBYTE40 MCASecurityId; // MCA security identifier
MQBYTE40 RemoteSecurityId; // Remote security identifier
/* Ver:6 */
MQCHAR SSLCipherSpec[32]; // SSL CipherSpec
MQPTR SSLPeerNamePtr; // Address of SSL peer name
MQLONG SSLPeerNameLength; // Length of SSL peer name
MQLONG SSLClientAuth; // Whether SSL client authentication is required
MQLONG KeepAliveInterval; // Keepalive interval
MQCHAR LocalAddress[48]; // Local communications address
MQLONG BatchHeartbeat; // Batch heartbeat interval
/* Ver:7 */
MQLONG HdrCompList[2]; // Header data compression list
MQLONG MsgCompList[16]; // Message data compression list
MQLONG CLWLChannelRank; // Channel rank
MQLONG CLWLChannelPriority; // Channel priority
MQLONG CLWLChannelWeight; // Channel weight
MQLONG ChannelMonitoring; // Channel monitoring
MQLONG ChannelStatistics; // Channel statistics
/* Ver:8 */
MQLONG SharingConversations; // Limit on sharing conversations
MQLONG PropertyControl; // Message property control
MQLONG MaxInstances; // Limit on SVRCONN channel instances
MQLONG MaxInstancesPerClient; // Limit on SVRCONN channel instances per client
MQLONG ClientChannelWeight; // Client channel weight
MQLONG ConnectionAffinity; // Connection affinity
/* Ver:9 */
} ;
MQCNO = Client Connection
struct tagMQCNO {
MQCHAR4 StrucId; /* Structure identifier */
MQLONG Version; /* Structure version number */
MQLONG Options; /* Options that control the action of MQCONNX */
/* Ver:1 */
MQLONG ClientConnOffset; /* Offset of MQCD structure for client connection */
MQPTR ClientConnPtr; /* Address of MQCD structure for client connection */
/* Ver:2 */
MQBYTE128 ConnTag; /* Queue-manager connection tag */
/* Ver:3 */
PMQSCO SSLConfigPtr; /* Address of MQSCO structure for client connection */
MQLONG SSLConfigOffset; /* Offset of MQSCO structure for client connection */
/* Ver:4 */
MQBYTE24 ConnectionId; /* Unique Connection Identifier */
MQLONG SecurityParmsOffset; /* Offset of MQCSP structure */
PMQCSP SecurityParmsPtr; /* Address of MQCSP structure */
/* Ver:5 */
} ;
MQCB
what is it ?
MQCB feature is introduced in section 6.4 of IBM Redbook "WebSphere MQ V7.0 New Features and Enhancements".
func( QueueArray[] )
{
MQCONN(QMName, &Hcon, &CompCode, &CReason);
for(number of queues in QueueArray[])
{
od,Queuename = QueueArray[index];
MQOPEN(Hcon, &od, O_options, &Hobj, &OpenCode, &Reason);
MQCB(Hcon, MQOP_REGISTER, &cbd, Hobj, &md, &gmo, &CompCode, &Reason);
}
MQCTL(Hcon, [color=red]MQOP_START_WAIT[/color], &ctlo, &CompCode, &Reason);
MQDSIC(&Hcon, &CompCode, &Reason);
}
main()
{
CreateThread(func[INQ1,INQ2,INQ3]);
CreateThread(func[INQ4,INQ5,INQ6]);
CreateThread(func[INQ7,INQ8,INQ9]);
etc.....
WaitForUserInputToEndProgram();
}
===
Code:
void MessageConsumer(MQHCONN hConn,
MQMD * pMsgDesc,
MQGMO * pGetMsgOpts,
MQBYTE * Buffer,
MQCBC * pContext)
{
MQLONG i,max;
MQLONG Length;
printf(" From MessageConsumer\n ");
switch(pContext->CallType)
{
case MQCBCT_MSG_REMOVED:
case MQCBCT_MSG_NOT_REMOVED:
max = pGetMsgOpts -> ReturnedLength;
if (max > 200) max = 200;
for (i=0; i < max; i++)
{
if (isprint(Buffer[i])) fputc(Buffer[i],stdout);
else fputc('.',stdout);
}
fputc('\n',stdout);
///sleep(10);
break;
}
}
What is the way to find the name of the MessageQueue from which we received the messages using MQCB?
pGetMsgOpts -> ResolvedQName
amqscbf0.c : sample C program that gets messages from a message queue using MQCB.
Initial values for dynamic structures
When a variable number of instances of a structure is required,
the instances are usually created in main storage obtained dynamically using the calloc or malloc functions.
To initialize the fields in such structures, the following technique is recommended:
-
declare an instance of the structure using the appropriate MQxxx_DEFAULT macro variable to initialize the structure.
This instance becomes the "model" for other instances:
MQMD Model = {MQMD_DEFAULT}; /* declare model instance */
The static or auto keywords can be coded on the declaration in order to give the model instance static or dynamic lifetime, as required.
-
use the calloc or malloc functions to obtain storage for a dynamic instance of the structure:
PMQMD Instance;
Instance = malloc(sizeof(MQMD)); /* get storage for dynamic instance */
-
use the memcpy function to copy the model instance to the dynamic instance:
memcpy( Instance, & Model, sizeof( MQMD ) ) ; /* initialize dynamic instance */
doc
MQ Administration
As MQAI
it is likely to be formally deprecated in a future release of MQ,
we shall use PCF's.
PCF commands
We put PCF command messages
(md.Format:=MQFMT_ADMIN)
into the queue manager's SYSTEM.ADMIN.COMMAND.QUEUE
and wait for a response on the "ReplyTo" queue.
Sample : the Cluster Queue Monitoring sample program (v8) -
AMQSCLM
MQAI = MQ Administration Interface
The MQAI is a programming interface to WebSphere MQ.
It performs administration tasks on a MQ queue manager.
2014, nov : the MQAI is planning on being deprecated in the near future
Configure MQ using mqExecute()
AMQSAICQ.C : sample to create a queue
sending an administration command MQCMD_CREATE_Q to the command server,
writing a PCF message into SYSTEM.ADMIN.COMMAND.QUEUE.
Configuring MQ using mqExecute.
display qstatus(SYSTEM.ADMIN.COMMAND.QUEUE) type(handle) all
1 : display qstatus(SYSTEM.ADMIN.COMMAND.QUEUE) type(handle) all
AMQ8450: Display queue status details.
QUEUE(SYSTEM.ADMIN.COMMAND.QUEUE) TYPE(HANDLE)
APPLTAG(30\eclipse\jre\bin\javaw.exe) APPLTYPE(USER)
BROWSE(NO) CHANNEL( )
CONNAME( ) HSTATE(INACTIVE)
INPUT(NO) INQUIRE(NO)
OUTPUT(YES) PID(2808)
QMURID(0.0) SET(NO)
TID(*)
URID(XA_FORMATID[00000000] XA_GTRID[] XA_BQUAL[])
URTYPE(QMGR) USERID(wbrkadm@NewName)
AMQ8450: Display queue status details.
QUEUE(SYSTEM.ADMIN.COMMAND.QUEUE) TYPE(HANDLE)
APPLTAG(ebSphere MQ\bin\amqpcsea.exe) APPLTYPE(SYSTEM)
BROWSE(NO) CHANNEL( )
CONNAME( ) HSTATE(ACTIVE)
INPUT(EXCL) INQUIRE(YES)
OUTPUT(NO) PID(2696)
QMURID(0.0) SET(NO)
TID(1)
URID(XA_FORMATID[00000000] XA_GTRID[] XA_BQUAL[])
URTYPE(QMGR)
MQ code samples
-
Sample MQ programs (publib v6),
v8,
[*****]
-
JCT - 60 samples (C, Java, WF) -
local at "\\MQ\Codi\Samples IBM"
( Also at "\\CPP\MQI\Internet\CapitalWare\www.capitalware.biz\dl\code\c" )
The 50 code samples provided by MQ v 7.5 at <mq>\tools\c\samples\ are
103.463 amqsact0.c retrieve activity trace and write formatted data
27.000 amqsaem0.c API exit that manipulates message properties
24.042 amqsaicl.c (not al Linux)
20.249 amqsaicq.c create a local queue using MQAI (MQCMD_CREATE_Q) PCF command
34.958 amqsaiem.c basic event monitor using MQAI.
20.972 amqsailq.c inquire the current depth of all local queues using MQAI (MQCMD_INQUIRE_Q) PCF command
17.828 amqsapt0.c asynchronously puts messages to a message queue using MQPUT and MQSTAT
208.828 amqsaxe0.c sample ApiExit which traces MQAPI calls
38.110 amqsbcg0.c read and output both the message descriptor fields and the message content of all the messages on a queue.
56.623 amqsblst.c simple MQ bandwidth and connectivity tester.
20.577 amqscbf0.c get messages from a message queue using MQCB
193.996 amqsclma.c cmqcfc.h Active Cluster Queue Message Distribution Service
23.645 amqscnxc.c how to specify client connection information on MQCONNX
20.022 amqsecha.c echo messages to reply to queue
44.649 amqsfhac.c put and get messages under syncpoint using a reconnectable connection
16.768 amqsgbr0.c displays messages on a queue (using Browse option of MQGET)
17.245 amqsget0.c gets messages from a message queue (using MQGET)
17.288 amqsghac.c get messages from a message queue using a reconnectable connection (high available client)
18.898 amqsgrma.c gets reference messages from a specified queue
26.446 amqsinqa.c inquires selected attributes of a queue, using MQINQ; starts triggered, sends results to ReplyToQ
18.439 amqsiqma.c inquiry properties of a message handle, using MQINQMP
31.156 amqsldpc.c (no Linux) query an LDAP directory and put messages to a queue (MQPUT)
15.163 amqslog0.c monitor the logger event queue and display formatted content
23.228 amqsmhac.c transfer messages from one queue to another using a reconnectable connection
100.479 amqsmon0.c get an accounting message from the specified queue and writes the formatted data to standard output
19.046 amqsphac.c put messages to a queue using a reconnectable connection (high available client)
42.453 amqsprma.c create a reference message, referring to a file, and put it to a queue
64.163 amqspse0.c publish exit
24.460 amqsptl0.c put messages to a list of queues (using MQPUT and lists)
15.013 amqspuba.c publish messages on a topic using MQPUT
16.685 amqsput0.c put messages to a message queue (using MQPUT)
99.991 amqsqrma.c channel message exit that processes reference messages
22.267 amqsreq0.c put request messages to a message queue and shows the replies (using REPLY queue)
52.614 amqssbxa.c subscribe and get messages from a topic
25.509 amqsseta.c inhibits PUTs to a message queue (using MQSET). Must run as a triggered program, and so receives input in a trigger parameter
52.527 amqsspin.c (no Linux) SSPI Channel exit routines for MQ
36.070 amqssslc.c demo how to use MQCNO and MQSCO to supply SSL/TLS client connection information on the MQCONNX call
21.195 amqsstma.c set properties of a message handle (using MQSETMP) and put it to a message queue
29.058 amqsstop.c issues a STOP CONN request to the command server for all connections for the specified process
17.367 amqssuba.c subscribe and get messages from a topic (using MQSUB)
17.336 amqstrg0.c acts as a trigger monitor
14.959 amqstxgx.c Get transaction for Tuxedo
14.902 amqstxpx.c Put transaction for Tuxedo
12.221 amqstxsx.c sample Server for Tuxedo
12.223 amqsvfc0.c skeleton of a Data Conversion exit
9.256 amqswlm0.c CLWL exit that chooses a destination queue manager
amqsxae0.c (oldie) sample Encina program.
79.588 amqsxrma.c channel message exit that processes reference messages
24.193 amquregn.c (no Linux) dumps the MQ values in the Registry to the console
11.231 amqzscgn.c CICS GLobal User Exit (GLUE)
14.998 amqzscin.c (no Linux) XA switch program for CICS XA Initialisation
9.859 amqzscix.c XA Initiation for CICS
On the
web
Compilació
xlc_r -L/usr/mqm/lib -lmqm -o amsailq amsailq.c
cc -q64 -L/usr/mqm/lib64 -lmqm -o amsailq amsailq.c
gcc -o wlg wlg.c -I/opt/mqm/inc -lmqm_r
Guindous
$ type CO.CMD
@echo off
if .%1. == .'?'. goto ajuda
echo "1 - posar entorn del Visual Studio."
CALL "c:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
echo CMQC.H must be found using ... ?
SET FN="amqsaicq"
echo Esborrar fitxers vells
del %FN%.obj
del %FN%.exe
echo SERVER(%FN%) :
CL %FN%.c -o %FN%.exe mqm.lib
echo CLIENT(%FN%) :
CL %FN%.c -o %FN%c.exe mqic32.lib // or c:\MQ\tools\Lib64\mqic.lib
dir *.EXE
goto fi
: =============================================================================
:ajuda
echo CO == compilar %FN%.c
echo Sortida = %FN%.exe + %FN%c.exe
:fi
Si hem de ser mes explicits, hem de posar :
CALL "c:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
CL /I"C:\Program Files\IBM\WebSphere MQ\Tools\c\include" BWMI.c -o BWMIS.exe "c:\Program Files\IBM\WebSphere MQ\Tools\Lib\mqm.lib"
CL /I"C:\Program Files\IBM\WebSphere MQ\Tools\c\include" BWMI.c -o BWMIC.exe "c:\Program Files\IBM\WebSphere MQ\Tools\Lib\mqic32.lib"
Linux
Detailed samples
here.
sebas@p7029-6E3:~/eines/qnr> cat co.sh
#!/bin/bash
clear
FN=myput
FNC=$FN".c"
echo "Compilem" $FN
gcc -o $FN $FNC -I/opt/mqm/inc -lmqm_r
Queue Name Resolution
See \\MQ\eines\AMQSPUT_modificat
hCon := MQCONN ( QM_name_Connect ) ; // connect to some queue manager
od.ObjectName := Queue_name ; // set queue we want to write into (may be remote)
od.ObjectQMgrName, := QM_name_Open ; // set queue manager where the queue is located (my be remote)
hObj := MQOPEN ( hCon, & od, Open_Options ) ; // open queue to write
MQPUT ( hCon, hObj, & md, & pmo, lng, ptr ) ; // write msg into (remote) queue
Creació d'una cua
Detalls AMQSAICQ
MQOPEN - 'SYSTEM.ADMIN.COMMAND.QUEUE'
****Message descriptor****
StrucId : 'MD ' Version : 2
Report : 0 MsgType : 1
Expiry : 237 Feedback : 0
Encoding : 546 CodedCharSetId : 437
Format : 'MQADMIN '
Priority : 0 Persistence : 0
Crear una cua dinamica amb MQ_OPEN()
Use a dynamic queue when you do not need the queue after your application ends.
See amqsreq0.c sample,
and documentation :
creating dynamic queues
You can specify the name of the dynamic queue that you create
- completely
Give the full name that you want in the DynamicQName field of the MQOD structure
- providing a prefix
The form is "prefix*" - specify an asterisk (*) for the last non-blank character of the DynamicQName field
- let the qmgr to generate it
Specify an asterisk (*) in the first character position of the DynamicQName field
Code resum:
MQ API and Visual Studio
The default code is like this:
#define MaxMsgLng 100
MQBYTE messsage_buffer [ MaxMsgLng ] ;
buflen = sizeof( messsage_buffer ) - 1 ;
This way of coding means that the buffer variable is defined on the stack.
The default stack size for a Visual Studio program is only 1MB,
so changing MaxMsgLng to 1024*1024*4 does produce a run-time error.
The correct coding is this one:
#define MaxMsgSize 1024*1024*4
char * messsage_buffer ;
messsage_buffer = malloc( MaxMsgSize ) ;
buflen = MaxMsgSize - 1 ;
Thanks, PaulClarke at
mqseries.net
I'd say this way also works :
#define MaxMsgSize 1024*1024
MQBYTE buffer [ MaxMsgSize ] ; // message buffer in heap ?
int main ( int argc, char ** argv )
{
MQ API trace
See details
here
MQ_Connect()
.
MQ_Inquiry()
.
MA0W
MA0W !
amqsaxe0.c - sample ApiExit which traces MQAPI calls.
The
MA0W SupportPac is a trace exit.
This trace has extremely fine control and you can enable it for a single PID, for specific queues or channels, etc.
It will give you API timings so you will be able to see whether the time is being spent between API calls or in the API call itself.
In other words, did the program wait 10 seconds between API calls or did the GET take 10 seconds to complete?
If you are getting messages rolled back due to filling the transaction log and then re-read this can cause delays that are pretty transparent unless you have a trace.
Compilació d'una Exit = crear un module (=DLL)
#!/usr/bin/ksh
FNO=amqsaxe0
FNR=amqsaxe0_r
NFC=../eines_src/amqsaxe0.c
rm /var/mqm/exits/amqsaxe0
rm /var/mqm/exits/amqsaxe0_r
rm /var/mqm/exits64/amqsaxe0
rm /var/mqm/exits64/amqsaxe0_r
echo "Anem a compilar la Exit ... " $NFC ", sortida " $FNO
xlc -q32 -e MQStart -bE:amqsaxe0.exp -bM:SRE -L/usr/mqm/lib -lmqm -lmqmzf -o $FNO $NFC
cp $FNO /var/mqm/exits
xlc_r -q32 -e MQStart -bE:amqsaxe0.exp -bM:SRE -L/usr/mqm/lib -lmqm_r -lmqmzf_r -o $FNR $NFC
cp $FNR /var/mqm/exits
xlc -q64 -e MQStart -bE:amqsaxe0.exp -bM:SRE -L/usr/mqm/lib64 -lmqm -lmqmzf -o $FNO $NFC
cp $FNO /var/mqm/exits64
xlc_r -q64 -e MQStart -bE:amqsaxe0.exp -bM:SRE -L/usr/mqm/lib64 -lmqm_r -lmqmzf_r -o $FNR $NFC
cp $FNR /var/mqm/exits64
ls -al /var/mqm/exits
ls -al /var/mqm/exits64
echo "Fi."
I el fitxer "amqsaxe0.exp" conté :
**************************************************************************
* Module Name: mirrorq.exp *
* Description: library export file for mirrorq *
**************************************************************************
MQStart
EntryPoint
Configuració de la Exit que fa trassa de la API de MQ
Edit qm.ini file :
/* ApiExitLocal: */
/* Name=SampleApiExit */
/* Sequence=100 */
/* Function=EntryPoint */
/* Module=<Module> */
/* */
/* ... where the <Module> is */
/* AIX: /usr/mqm/samp/bin/amqsaxe */
/* Other UNIXs: /opt/mqm/samp/bin/amqsaxe */
Make sure the directory "/var/mqm/trace" exists
and export the following environment variable
"export MQAPI_TRACE_LOGFILE=/var/mqm/trace/ApiTrace"
MQ at C sharp
MA7P - gone at Oct 2007.
http://www.codeproject.com/csharp/csharpmq.asp
Code sample (on-line)
Using .Net :
GC34-6605-01
Capitalware C#.
( Also at "\\CPP\MQI\Internet\CapitalWare\www.capitalware.biz\dl\code\csharp" )
MQ entry points
Using DUMPBIN.exe (from VisualStudio)
on either MQM.DLL (server) or MQIC32.DLL (client),
shows those entry points :
1 0 00001ED0 MQBACK
2 1 00001FA0 MQBACKstd@12
3 2 00001FC0 MQBEGIN
4 3 000020A0 MQBEGINstd@16
5 4 00001630 MQCLOSE
6 5 00001750 MQCLOSEstd@20
7 6 00001DE0 MQCMIT
8 7 00001EB0 MQCMITstd@12
9 8 00001000 MQCONN
10 9 00001100 MQCONNX
11 A 000011E0 MQCONNXstd@20
12 B 000010E0 MQCONNstd@16
13 C 000013F0 MQDISC
14 D 000013D0 MQDISCstd@12
15 E 00001780 MQGET
16 F 00001870 MQGETstd@36
17 10 00001B80 MQINQ
18 11 00001C70 MQINQstd@40
19 12 000014C0 MQOPEN
20 13 00001600 MQOPENstd@24
21 14 000018B0 MQPUT
22 15 00001A50 MQPUT1
23 16 00001B40 MQPUT1std@32
24 17 00001A10 MQPUTstd@32
25 18 00001CB0 MQSET
26 19 00001DA0 MQSETstd@40
27 1A 00002460 mqAddInquiry
28 1B 00002480 mqAddInquirystd@16
29 1C 00002280 mqAddInteger
30 1D 000022B0 mqAddIntegerstd@20
31 1E 00002140 mqAddString
32 1F 00002170 mqAddStringstd@24
33 20 00002780 mqBagToBuffer
34 21 000027B0 mqBagToBufferstd@28
35 22 00002720 mqBufferToBag
36 23 00002750 mqBufferToBagstd@24
37 24 00002500 mqClearBag
38 25 00002520 mqClearBagstd@12
39 26 00002580 mqCountItems
40 27 000025B0 mqCountItemsstd@20
41 28 000020C0 mqCreateBag
42 29 000020E0 mqCreateBagstd@16
43 2A 00002100 mqDeleteBag
44 2B 00002120 mqDeleteBagstd@12
45 2C 000024A0 mqDeleteItem
46 2D 000024D0 mqDeleteItemstd@20
47 2E 000025E0 mqExecute
48 2F 00002620 mqExecutestd@36
49 30 000026C0 mqGetBag
50 31 000026F0 mqGetBagstd@28
51 32 000023A0 mqInquireBag
52 33 000023D0 mqInquireBagstd@24
53 34 00002340 mqInquireInteger
54 35 00002370 mqInquireIntegerstd@24
55 36 00002400 mqInquireItemInfo
56 37 00002430 mqInquireItemInfostd@28
57 38 00002200 mqInquireString
58 39 00002240 mqInquireStringstd@36
59 3A 000027E0 mqPad
60 3B 00002810 mqPadstd@20
61 3C 00002660 mqPutBag
62 3D 00002690 mqPutBagstd@28
63 3E 000022E0 mqSetInteger
64 3F 00002310 mqSetIntegerstd@24
65 40 000021A0 mqSetString
66 41 000021D0 mqSetStringstd@28
67 42 00002840 mqTrim
68 43 00002870 mqTrimstd@20
69 44 00002540 mqTruncateBag
70 45 00002560 mqTruncateBagstd@16
71 46 00001210 zrtMQCONN
72 47 000012F0 zrtMQCONNX
So, we have 36 entry points in total, of which :
- 13 are related to CMQC.H
- 22 are related to CMQBC.H
- 1 is unknown : zrtMQCONN(X)
13 :
MQCONN(), MQCONNX(), MQDISC(), MQOPEN(), MQCLOSE(),
MQPUT(), MQGET(), MQPUT1(), MQINQ(), MQSET(),
MQBEGIN(), MQBACK(), MQCMIT().
Llibre amb la lògica i els detalls de
mqExecute(),
mqPad(),
mqTrim(),
etc ?
>
>
>
MQ_v6.0_PCF and Administration Interface_SC34-6598-00_csqzac04.pdf
Definicions
#include <cmqc.h> /* MQI */
#include <cmqcfc.h> /* PCF */
#include <cmqbc.h> /* MQAI */
Compilem aixi:
c:\"Program Files (x86)"\Dev-Cpp\MinGW64\bin\gcc nom.c -I"c:\mq\tools\c\include" -L"c:\mq\tools\Lib\mqm.lib" -o nom.exe
c:\"Program Files (x86)"\Dev-Cpp\MinGW64\bin\gcc nom.c -I"c:\mq\tools\c\include" -L"c:\mq\tools\Lib\mqic32.lib" -o nomc.exe
Foro dev-c++
ICMP.DLL entry points
Internet Control Message Protocol
- IcmpSendEcho()
- IcmpCreateFile()
- register_icmp()
- IcmpCloseHandle()
- DllMain()
url
Windows Service
c:\Program Files\IBM\WebSphere MQ\bin> sc query MQSeriesServices
SERVICE_NAME: MQSeriesServices
TYPE : 10 WIN32_OWN_PROCESS
STATE : 4 RUNNING
(STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
c:\Program Files\IBM\WebSphere MQ\bin> sc qc MQSeriesServices
[SC] GetServiceConfig SUCCESS
SERVICE_NAME: MQSeriesServices
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 0 IGNORE
BINARY_PATH_NAME : "C:\Program Files\IBM\WebSphere MQ\bin\amqsvc.exe"
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : IBM MQSeries
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
API (call) list, up to 25+
- MQCONN()
Languages list
- C
- C++
- C# .Net
- VB .Net
- COBOL
- RPG
- PL/1
- Java
- JMS
- XMS - replaced by "Message Service Client for .NET"
- SOAP
- z/OS / CICS
- perl
- python
- guindous PowerShell :
MO74,
MQ - Windows Powershell Library
use PYTHON to access MQ
There are 3 API's.
gefira
PyMQI
v 1.3
import pymqi
queue_manager = 'QM01'
channel = 'SVRCONN.1'
host = '192.168.1.135'
port = '1434'
queue_name = 'TEST.1'
message = 'Hello from Python!'
conn_info = '{}({})'.format(host, port)
qmgr = pymqi.connect(queue_manager, channel, conn_info)
queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()
qmgr.disconnect()
MyMQI
examples [*****]
Spring Python
Zato
My API errors / dubtes
- Delphi + MQ_Inq() queue manager name.
Va be
Va malament
- Delphi + MQ_Put1().
Va be
Va malament
- mq v 7.5 on RHEL v4, mqrc 2539 if qm.ini : MaxChannels=20000 ; mqconnX() rc = 2539
Síntomes :
AMQERR01.LOG - "AMQ6024: Insufficient resources are available to complete a system request"
, plus a FDC
Solució :
Configure kernel (for example, shmmax) to allow a shared memory segment of at least 33558528 bytes
Used in \\Delphi\MQAI