|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Using correlationId |
« View previous topic :: View next topic » |
Author |
Message
|
sp70 |
Posted: Wed Nov 14, 2001 12:18 pm Post subject: |
|
|
Newbie
Joined: 13 Nov 2001 Posts: 7
|
Hi,
I have an application where I have the following setup:
-requestQueue, remote on box A
-requestQueue, local on box B
-replyQueue, remote on box B
-replyQueue, local on box A
Basically, what I need to do is to:
-put request message to box A
-get that request message from box B
-process the message
-put reply message to box B
-get that reply message from box A
I may have multiple requests going through at the same time, so I thought I would manage them using the correlationId field...so I match my requests/replies.
My problem is that even though I set the correlationId to use for the put request, it seems to change after the put is complete. So by the time I want to get the reply, the correlationId is different.
Any ideas what I am doing wrong? I am really stuck. Any assistance would be really appreciated. |
|
Back to top |
|
 |
vasu |
Posted: Thu Nov 15, 2001 8:59 am Post subject: |
|
|
Novice
Joined: 13 Nov 2001 Posts: 15
|
Correlation ID will not change after the Put command. Check to see if you are setting any flags like Migrate_MsgId_To_CorrelationId when putting the message which may overwrite the Correlation_Id you are setting.
If problem still persists post the sample code you are using |
|
Back to top |
|
 |
sp70 |
Posted: Thu Nov 15, 2001 11:24 am Post subject: |
|
|
Newbie
Joined: 13 Nov 2001 Posts: 7
|
Hi Vasu,
Thank you for your suggestion. I checked to see whether I had that flag set, and I did not. I added the flag -MQC.MQRO_PASS_CORREL_ID. I am still having problems with this. Below is a code snippet. I would really appreciate any input/suggestions.
public void write(String msgString, boolean syncpoint, String replyToQueueName)
{
MilliTimer timer = null;
if (m_loggingOn)
{
Logger.log("Queue.write()", Logger.DEBUG);
timer = new MilliTimer();
}
MQQueue queue = null;
byte[] correlationID = null;
try
{
if (m_disconnect || m_tryingAlternate)
{
init(m_hostName, m_channel, m_queueMgrName, m_queueName);
m_tryingAlternate = false;
}
queue = new MQQueue(m_queueMgr,
m_queueName,
MQC.MQOO_OUTPUT,
null,
null,
null);
MQMessage msg = new MQMessage();
msg.format = MQC.MQFMT_STRING;
msg.expiry = m_expiry;
msg.writeString(msgString);
correlationID = createUUID();
System.out.println("write -1: correlationID is: " + correlationID);
msg.correlationId = correlationID;
System.out.println("write -2 " + msg.correlationId);
MQPutMessageOptions pmo = new MQPutMessageOptions();
if (syncpoint)
{
pmo.options = pmo.options | MQC.MQPMO_SYNCPOINT;
}
msg.report = MQC.MQRO_PASS_CORREL_ID;
msg.replyToQueueName = replyToQueueName;
queue.put(msg, pmo);
System.out.println("write -3 " + msg.correlationId);
if (m_loggingOn)
{
timer.stop();
Logger.log("elapsed time for Queue.write() = [" + timer.elapsed() + "]",
Logger.DEBUG);
}
}
catch (MQException e)
{
if (hasAlternates())
{
if (m_index >= getAltCount())
{
throw new RuntimeException("Queue.write(): m_index >= getAltCount() (no more alternates to try)");
}
m_hostName = m_hostNames[m_index];
m_channel = m_channels[m_index];
m_queueMgrName = m_queueMgrNames[m_index];
m_queueName = m_queueNames[m_index];
m_index++;
m_tryingAlternate = true;
if (m_loggingOn)
{
Logger.log("Queue.write(): trying alternate", Logger.INFO);
}
write(msgString, syncpoint);
}
else
{
throw new BaseException(e);
}
}
catch (Throwable t)
{
throw new BaseException(t);
}
finally
{
try
{
if (
(queue != null) &&
(queue.isOpen) //&&
//(!syncpoint)
)
{
queue.close();
}
if (m_disconnect)
{
if (syncpoint)
{
throw new RuntimeException("Queue.write(): m_disconnect && syncpoint");
}
else
{
close();
}
}
}
catch (Throwable t)
{
throw new BaseException(t);
}
}
}
|
|
Back to top |
|
 |
vasu |
Posted: Thu Nov 15, 2001 11:49 am Post subject: |
|
|
Novice
Joined: 13 Nov 2001 Posts: 15
|
I dont see any problem with your code. When setting the correlation ID, are you converting Correlation ID into Hex representation ? The function createUUID() --will this return correlation ID in hex form, if not you need to convert the string representation into Hex representation. Here is the sample code
*********************************************************
public static String getCorrIdAsHex( String corrID ) {
// Returns hex String representation of char c
char hexDigit[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
StringBuffer hexString = new StringBuffer();
int corrIDLen = corrID.length();
if (corrIDLen > 24)
corrIDLen = 24;
for (int i = 0; i < corrIDLen; i++) {
char c = corrID.charAt(i);
byte lowByte = (byte) (c & 0xff);
char[] array = { hexDigit[(lowByte >> 4) & 0x0f], hexDigit[lowByte & 0x0f] };
hexString.append(array);
}
if (corrIDLen < 24)
for (int i = 0; i < ((24 - corrIDLen) * 2); i++)
hexString.append('0');
hexString.append("'");
return new String(hexString.toString());
}
*********************************************************** |
|
Back to top |
|
 |
vasu |
Posted: Thu Nov 15, 2001 11:50 am Post subject: |
|
|
Novice
Joined: 13 Nov 2001 Posts: 15
|
use this code instead... sorry
*********************************************************
public static String getCorrIdAsHex( String corrID ) {
// Returns hex String representation of char c
char hexDigit[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
StringBuffer hexString = new StringBuffer();
int corrIDLen = corrID.length();
if (corrIDLen > 24)
corrIDLen = 24;
for (int i = 0; i < corrIDLen; i++) {
char c = corrID.charAt(i);
byte lowByte = (byte) (c & 0xff);
char[] array = { hexDigit[(lowByte >> 4) & 0x0f], hexDigit[lowByte & 0x0f] };
hexString.append(array);
}
if (corrIDLen < 24)
for (int i = 0; i < ((24 - corrIDLen) * 2); i++)
hexString.append('0');
return new String(hexString.toString());
}
***********************************************************
|
|
Back to top |
|
 |
sp70 |
Posted: Thu Nov 15, 2001 11:56 am Post subject: |
|
|
Newbie
Joined: 13 Nov 2001 Posts: 7
|
The createUUID returns a byte[]. When I do the println before the put and then after the put, the correlationIds are different. It prints garbage such as [B@1e75471 for the correlationId, but I would expect to get the same garbage before and after the put.
Here is the code that I am using to generate the correlationId. Any other suggestions?
private byte[] createUUID( ) throws IOException
{
// The create UUID method makes a universally unique id to be used by MQ in order to track the correlation id
UID oUID = new UID ( );
ByteArrayOutputStream oBAOS = new ByteArrayOutputStream ( );
DataOutputStream oDOS = new DataOutputStream ( oBAOS );
oUID.write ( oDOS );
oDOS.close ( );
return oBAOS.toByteArray ( );
}
|
|
Back to top |
|
 |
vasu |
Posted: Thu Nov 15, 2001 12:00 pm Post subject: |
|
|
Novice
Joined: 13 Nov 2001 Posts: 15
|
for testing, convert byte array coming from createUUID() into string and pass it to Hex conv function
String corrIdAsString = new String( createUUID() );
String corrIdAsHex = getCorrIdAsHex( corrIdAsString );
corrIdAsHex.toBytes() -- use this to set Corr Id for MQ Message
Let me know how it goes |
|
Back to top |
|
 |
EddieA |
Posted: Thu Nov 15, 2001 12:09 pm Post subject: |
|
|
 Jedi
Joined: 28 Jun 2001 Posts: 2453 Location: Los Angeles
|
As an aside, is there a reason that you can't use one of the 'usual' conventions for MQ which lets MQ do the generation of unique IDs.
Application A sets MessageId and CorrelationId to MQ[M C]I_NONE. After PUTting the message it retreives the, now, unique MessageId and uses that to match on CorrelationId for the returned message.
Application B waits for any message. When replying, it sets CorrelationId to the MessageId of the incoming message and then sets MessageId to MQMC_NONE. That way the reply has a unique MesageId and the Correation Id is what A is waiting for.
Cheers,
_________________ Eddie Atherton
IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Message Broker V7.0 |
|
Back to top |
|
 |
sp70 |
Posted: Thu Nov 15, 2001 12:14 pm Post subject: |
|
|
Newbie
Joined: 13 Nov 2001 Posts: 7
|
I will give both of your suggestions a try. I'll do that right now, and let you know how I make out. Thanks for your help. |
|
Back to top |
|
 |
sp70 |
Posted: Thu Nov 15, 2001 1:42 pm Post subject: |
|
|
Newbie
Joined: 13 Nov 2001 Posts: 7
|
I tried both your suggestions, and am still having problems with this. Could there be something in the setup of the queues that would force the correlation/message ids to change? I really appreciate your assistance. |
|
Back to top |
|
 |
EddieA |
Posted: Thu Nov 15, 2001 1:52 pm Post subject: |
|
|
 Jedi
Joined: 28 Jun 2001 Posts: 2453 Location: Los Angeles
|
No. As stated earlier, MQSeries does not modify the CorrelationId when writing a message. It will only modify the MesageId if the value is null, as set by MQMI_NONE.
Cheers,
_________________ Eddie Atherton
IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Message Broker V7.0 |
|
Back to top |
|
 |
vasu |
Posted: Thu Nov 15, 2001 2:04 pm Post subject: |
|
|
Novice
Joined: 13 Nov 2001 Posts: 15
|
When putting the reply message, what is the logic behind ? Are you copying the correlation id also in the message processing logic ? |
|
Back to top |
|
 |
bduncan |
Posted: Fri Nov 16, 2001 3:08 pm Post subject: |
|
|
Padawan
Joined: 11 Apr 2001 Posts: 1554 Location: Silicon Valley
|
One approach that many people use is the following...
When they create a message that will serve as a request, they have the Queue Manager set the MsgId to some unique value, and they will leave the CorrelId blank. The application will then put the message to a queue. On the other side, another application will pick up the request, process it, and prepare a reply message. Now, what this application does is create a new message, and again, lets the queue manager provide the MsgId. However, this application will set the CorrelId of the reply message to the MsgId of the request message it just processed. It then puts this new message to the reply queue. The original application, in the meantime, after sending off the request, did an MQGET on the reply queue, and specified to match against CorrelId, but the value it supplied to match against was actually the MsgId of the original request message.
It may be easier to see:
Request Message
---------------
MsgId: 123456789 (some value from the QMgr)
CorrelId : null
Reply Message
-------------
MsgId: 564563233 (some other value from QMgr)
CorrelId: 123456789 (original MsgId)
So the application that made the request will wait for a reply message with a CorrelId of 123456789
_________________ Brandon Duncan
IBM Certified MQSeries Specialist
MQSeries.net forum moderator |
|
Back to top |
|
 |
sp70 |
Posted: Tue Nov 27, 2001 11:00 am Post subject: |
|
|
Newbie
Joined: 13 Nov 2001 Posts: 7
|
Hi,
I would like to thank all of you for your assistance with this problem. Your suggestions really helped me out. I did get this to work. Thank you very much! |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
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
|
|
|
|