Author |
Message
|
martinrydman |
Posted: Sun May 29, 2005 5:01 am Post subject: Creating MQMD header from scratch |
|
|
 Centurion
Joined: 30 Jan 2004 Posts: 139 Location: Gothenburg, Sweden
|
Hi,
I'm on the lookout for some sample ESQL code to create a MQMD header withe the minimum fields set to create a message that can be successfully put to a queue and consumed by a subsequent flow. We have a Timer-node that triggers a flow at a set interval, and this flow needs to send a message to trig the actual thing we want to do (a HTTP request). It doesn't matter really what the message contain, as long as it can be used to trigger a requalr flow.
I realize there is a lot of docs describing this, but (as always) a working example would cut som serious corners!
Thanks in advance
/Martin |
|
Back to top |
|
 |
martinrydman |
Posted: Sun May 29, 2005 7:29 am Post subject: |
|
|
 Centurion
Joined: 30 Jan 2004 Posts: 139 Location: Gothenburg, Sweden
|
An update...
I took the trace of an existing message and tried the following:
Code: |
SET OutputRoot.MQMD.SourceQueue = '';
SET OutputRoot.MQMD.Transactional = TRUE;
SET OutputRoot.MQMD.Encoding = 546;
SET OutputRoot.MQMD.CodedCharSetId = 850;
SET OutputRoot.MQMD.Format = 'MQSTR ';
SET OutputRoot.MQMD.Version = 2;
SET OutputRoot.MQMD.Report = 0;
SET OutputRoot.MQMD.MsgType = 8;
SET OutputRoot.MQMD.Expiry = -1;
SET OutputRoot.MQMD.Feedback = 0;
SET OutputRoot.MQMD.Priority = 0;
SET OutputRoot.MQMD.Persistence = 0;
SET OutputRoot.MQMD.MsgId = X'000000000000000000000000000000000000000000000000';
SET OutputRoot.MQMD.CorrelId = X'100000000000000000000000000000000000000000000001';
SET OutputRoot.MQMD.BackoutCount = 0;
SET OutputRoot.MQMD.ReplyToQ = ' ';
SET OutputRoot.MQMD.ReplyToQMgr = ' ';
SET OutputRoot.MQMD.UserIdentifier = ' ';
SET OutputRoot.MQMD.AccountingToken = X'0000000000000000000000000000000000000000000000000000000000000000';
SET OutputRoot.MQMD.ApplIdentityData = ' ';
SET OutputRoot.MQMD.PutApplType = 0;
SET OutputRoot.MQMD.PutApplName = '';
SET OutputRoot.MQMD.PutDate = CURRENT_DATE;
SET OutputRoot.MQMD.PutTime = CURRENT_TIME;
SET OutputRoot.MQMD.ApplOriginData = ' ';
SET OutputRoot.MQMD.GroupId = X'000000000000000000000000000000000000000000000000';
SET OutputRoot.MQMD.MsgSeqNumber = 1;
SET OutputRoot.MQMD.Offset = 0;
SET OutputRoot.MQMD.MsgFlags = 0;
SET OutputRoot.MQMD.OriginalLength = -1; |
No matter what I try, the CorrelId field looses its value. I can debug inside the compute-node and see its value, but immediately after leaving the node, the CorrelId field has lost its value, and the MQOutput will report an error saying that the CorrelId field must be the correct length.
I'm obviously missing som technicality here. Anybody know what it might be?
/Martin |
|
Back to top |
|
 |
whiting |
Posted: Sun May 29, 2005 11:34 am Post subject: CorrelId |
|
|
Acolyte
Joined: 26 Mar 2002 Posts: 64 Location: Greenville, SC
|
I don't think a CorrelId is required. Have you tried without setting the CorrelId? I don't think a MsgId would be required either. Set the options in the MQOutput to create a new MsgId.
If either of those fields is provided, then I'm sure that they will have to be the proper length, but If you don't include them, then the MQOutput node will provide appropriate defaults.
//Bill |
|
Back to top |
|
 |
TonyD |
Posted: Sun May 29, 2005 3:01 pm Post subject: |
|
|
Knight
Joined: 15 May 2001 Posts: 540 Location: New Zealand
|
The single statement:
Code: |
SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID;
|
in a Compute node prior to an MQOutput is sufficient to initialise an MQMD; other MQMD fields, such as Format, Expiry, ReplyToQ and the Ids can be specified also, but only if specific values are required. |
|
Back to top |
|
 |
martinrydman |
Posted: Sun May 29, 2005 11:25 pm Post subject: |
|
|
 Centurion
Joined: 30 Jan 2004 Posts: 139 Location: Gothenburg, Sweden
|
Hi,
The MQMD_STRUC_ID thing does indeed populate a subset of the MQMD, but the CorrelId problem stubbornly persist. This is what a Trace produces right after the Compute node that uses the single statement:
Code: |
(0x01000000):Properties = (
(0x03000000):MessageSet = ''
(0x03000000):MessageType = ''
(0x03000000):MessageFormat = ''
(0x03000000):Encoding = 546
(0x03000000):CodedCharSetId = 0
(0x03000000):Transactional = FALSE
(0x03000000):Persistence = FALSE
(0x03000000):CreationTime = GMTTIMESTAMP '2005-05-30 07:23:08.661'
(0x03000000):ExpirationTime = -1
(0x03000000):Priority = 0
(0x03000000):ReplyIdentifier = X''
(0x03000000):ReplyProtocol = 'MQ'
(0x03000000):Topic = NULL
)
(0x01000000):MQMD = (
(0x03000000):StrucId = 'MD '
(0x03000000):Format = ''
(0x03000000):Encoding = 546
(0x03000000):CodedCharSetId = 0
(0x03000000):Transactional = FALSE
(0x03000000):Persistence = 0
(0x03000000):PutDate = DATE '2005-05-30'
(0x03000000):PutTime = GMTTIME '07:23:08.661'
(0x03000000):Expiry = -1
(0x03000000):Priority = 0
(0x03000000):CorrelId = X''
)
(0x01000010):XML = (
(0x01000000):timer = (
(0x01000000):interval = (
(0x02000000): = '10000'
)
(0x01000000):counter = (
(0x02000000): = '1'
)
)
)
)
|
Any ideas?
/Martin |
|
Back to top |
|
 |
TonyD |
Posted: Mon May 30, 2005 4:06 am Post subject: |
|
|
Knight
Joined: 15 May 2001 Posts: 540 Location: New Zealand
|
OK, but what does a trace after the MQOutput show?
A trace of a recent MQMD I generated with a StrucId and Format shows in a trace after the Compute only:
Code: |
)
(0x01000000):MQMD = (
(0x03000000):Version = 2
(0x03000000):StrucId = 'MD '
(0x03000000):Format = 'MQSTR '
)
|
The remaining, unspecified fields are populated, with defaults, when the message is actually written.
If you are setting MsgId or CorrelId you need to set them as blobs which probably accounts for your length problem, e.g:
Code: |
SET OutputRoot.MQMD.MsgId = CAST('41414141414141414142424242424242424343434343434343' AS BLOB)
|
:creates a 24-byte MsgId '11111111222222233333333'. However it appears that you actually do not care about the MsgId, CorrelId values so why bother to set them? |
|
Back to top |
|
 |
martinrydman |
Posted: Mon May 30, 2005 8:53 am Post subject: |
|
|
 Centurion
Joined: 30 Jan 2004 Posts: 139 Location: Gothenburg, Sweden
|
Hi,
the point is, I don't. This is the complete COMPUTE MODULE:
Code: |
CREATE COMPUTE MODULE VCC164_Scheduler_AddMQMD
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
CALL ConstructMQMD();
SET OutputRoot.XML = InputRoot.XML;
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
CREATE PROCEDURE ConstructMQMD() BEGIN
SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID;
END;
END MODULE;
|
The rest of the fields magically appear in the Trace immediately after the comute node. Odd, I think
/Martin |
|
Back to top |
|
 |
TonyD |
Posted: Mon May 30, 2005 2:51 pm Post subject: |
|
|
Knight
Joined: 15 May 2001 Posts: 540 Location: New Zealand
|
Try commenting out:
Code: |
-- CALL CopyMessageHeaders();
|
:as shown above. |
|
Back to top |
|
 |
EddieA |
Posted: Mon May 30, 2005 3:04 pm Post subject: |
|
|
 Jedi
Joined: 28 Jun 2001 Posts: 2453 Location: Los Angeles
|
TonyD wrote: |
Try commenting out:
Code: |
-- CALL CopyMessageHeaders();
|
:as shown above. |
Then he'll have no Properties folder.
Cheers, _________________ Eddie Atherton
IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Message Broker V7.0 |
|
Back to top |
|
 |
TonyD |
Posted: Mon May 30, 2005 4:37 pm Post subject: |
|
|
Knight
Joined: 15 May 2001 Posts: 540 Location: New Zealand
|
Quote: |
Then he'll have no Properties folder.
|
My mistake!...however, what I was getting at is that the MessageHeader folders, including an MQMD, are being copied from earlier in the flow.
How about:
Code: |
CREATE COMPUTE MODULE VCC164_Scheduler_AddMQMD
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
-- CALL CopyMessageHeaders();
SET OutputRoot.Properties = InputRoot.Properties;
CALL ConstructMQMD();
SET OutputRoot.XML = InputRoot.XML;
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
CREATE PROCEDURE ConstructMQMD() BEGIN
SET OutputRoot.MQMD.StrucId = MQMD_STRUC_ID;
END;
END MODULE;
|
|
|
Back to top |
|
 |
zpat |
Posted: Mon May 30, 2005 11:00 pm Post subject: |
|
|
 Jedi Council
Joined: 19 May 2001 Posts: 5866 Location: UK
|
The only MQMD fields that I would worry about setting (as opposed to allowing to default) would be the format and persistence. |
|
Back to top |
|
 |
ydsk |
Posted: Tue May 31, 2005 7:39 am Post subject: |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
Also the CCSID and Encoding fields in the MQMD need to be set appropriately...if the output message is going to a different platform than the one the broker is running on. |
|
Back to top |
|
 |
voodoo123 |
Posted: Tue Aug 29, 2006 11:13 pm Post subject: |
|
|
Newbie
Joined: 14 Aug 2006 Posts: 5
|
SET OutputRoot.Properties.ReplyIdentifier = MQMI_NONE;
SET OutputRoot.MQMD.CorrelId = MQMI_NONE;
Try this
This will work |
|
Back to top |
|
 |
ak |
Posted: Thu Aug 31, 2006 3:12 am Post subject: Creating MQMD header from scratch |
|
|
Apprentice
Joined: 07 Aug 2006 Posts: 48 Location: England
|
This seems to work for us
SET OutputRoot.MQMD.CorrelId = CAST(x'484846584D4C434C49454E54202020202020202020202020' AS BLOB); |
|
Back to top |
|
 |
ulisesmartins |
Posted: Fri Sep 01, 2006 9:36 pm Post subject: |
|
|
Newbie
Joined: 21 Jul 2004 Posts: 5 Location: Bs.As. Argentina
|
We have the same problem, the work around we found is to copy the entire message first:
SET OutputRoot=InputRoot
Then we set the CorrelId... |
|
Back to top |
|
 |
|