Author |
Message
|
JohnSmith |
Posted: Tue May 04, 2010 6:22 am Post subject: JMS msgId and correlId trouble in WMB |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
fjb_saper wrote:
Quote: |
This is going to be sooo easy. Be creative.
retrieve the message id , set the correlation id, retrieve the correlID as bytes.
Set the bytes:
JMS part
msgID = inmsg.getJMSMessageID();
dummymsg.setJMSCorrelationID() = msgID;
byte[24] mqmsgid = dummymsg.getCorrelationIDAsBytes();
Now you can use the bytearray to set the correlID on the mq message...
However you should:
first check the JMSCorrelationID for "ID:" + String.replicate("0",48 );
(initial value or something like JMSC.MQID_NONE or MQSC.MQID_NONE...
If this is the value go ahead and move the msgid to the correlId
if the correlID has already a non initial value, it should be "passthrough" |
Hi fjb_saper,
I am trying to do something similar,seehttp://www.mqseries.net/phpBB2/viewtopic.php?t=44866
I am using a JMSOutputNode to write into a MQ queue, now once its write into the queue, then in the "WrittenDestination.JMS.DestinationData.JMSCorrelationID" I am getting the JMS CorrelationID whose value is "39376236616335312d633462372d343333362d396637382d" whereas when I look into the MQ Message correlation ID it is showing as "333933373632333636313633333533313264363333343632" in HEX and showing in ASCII as "39376236616335312d633462". If you see this ASCII value is equal to first 24 chars of JMS CorrelationID. But, how do I convert the JMSCorrelationID into MQ CorrelationID(showing as 48 chars means 24BYTE[]) so that can use MQ Get options later to get the reply.
I am using ESQL to implement the same and the message broker version is 6.1. |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue May 04, 2010 1:55 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
As Jeff said show your ESQL.
However know this of the MQ JMS implementation: the correlationID is stored in the RFH header.
If the correlationId is <= byte[24] then the correlationID will be copied into a byte [24] padded with [0x00] and also be put into the MDMD.
If the correlationId is > byte[24] the first 24 bytes are put the MQMD. This can make for non unique correlId if you are setting the value and not taking this rule into account.
WrittenDestination.JMS.DestinationData.JMSCorrelationID is the right place to get the correlationId for an outgoing message. Did you set the correlationId on the message?? I would expect that you would need to retrieve/match it from an incoming message??
Quote: |
how do I convert the JMSCorrelationID into MQ CorrelationID |
This is the same as asking how do I convert between different formats...
So what you have is a ??? as JMSCorrelationId from the JMS node...
What you need is a byte[24] => 24 byte long BLOB to set on the MQMD.
Be aware that depending on the pattern you are using you could entirely let the broker generate all this for MQ.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
JohnSmith |
Posted: Tue May 04, 2010 4:30 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
Following is the ESQL code I am using, I try to use a JAVA function so that I can convert char into a HEX value.
Quote: |
CREATE COMPUTE MODULE Test2_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputLocalEnvironment = InputLocalEnvironment;
SET OutputRoot = InputRoot;
DECLARE jms_cor_id BLOB SUBSTRING(Environment.Variable.JMS_Cor_Id FROM 1 FOR 12);
DECLARE jms_cor_id_str CHAR GET_HEX_STR(jms_cor_id);
SET OutputRoot.MQMD.CorrelId = CAST(jms_cor_id_str AS BLOB);
-- CALL CopyEntireMessage();
RETURN TRUE;
END; |
In the above I am passing the JMS correlation ID into a Java function, below is the JAVA function code -
Quote: |
public class Test {
public static String dumpHexId(byte[] myId) {
String hexAscii = "";
for (int i=0; i < myId.length;i++) {
char b = (char)(myId[i] & 0xFF);
if (b < 0x10) {
hexAscii = hexAscii + "0";
}
hexAscii = hexAscii + (String)(Integer.toHexString(b)).toUpperCase();
}
return hexAscii;
} |
but the above is not producing the correct result. |
|
Back to top |
|
 |
JohnSmith |
Posted: Tue May 04, 2010 8:29 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
Quote: |
CREATE COMPUTE MODULE Test2_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputLocalEnvironment = InputLocalEnvironment;
SET OutputRoot = InputRoot;
DECLARE jms_cor_id BLOB SUBSTRING(Environment.Variable.JMS_Cor_Id FROM 1 FOR 12);
DECLARE jms_cor_id_str CHAR GET_HEX_STR(jms_cor_id);
SET OutputRoot.MQMD.CorrelId = CAST(jms_cor_id_str AS BLOB);
-- CALL CopyEntireMessage();
RETURN TRUE;
END;
In the above I am passing the JMS correlation ID into a Java function, below is the JAVA function code -
Quote:
public class Test {
public static String dumpHexId(byte[] myId) {
String hexAscii = "";
for (int i=0; i < myId.length;i++) {
char b = (char)(myId[i] & 0xFF);
if (b < 0x10) {
hexAscii = hexAscii + "0";
}
hexAscii = hexAscii + (String)(Integer.toHexString(b)).toUpperCase();
}
return hexAscii;
}
|
Changed the above code and now it is working, earlier I was passing the correlation ID as a BLOB value to the function, now instead of passing BLOB I passed CHAR and then tested, it is working fine now.
Wish could have done the same in esql, without using a JAVA function.
Below code is working fine
Quote: |
BEGIN
SET OutputLocalEnvironment = InputLocalEnvironment;
SET OutputRoot = InputRoot;
DECLARE jms_cor_id CHAR SUBSTRING(InputLocalEnvironment.WrittenDestination.JMS.DestinationData.JMSCorrelationID FROM 1 FOR 24);
DECLARE jms_cor_id_str CHAR GET_HEX_STR(jms_cor_id);
SET OutputRoot.MQMD.CorrelId = CAST(jms_cor_id_str AS BLOB);
RETURN TRUE;
END; |
Quote: |
public static String stringToHexId(String str) {
byte[] myId = str.getBytes();
String hexAscii = "";
for (int i=0; i < myId.length;i++) {
char b = (char)(myId[i] & 0xFF);
if (b < 0x10) {
hexAscii = hexAscii + "0";
}
hexAscii = hexAscii + (String)(Integer.toHexString(b)).toUpperCase();
}
return hexAscii;
} |
|
|
Back to top |
|
 |
mqjeff |
Posted: Wed May 05, 2010 2:22 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
If you cast a BLOB value to a CHAR value *without* specifying a CCSID, you will get a string like you want, without needing to call a java function.
It will have some extra characters, some quotes and etc. So it will need some additional substringing.
I suspect you're still going the long way around to set the ID. |
|
Back to top |
|
 |
JohnSmith |
Posted: Wed May 05, 2010 5:57 am Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
mqjeff wrote:
Quote: |
If you cast a BLOB value to a CHAR value *without* specifying a CCSID, you will get a string like you want, without needing to call a java function.
It will have some extra characters, some quotes and etc. So it will need some additional substringing.
|
Hi Jeff, I will try the same and let you know. |
|
Back to top |
|
 |
JohnSmith |
Posted: Wed May 19, 2010 8:20 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
After running our application smoothly in SIT environment for few days with the message flow designed using JMSOuput Node and JMSInput Node, we got stuck again while moving to UAT.
Problem start because of our design, which is something like
1. Use JMSOuput node to put a message into the queue.
2. Run a flow in parallel which will use the JMSInput node to pick up the response and pass it to our main flow, in the main flow we will check the JMS correlation and compare it and construct the response to send back to the calling application.
Now when we moved to UAT environment, it turns out that the backend application is sharing the queue for both environments.
So we have to figure our a way to run the testing in both SIT/UAT in parallel, which doesnt seems possible with the above design.
One way I can see here is dont pick up the message from the queue, first only browse and check if correlation ID match then pick the message. so that if that message belongs to UAT, then SIT wouldnt not accidentally picked it up.
But, this feature is only available in MQGET node and we are using JMSInput node to retreive the message, which picks each and every msg coming into the queue.
Is there any way to workaround on this? I need all the experts advice here.
thanks |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu May 20, 2010 1:24 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Put a selector on the JMSInput node. It will check for matching correlId.
You may have to do that by passing the selector to the LocalEnvironment...
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
JohnSmith |
Posted: Thu May 20, 2010 4:54 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
fjb_saper
Quote: |
Put a selector on the JMSInput node. It will check for matching correlId.
You may have to do that by passing the selector to the LocalEnvironment... |
thanks Jeff, I will try that and will let you know whether it really works  |
|
Back to top |
|
 |
JohnSmith |
Posted: Thu May 20, 2010 6:07 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
fjb_saper
Quote: |
Put a selector on the JMSInput node. It will check for matching correlId.
You may have to do that by passing the selector to the LocalEnvironment... |
Got a problem at the very beginning , as JMSINput node MUST be the first node in any message flow, how we are going to set the LocalEnvironmentVariabale.CorrelationID property dynamically in the JMS Selector? |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu May 20, 2010 7:27 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
JohnSmith wrote: |
Got a problem at the very beginning , as JMSINput node MUST be the first node in any message flow, how we are going to set the LocalEnvironmentVariabale.CorrelationID property dynamically in the JMS Selector? |
I was thinking here at using the JMSInput node with selector as the equivalent of a JMSGetNode. What I don't get is why it must be the first node in your message flow... Maybe I missed something and there is a JMSGetNode....
Maybe you need to promote the property to the flow so that you can set it dynamically. It might also be useful to have it set to a dummy value at start of flow so that no message gets picked up at flow startup...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
JohnSmith |
Posted: Thu May 20, 2010 9:22 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
fjb_saper wrote:
Quote: |
What I don't get is why it must be the first node in your message flow |
It must be the first Input node, as it doesnt have any IN terminal, so can not be inserted in the middle of a flow.
Quote: |
Maybe you need to promote the property to the flow so that you can set it dynamically. It might also be useful to have it set to a dummy value at start of flow so that no message gets picked up at flow startup |
It also can not become a part of subflow as it doesn't have any INput terminal, so I dont know how it is going to help promoting the property.
The only way is we have to use JMSINput node in a seperate flow, but then how we will pick the correlationID from the request? |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri May 21, 2010 11:04 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
You could potentially have a JMSInput node that picks up all messages from provider X and put them as MQ messages for the broker to pick up with correlationId....  _________________ MQ & Broker admin |
|
Back to top |
|
 |
JohnSmith |
Posted: Mon May 24, 2010 5:22 pm Post subject: |
|
|
Voyager
Joined: 17 Mar 2010 Posts: 86
|
fjb_saper wrote:
Quote: |
You could potentially have a JMSInput node that picks up all messages from provider X and put them as MQ messages for the broker to pick up with correlationId.... |
I have done that but the problem is we are planning to share the back end with 2 different environments as I mentioned, so If we suppose a message meant to come for SIT gets picked by JMSInput Node running in UAT environment, then SIT will lose that message, and vice versa which shouldn't happen.
Only way to avoid this is to first browse the message for correlation ID and only when it seems to be yours then pick the message, but unfortunately JMSInput node seems "incapable" to do so. |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon May 24, 2010 6:54 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
JohnSmith wrote: |
fjb_saper wrote:
Quote: |
You could potentially have a JMSInput node that picks up all messages from provider X and put them as MQ messages for the broker to pick up with correlationId.... |
I have done that but the problem is we are planning to share the back end with 2 different environments as I mentioned, so If we suppose a message meant to come for SIT gets picked by JMSInput Node running in UAT environment, then SIT will lose that message, and vice versa which shouldn't happen.
Only way to avoid this is to first browse the message for correlation ID and only when it seems to be yours then pick the message, but unfortunately JMSInput node seems "incapable" to do so. |
You're missing my point.
Use the JMS node to pick up all messages regardless of provider. This message is picked up from which ever provider you have. You then have a JMS to MQ transform and put the message to the broker's qmgr with an MQOutput Node. This is a little helper flow.
The actual processing flow then does an MQGet on the broker's qmgr queue with check of correlationId.
All should be well and there should be no problem keeping your environments separate.... So yes you need one more flow but you gain in flexibility...
Have fun
Thi _________________ MQ & Broker admin |
|
Back to top |
|
 |
|