Author |
Message
|
mcdonald |
Posted: Wed Oct 05, 2011 5:56 am Post subject: PERL MQ read queue |
|
|
Newbie
Joined: 05 Oct 2011 Posts: 6
|
Hi All,
I have been tasked with reading the messages present in the MQ queue, using PERL.
I have no knowledge of MQ series or its APIs but have basic understanding of PERL.
Based on my research on this forum, I found the following code snippet to read a queue's messages.
1. Can someone please confirm that this will read the queue correctly?
Code: |
use MQSeries;
use MQSeries::QueueManager;
use MQSeries::Message;
use MQSeries::Message::IIH;
$qmgr = MQSeries::QueueManager->new
(
QueueManager => ' ', ClientConn =>{ 'ChannelName'=> 'SYSTEM.DEF.SVRCONN','TransportType'=> 'TCP','ConnectionName' => "TC3MSGBK(14140)"}) || die("Unable to connect to queue manager\n");
# QueueManager => ' ', ClientConn =>{ 'ChannelName'=> 'SYSTEM.DEF.SVRCONN','TransportType'=> 'TCP','ConnectionName' => "HOSTSYSB"}) || die("Unable to connect to queue manager\n");
# Get a message from an IMS queue
my $queue = MQSeries::Queue->
new(QueueManager => 'TEST.QM',
Queue => 'IMS.DATA.QUEUE',
Mode => 'input');
my $msg = MQSeries::Message::IIH->new();
$queue->Get(Message => $msg);
my $data = $msg->Data();
print "Have transaction '", $data->{Transaction}, "' and body '", $data->{Body}, "'\n"; |
2. Every time we read the queue, how many messages does it retrieve? If the queue receives 1000 messages in a span of 1 hour, does reading it at the end of 1 hour retrieve all the 1000 messages (Data Body) at once?
3. If it retrieves only one message per read, how do I iterate for it to read all un-read queue messages? Is there a flag for unread messages?
Any help would be appreciated, thanks. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Oct 05, 2011 6:02 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
- That code looks reasonably good. Does it execute? You will want to ensure that you are also reporting the MQRC when you hit your DIE statements. See the examples at http://search.cpan.org/~mqseries/MQSeries-1.32/MQSeries/QueueManager.pm
- Each Get only ever returns one message
- Each Get is a destructive read, the message that is returned is not left on the queue. Unless you take steps to browse the message instead of destructively get it. Don't take those steps.
Remember that an MQ Queue is in fact queue - a FIFO structure. |
|
Back to top |
|
 |
mcdonald |
Posted: Wed Oct 05, 2011 6:08 am Post subject: |
|
|
Newbie
Joined: 05 Oct 2011 Posts: 6
|
Thanks for the quick reply.
4. If each get only ever returns one message, how do I know when the queue is empty? Intention is to read ALL messages on the queue one by one and process it to a file. If while reading the queue, I don't get anything (queue is empty), then stop and re-poll after 1 sec.
5. What do you mean by 'Ensure that you are also reporting the MQRC when you hit your DIE statements'? Sorry but I am presuming these are MQ related abbreviations and have no idea what they mean. Are you asking me to include some additional code for the read operation to work correctly? |
|
Back to top |
|
 |
Vitor |
Posted: Wed Oct 05, 2011 6:18 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
mcdonald wrote: |
4. If each get only ever returns one message, how do I know when the queue is empty? |
You get a no message found error from your get. I am not now nor have I ever been a PERL developer, so what you do next is your business unless my most worthy associate pops up with expert advice.
mcdonald wrote: |
5. What do you mean by 'Ensure that you are also reporting the MQRC when you hit your DIE statements'? |
MQRC = MQ Reason Code = Notification It's Not Gone All That Well. Examples include your queue having no messages on it, the queue not being accessable, the queue manager not being accessable, etc, etc. A code of zero means that you probably shouldn't do what I'm assuming the DIE command does, because whatever WMQ operation you just attempted worked. Quoting the code will not only tell you it's not worked but give you a clue as to why. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Oct 05, 2011 8:59 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
As my colleague says, MQRC is "MQ Reason Code".
The perldoc for the QueueManager module, which I pointed you at through the CPAN website, contains sample code specifically for how to report both the ReasonCode and the CompletionCode.
Your perl code should be in the habit of always reporting both of these in any Die statements or error messages. It is not possible to troubleshoot MQ calls without knowing the value of these fields. |
|
Back to top |
|
 |
mcdonald |
Posted: Mon Oct 10, 2011 3:03 am Post subject: |
|
|
Newbie
Joined: 05 Oct 2011 Posts: 6
|
Hi,
Thank you for that.
Since the queue read results in only one message being read everytime, can anyone please help with providing a means by which I can achieve the following -
while (queue is not empty)
{
read_queue => my program above
}
What I am interested in knowing is whether I can program it to read all the messages one by one until the queue is empty, instead of just reading one message and exiting.
Thank you |
|
Back to top |
|
 |
zpat |
Posted: Mon Oct 10, 2011 4:00 am Post subject: |
|
|
 Jedi Council
Joined: 19 May 2001 Posts: 5866 Location: UK
|
It would be very poor code to connect or open the queue for each message.
I am sure Perl MQ supports normal MQ programming.
Look for MQRC 2033 for "no messages available" (empty queue). |
|
Back to top |
|
 |
bruce2359 |
Posted: Mon Oct 10, 2011 4:12 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9469 Location: US: west coast, almost. Otherwise, enroute.
|
Basic Perl also includes support for a do loop. Search Google for Perl+do+loop. _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
mcdonald |
Posted: Mon Oct 10, 2011 4:20 am Post subject: |
|
|
Newbie
Joined: 05 Oct 2011 Posts: 6
|
Hi zpat/bruce,
Yes, I was thinking of utilizing a do loop but have no clue what condition to give inside. I have no knowledge of MQSeries so was at a dead-end.
Now that you have informed me that 2033 is the MQRC for no messages availalble, my initial question was how do I access this specific MQRC.
Essentially,
do
{
read_queue ** i.e. my program above **
} while ("MQRC is not 2033")
Now, I have no idea how to code that "MQRC is not 2033" condition as it requires know-how of MQSeries? Essentially, question is how do I read this MQRC variable or error?
I was looking at http://search.cpan.org/~mqseries/MQSeries-1.32/MQSeries/QueueManager.pm as suggested, but am not able to figure out that part yet.
I have looked a lot of google results for PERL MQSeries READ queue, but not getting anything relevant at the moment regarding how to read MQRC.
Thanks. |
|
Back to top |
|
 |
bruce2359 |
Posted: Mon Oct 10, 2011 5:12 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9469 Location: US: west coast, almost. Otherwise, enroute.
|
You need to improve your Google search skills.
Try searching Google for perl+wmq. Look for these keywords: sample code or examples of perl code or sample programs.
Capitalware has Perl samples. _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Oct 10, 2011 5:58 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
You need to improve your ability to read the Perl documentation. Understanding how to read perldoc is vital to the process of being a Perl programmer.
From the page on the Queue module
Code: |
while (1) {
my $getmessage = MQSeries::Message->new();
$queue->
Get(Message => $getmessage,
Sync => 1,
) or die("Unable to get message\n" .
"CompCode = " . $queue->CompCode() . "\n" .
"Reason = " . $queue->Reason() . "\n");
if ( UpdateSomeDatabase($getmessage->Data()) ) {
$qmgr_obj->Commit()
or die("Unable to commit changes to queue.\n" .
"CompCode = " . $queue->CompCode() . "\n" .
"Reason = " . $queue->Reason() . "\n");
} else {
$qmgr_obj->Backout()
or die("Unable to backout changes to queue.\n" .
"CompCode = " . $queue->CompCode() . "\n" .
"Reason = " . $queue->Reason() . "\n");
}
}
|
You see that? Where it calls the method "Reason()"? |
|
Back to top |
|
 |
mcdonald |
Posted: Mon Oct 10, 2011 6:01 am Post subject: |
|
|
Newbie
Joined: 05 Oct 2011 Posts: 6
|
Thanks guys, really appreciate your time and help.
Sorry all these are new to me, just getting a hang of how things work from both MQSeries and PERL side. I will test the completed code and make sure it works. Will post the complete code once done so that its useful to other people in same situation as me.
Thanks again. |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Oct 10, 2011 6:05 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
mcdonald wrote: |
just getting a hang of how things work from both MQSeries and PERL side. |
I guess your "basic understanding of Perl" is a bit more basic than I expected.
You should focus on learning Perl as much as possible before focusing on learning WebSphere MQ. It's easier to fix MQ problems when you've got good code in the first place, and much harder to fix bad code if you've got good MQ practices in place. |
|
Back to top |
|
 |
mcdonald |
Posted: Mon Oct 10, 2011 6:12 am Post subject: |
|
|
Newbie
Joined: 05 Oct 2011 Posts: 6
|
Thanks mqjeff.
Yes, I figured out what was the problem.
Apparently, I was looking everywhere in the documentation for the read example, but was looking in the wrong module (QueueManager).
Looks like its actually the MQSeries::Queue module and not the MQSeries::QueueManager module which actually handles the read operation.
Your code fragment helped me point myself to the correct module.
Much appreciated. |
|
Back to top |
|
 |
|