Author |
Message
|
wahlens |
Posted: Thu Jul 08, 2004 9:23 am Post subject: CorrelationId in C# |
|
|
Newbie
Joined: 08 Jul 2004 Posts: 2 Location: Kansas City, MO
|
All,
Can anyone provide me some feedback or examples on how to obtain the Correlation Id of a message that my C# application is getting from MQ (v 5.3) (using the WebShpere MQ Classes for .NET)?
I have been tying to use the <mqMsg>.CorrelationId.GetValue(); which returns a byte array. I assign this to a local byte arry but every time I run my application, the value that returned is always the same. Any help is greatly appreciated!!! _________________ wahlen |
|
Back to top |
|
 |
bower5932 |
Posted: Thu Jul 08, 2004 1:31 pm Post subject: |
|
|
 Jedi Knight
Joined: 27 Aug 2001 Posts: 3023 Location: Dallas, TX, USA
|
Is it possible that you are setting the same value with every put? You might want to look at running amqsbcg against your messages on the queue to see what they have for a correlation id. |
|
Back to top |
|
 |
kirani |
Posted: Thu Jul 08, 2004 1:41 pm Post subject: |
|
|
Jedi Knight
Joined: 05 Sep 2001 Posts: 3779 Location: Torrance, CA, USA
|
wahlens wrote: |
I assign this to a local byte arry but every time I run my application, the value that returned is always the same.
|
How are you checking this value? _________________ Kiran
IBM Cert. Solution Designer & System Administrator - WBIMB V5
IBM Cert. Solutions Expert - WMQI
IBM Cert. Specialist - WMQI, MQSeries
IBM Cert. Developer - MQSeries
|
|
Back to top |
|
 |
wahlens |
Posted: Tue Jul 13, 2004 9:46 am Post subject: CorrelationId in C# |
|
|
Newbie
Joined: 08 Jul 2004 Posts: 2 Location: Kansas City, MO
|
I have tried ckecking the correlation Id serval ways:
In a while loop for each message that I am getting from MQ I have done
1: For Loop: for the length of mqMsg.CorrelationId.Length
{
Byte array[index] = mqMsg.CorrelationId.GetValue(Int index);
}
2: string var = mqMsg.CorrelationId.ToString();
I have also tried to get it using the following MQC* methods
MQC.MQPMRF_CORREL_ID;
MQC.MQIT_CORREL_ID;
CMQCFC.MQCACF_CORREL_ID; _________________ wahlen |
|
Back to top |
|
 |
EddieA |
Posted: Tue Jul 13, 2004 10:05 am Post subject: |
|
|
 Jedi
Joined: 28 Jun 2001 Posts: 2453 Location: Los Angeles
|
Any function that relies on a string will not work on the CorrelationID. The field is defined as bytes, which will contain binary zeros. So any string functions will think that the field ends there. But it doesn't.
Cheers, _________________ Eddie Atherton
IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Message Broker V7.0 |
|
Back to top |
|
 |
JasonE |
Posted: Wed Jul 14, 2004 1:35 am Post subject: |
|
|
Grand Master
Joined: 03 Nov 2003 Posts: 1220 Location: Hursley
|
Method 1 looks ok thought (at a glance), ie checking bytes. How are you recreating the problem - show me how to change the supplied c# nmqsget.cs to recreate the problem.
To show this, use nmqsput.cs to put a message on the queue, amqsbcg to see its correlid, and modify nmqsget.cs to get that specific correl id. Show me your changes, and I'll try it here. |
|
Back to top |
|
 |
dpchiesa |
Posted: Fri Aug 13, 2004 5:24 am Post subject: String to Correlation ID |
|
|
 Apprentice
Joined: 29 May 2002 Posts: 46
|
here's what I do to derive a "Postcard friendly" Correlation ID from a string.
Code: |
const int CO_ID_LENGTH= 24;
public static byte[] StringToCorrelationId(String s)
{
char[] c=s.ToCharArray();
byte[] result= new byte[CO_ID_LENGTH];
int i;
for (i=0; (i < c.Length) && (i < CO_ID_LENGTH-1); i++)
result[i]= System.BitConverter.GetBytes(c[i])[0];
result[i++]= 0;
while (i < CO_ID_LENGTH) result[i++]=(byte)0x20;
return result ;
}
|
(The MQ Postcard sample app, I believe, uses the chars from the "recipient name", followed by a zero, followed by a series of 0x20, to generate the correlation ID)
Every string passed through this function will generate a correlation ID. But the function is not generally reversible. In other words, not every Correlation ID will map to a valid string (as EddieA sez, correlation ID can have zeroes).
The algorithm is naive - you will not get a unique CO ID for each unique string. Any 2 strings that have the same first 23 characters will generate the same co ID. You could get fancier by computing a hash and including it into the co ID. This would give you a unique value for each input string.
_________________ -dpchiesa |
|
Back to top |
|
 |
Leigh Kendall |
Posted: Mon Apr 24, 2006 8:10 am Post subject: |
|
|
 Acolyte
Joined: 10 Apr 2003 Posts: 66 Location: Hartford, CT
|
I know this is a bit late to the party, but hopefully others will find it useful:
An easy way to convert the Message/Correlation Id's to hex strings. Note, if you WANT hypens, omit the Replace method call.
Dim currentMsgId As String = BitConverter.ToString(message.MessageId).Replace("-", "")
So simple, but took me a while to find...
HTH, _________________ Leigh Kendall |
|
Back to top |
|
 |
maneshgurav |
Posted: Mon May 01, 2006 12:00 pm Post subject: |
|
|
Novice
Joined: 20 Apr 2006 Posts: 12
|
Hi All,
My requirement is to obtain a message id (of REQUEST) and store it in a database. And again, when needed, read the message id from the database and obtain the corresponding REPLY from the MQ Queue.
I am using Leigh Kendall's method to convert the MessageId from Byte() to HexString. I can store this HexString (with hypens) in the database. The VB.Net code is:
oQueue.Put(oMessage, oPMO)
sMessageId = BitConverter.ToString(oMessage.MessageId)
I get the MessageId like "41-4D-51-20-4D-54-4C-31-39-30-4D-51-54-45-53-54-94-A7-22-44-26-35-9E-01". Now once I read it from the database and want to retrive corresponding message from MQ, how can I convert this HexString back to Byte()?
Any help is appreciated.
Thank you,
Manesh |
|
Back to top |
|
 |
Leigh Kendall |
Posted: Tue May 02, 2006 12:25 pm Post subject: |
|
|
 Acolyte
Joined: 10 Apr 2003 Posts: 66 Location: Hartford, CT
|
maneshgurav -
Unfortunately there's no counterpart to BitConverter.ToString() built into .NET.
Here's a link to a project on CodeProject though:
http://www.codeproject.com/csharp/hexencoding.asp
Also, search the MS newsgroups via Google. Lots of examples, but the link above should do the trick. Just drop in the class and away you go. This *should* be in the .NET BCL's...
HTH, _________________ Leigh Kendall |
|
Back to top |
|
 |
maneshgurav |
Posted: Fri May 05, 2006 9:02 am Post subject: |
|
|
Novice
Joined: 20 Apr 2006 Posts: 12
|
Hi All,
I finally got a working solution!
Thank you all for your help.
But I did not use the most discussed solution - storing Message Id in the format of Hexadecimal String - as it involves a lot of work and does not work sometime. I am converting it to literal string.
Example:
Message Id as a Byte Array: {65,77,81,32,77,84,76,49,57,48,77,81,84,69,83,84,148,167,34,68,38,229,77,143}
This array has 24 bytes. There are .Net libraries that will allow you to convert a Byte Array into Hexadecimal String as shown below:
Message Id as a HexString:
"41-4D-51-20-4D-54-4C-31-39-30-4D-51-54-45-53-54-94-A7-22-44-26-E5-4D-8F"
Notice that “41” in HexString corresponds to 65 in Byte Array. But unfortunately, there is no single API to convert this HexString back to the Byte Array. So you can have your own function to convert each part of the HexString (like “41”) into a decimal and then form a Byte Array with all the decimals.
So I am storing the Message Id as a String (not HexString) obtained by literally converting the Bytes to Strings as shown below:
Message Id as a String:
"65-77-81-32-77-84-76-49-57-48-77-81-84-69-83-84-148-167-34-68-38-229-77-143"
This string can be easily converted back to the Byte Array.
VB.Net functions that I developed for the conversion are:
Code: |
Private Function convertByteArrayToString(ByVal btArray As Byte()) As String
Dim sReturn As String
Dim iCntr As Integer
Try
If btArray.Length = 0 Then
Throw New Exception("Empty Byte Array passed for conversion into String.")
End If
sReturn = CStr(btArray.GetValue(0))
For iCntr = 1 To btArray.Length - 1
sReturn = sReturn & BYTE_SEPARATOR & CStr(btArray.GetValue(iCntr))
Next
Return sReturn
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
Private Function convertStringToByteArray(ByVal sConcatenated As String) As Byte()
Dim sarrBytes As String()
Dim btarrReturn As Byte()
Dim iCntr As Integer
Try
If sConcatenated = String.Empty Then
Throw New Exception("Empty String passed for conversion into Byte Array.")
End If
sarrBytes = sConcatenated.Split(BYTE_SEPARATOR)
ReDim btarrReturn(sarrBytes.Length - 1)
For iCntr = 0 To sarrBytes.Length - 1
btarrReturn.SetValue(CByte(sarrBytes.GetValue(iCntr)), iCntr)
Next
Return btarrReturn
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
|
Thank you,
Manesh |
|
Back to top |
|
 |
jefflowrey |
Posted: Fri May 05, 2006 9:45 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
So instead of using the commonly tried and tested method of converting to hex string representation, and in order to avoid having to write one custom routine, you decided to invent your own method for which you had to write two custom routines. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
maneshgurav |
Posted: Fri May 05, 2006 11:09 am Post subject: |
|
|
Novice
Joined: 20 Apr 2006 Posts: 12
|
No jefflowrey. The link suggested by Leigh Kendall has 6 functions to do this task and they are in C#. I tried to convert them to VB.net. But they have some functionality like '// remove all none A-F, 0-9, characters'. Some other functions mentioned earlier remove whitespaces from the Message Id. My requirement was to get the Message Id of request, store it in a database and use it later to retrieve the corresponding response. So I wanted to use the Request Message Id as it is, without making any modifications to it. I tried many methods discussed here. If you use them to convert a Byte Array to 'some format' and later convert them back to Byte Array, sometimes the Byte Arrays don't match. So I thought that the best way would be store it as it is and use it. |
|
Back to top |
|
 |
|