Author |
Message
|
rivast_2001 |
Posted: Mon Apr 18, 2005 6:52 am Post subject: Posting a message to MQSeries with a Message Id |
|
|
 Novice
Joined: 14 Jul 2004 Posts: 15 Location: Mansfield, MA
|
I am creating a .NET application where I am trying to write and read a message to an iSeries MQSeries queue and this is done without any issues. At this moment I am at the point that I need to assign a Message Id to the message. For this I am following the method signature specifications where the message need to be a byte array. I can write and read from the queue with not issues. My questions is when I am trying to see the message from the iSeries Queue Manager interface programs, specially option "Display MQ Message Description", I am not able to see the message Id I am writing nor the RPG program that is reading the message from the queue. Which format should I be using to write this byte array from the .NET application? The description of my environment is the following,
- .NET framework 1.1
- Visual Studio 2003
- iSeries Web Sphere MQ
- Web Sphere MQ Series Developer Toolkit CSD 07
- WebSphere MQ classes for Microsoft .NET - ma7p.msi - amqmdnet.dll
I have tested the application writing to MQ in the iSeries using the following segment of code. I have also tested the following encoding types and none of them allows me to see the message id on the iSeries interface.
- _putMessage.MessageId = System.Text.Encoding.ASCII.GetBytes(inMessageId);
- _putMessage.MessageId = System.Text.Encoding.BigEndianUnicode.GetBytes(inMessageId);
- _putMessage.MessageId = System.Text.Encoding.Default.GetBytes(inMessageId);
- _putMessage.MessageId = System.Text.Encoding.Unicode.GetBytes(inMessageId);
- _putMessage.MessageId = System.Text.Encoding.UTF7.GetBytes(inMessageId);
- _putMessage.MessageId = System.Text.Encoding.UTF8.GetBytes(inMessageId);
Sample of the method used to write to MQ Series queue.
public byte[] PutMessageIntoQueue(string inQueueName,
string inMessage, EnumMessageFormat inMessageFormat, int inPriority, string inMessageId,
int inSecondsToExpire, bool inCloseQueue)
{
byte[] outValue;
IBM.WMQ.MQQueue backupQueue = null;;
string backupQueueName = string.Empty;
try
{
if (inMessage.Trim().Length == 0)
throw new Exception(CONST_INVALID_MESSAGE);
//checking if connection with _queue manager is active
CheckQueueManagerConnection();
int openOptions = MQC.MQOO_OUTPUT;
if (
(_queue == null)
|| (_queueName.Trim().ToUpper() != inQueueName.Trim().ToUpper())
|| (_queue.OpenOptions != openOptions)
)
{
if (_queue != null)
{
backupQueue = _queue;
backupQueueName = _queueName;
}
_queue = _qManager.AccessQueue(inQueueName, openOptions);
_queueName = inQueueName;
}
_putMessage = new MQMessage();
_putMessageOptions = new MQPutMessageOptions();
//specifying ibm037 character set identifier
_putMessage.CharacterSet = 37;
//specifying message identifier
if ( (inMessageId != null) && (inMessageId.Length) > 0)
{
_putMessage.MessageId = System.Text.Encoding.UTF8.GetBytes(inMessageId);
_putMessage.CorrelationId = MQC.MQCI_NONE;
}
//specifying the number of second for the message to expire
//values is specified in tenth of a second
if (inSecondsToExpire > 0)
_putMessage.Expiry = inSecondsToExpire * 10;
//setting priority of the message
if (inPriority > 0) _putMessage.Priority = inPriority;
//setting the nature of the message to the receiver
_putMessage.Format = MQC.MQFMT_STRING;
switch(inMessageFormat)
{
case EnumMessageFormat.UTFFormat:
{
_putMessage.WriteUTF(inMessage);
break;
}
default:
{
_putMessage.WriteString(inMessage);
break;
}
}
//putting the message into the _queue
_queue.Put(_putMessage, _putMessageOptions);
//returning the messageId assigned by the _queue manager
outValue = _putMessage.MessageId;
//closing the _queue
if (inCloseQueue)
{
_qManager.Commit();
_queue.Close();
_queue = null;
}
if (backupQueue != null)
{
if (!inCloseQueue) _queue.Close();
_queue = backupQueue;
_queueName = backupQueueName;
}
}
catch(Exception exc)
{
throw new Exception(
string.Format("Error {0} when putting messageinto queue \"{1}\".", exc.Message, inQueueName), exc);
}
return outValue;
}
--This is a sample of the information I am seeing on the iSeries
Display MQ Message Description
Queue Manager Name . : PARTNERVALQM
Queue name . . . . . : PRAS.OUTPUT.LOCAL.QUEUE
Report options . . . : NONE
Message type . . . . : DATAGRAM
Feedback code . . . : NONE
Data encoding . . . : REVERSE REVERSE IEEE_REVERSED
Coded character set
identifier . . . . : 37
Format name . . . . : MQSTR
Message priority . . : 0
Message persistence : NOT PERSISTENT
Message ID . . . . . : . . . . . . . . . . . . . . . . . . . . . . . .
Message ID
(Hexadecimal) . . : 563139313332343837343030303530343131303132373536
Correlation ID . . . : . . . . . . . . . . . . . . . . . . . . . . . .
Correlation ID
(Hexadecimal) . . : 000000000000000000000000000000000000000000000000
Backout counter . . : 0
Name of reply queue :
Display MQ Message Description
Hope someone have an answer for me on this. Thanks a lot. |
|
Back to top |
|
 |
RogerLacroix |
Posted: Mon Apr 18, 2005 7:25 am Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hi,
Why!?! Why are you setting the Message ID field of the message's MQMD??
The queue manager will happily AND correctly set the Message ID when your client application does a MQPUT. Most people who have been doing MQ for a while will tell you NOT to mess around with the Message ID.
Why don't you describe, from a high-level, what you are trying to accomplish. i.e. request/reply scenario, one-way message to update a database, web app doing an inquiry, etc... Then we will be in a better position to help you.
Also, you should read the manual (RTM). Because there are certain fields of the MQMD that are not convert between platforms. i.e. Windows is ASCII and OS/400 (iSeries) is EBCDIC.
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
rivast_2001 |
Posted: Mon Apr 18, 2005 10:26 am Post subject: |
|
|
 Novice
Joined: 14 Jul 2004 Posts: 15 Location: Mansfield, MA
|
Thanks a lot for getting back to me so quick. What I am trying to implement is the following scenario,
we have several Delphi applications that are registering requests on a remote machine. On this machine there is a .NET Windows NT Service in charge of submitting these request to the iSeries Input Queue trough a .NET web Service. This web service every time a request arrives it generates a unique key containing the source, date, time, etc, which we are trying to persist on the Message Id property of the message thta is being writen to MQ. This Id will be the one used later on by the remote Windows NT Service to find out the status of the request and retrive a response if completed.
Once the message is posted to the queue the iSeries RPG programs in charge of processing the request will be triggered on EACH entry to the queue and one of the parameters we are trying to pass is the MessageId also. At the end when these programs finished their execution they will have to write the message to the output queue with the same message id.
Based on you last e-mail I have been trying to capture the messageId returned by the Put() method and decoding it as an ASCII character set and this is what I am getting: ATX@WAYcUEYeASXTBcH. Should I be decoding it as something else? Is there any way that I can write my own MessageId? Thanks a lot again.
Tomas |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Apr 18, 2005 10:36 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
rivast_2001 wrote: |
Based on you last e-mail I have been trying to capture the messageId returned by the Put() method and decoding it as an ASCII character set and this is what I am getting: ATX@WAYcUEYeASXTBcH. Should I be decoding it as something else? |
Yes. You should be decoding as the bytes that it is, not in any sort of character set.
Also, it is very likely that the messageID field will end up being too short for what you are doing.
You are better off creating some sort of lookup table - in memory, or in a database or something, that will relate a new messageID created by MQ (and returned from the Put) with the necessary application information. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
rivast_2001 |
Posted: Tue Apr 19, 2005 11:06 am Post subject: |
|
|
 Novice
Joined: 14 Jul 2004 Posts: 15 Location: Mansfield, MA
|
Thanks a lot for your help. Finally I was able to write an EBCDIC encoder and populate the MessageId property within the message with the desired unique value.
At this moment I would like to trigger a program from MQ, which we have done before, but in this case I would like to pass the message id as a parameter. Is there any way to specify this value so it gets pass as a parameter when calling the RPG program? This is needed b/c we will have more than one job processing the request at the same time, kind of simulating multithreading on the iSeries, and the Message id will specify the entry to extract from the queue and process.
Thanks in advance,
rivast_2001 |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Apr 19, 2005 6:30 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Looking at something way too complicated.
MQ will handle multithreading out of the box.
Enjoy  |
|
Back to top |
|
 |
rivast_2001 |
Posted: Wed Apr 20, 2005 4:28 am Post subject: |
|
|
 Novice
Joined: 14 Jul 2004 Posts: 15 Location: Mansfield, MA
|
Is there any way to extract the Message Id and pass it as a parameter to the trigger or within the process? |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Apr 20, 2005 4:30 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Not with a default trigger monitor. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
rivast_2001 |
Posted: Wed Apr 20, 2005 4:41 am Post subject: |
|
|
 Novice
Joined: 14 Jul 2004 Posts: 15 Location: Mansfield, MA
|
Ok. We have the trigger monitor, but I have questions on how to pass the MessageId to the program to be executed by the trigger monitor. Is this something we need to specify within the definition of the process? If so, any ideas?
Process Id:
CRTMQMPRC PRCNAME(RENEWALCONTROLUPDATER.PROCESS) MQMNAME(PRRENEWQM) TEXT(‘Renewal Control File Updater Process’)
APPTYPE(*OS400)
APPID(‘MyLibrary/MyProgram’)
Trigger Monitor:
SBMJOB CMD(STRMQMTRM INITQNAME(RENEWAL.ACKNOWLEDGMENT.LOCAL.INITQUEUE) MQMNAME(PRRENEWQM)) JOBD(RBJOBD) |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Apr 20, 2005 5:07 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You have to change the code of the trigger monitor to do this.
You don't want to change the code of the trigger monitor.
You want to rethink your design. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
rivast_2001 |
Posted: Wed Apr 20, 2005 5:11 am Post subject: |
|
|
 Novice
Joined: 14 Jul 2004 Posts: 15 Location: Mansfield, MA
|
|
Back to top |
|
 |
|