ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » JMS msgId and correlId trouble in WMB

Post new topic  Reply to topic Goto page 1, 2  Next
 JMS msgId and correlId trouble in WMB « View previous topic :: View next topic » 
Author Message
JohnSmith
PostPosted: Tue May 04, 2010 6:22 am    Post subject: JMS msgId and correlId trouble in WMB Reply with quote

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
View user's profile Send private message
fjb_saper
PostPosted: Tue May 04, 2010 1:55 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
JohnSmith
PostPosted: Tue May 04, 2010 4:30 pm    Post subject: Reply with quote

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
View user's profile Send private message
JohnSmith
PostPosted: Tue May 04, 2010 8:29 pm    Post subject: Reply with quote

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
View user's profile Send private message
mqjeff
PostPosted: Wed May 05, 2010 2:22 am    Post subject: Reply with quote

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
View user's profile Send private message
JohnSmith
PostPosted: Wed May 05, 2010 5:57 am    Post subject: Reply with quote

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
View user's profile Send private message
JohnSmith
PostPosted: Wed May 19, 2010 8:20 pm    Post subject: Reply with quote

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
View user's profile Send private message
fjb_saper
PostPosted: Thu May 20, 2010 1:24 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
JohnSmith
PostPosted: Thu May 20, 2010 4:54 pm    Post subject: Reply with quote

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
View user's profile Send private message
JohnSmith
PostPosted: Thu May 20, 2010 6:07 pm    Post subject: Reply with quote

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
View user's profile Send private message
fjb_saper
PostPosted: Thu May 20, 2010 7:27 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
JohnSmith
PostPosted: Thu May 20, 2010 9:22 pm    Post subject: Reply with quote

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
View user's profile Send private message
fjb_saper
PostPosted: Fri May 21, 2010 11:04 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
JohnSmith
PostPosted: Mon May 24, 2010 5:22 pm    Post subject: Reply with quote

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
View user's profile Send private message
fjb_saper
PostPosted: Mon May 24, 2010 6:54 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » JMS msgId and correlId trouble in WMB
Jump to:  



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
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.