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 » IBM MQ API Support » [Solved] Browsing messages in Perl.

Post new topic  Reply to topic
 [Solved] Browsing messages in Perl. « View previous topic :: View next topic » 
Author Message
jgooch
PostPosted: Fri May 21, 2004 7:51 am    Post subject: [Solved] Browsing messages in Perl. Reply with quote

Acolyte

Joined: 29 May 2002
Posts: 63
Location: UK

Hi gang,

I'm trying to write a browse queue function using the Perl OO API. I can get it working using sync'd gets and a backout, but my code does not work using the MQOO_BROWSE and MQGMO_BROWSE_NEXT options. The error I receive is a 2037 (not open for input). If I change the open to use MQOO_INPUT, the script removes the messages from the queue.

Any explanation of my undoubtedly obvious ineptitude would be gratefully received.

Here's the code (apologies that the indentation has been lost):-
Quote:
# instantiate the queue object
$o_q = MQSeries::Queue->new (
QueueManager => "MWMQDJG",
Queue => "TEST.JG",
Options => MQSeries::MQOO_BROWSE + MQSeries::MQOO_FAIL_IF_QUIESCING,
AutoOpen => 0,
) || die "Unable to instantiate MQSeries::Queue object\n";

# open the queue
unless ( $o_q->Open() ) {
die "Unable to open queue object " .
"CompCode => " . $o_q->CompCode() . " " .
"Reason => " . $o_q->Reason()."\n";
}

# set up the options for the GETting
%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING +
MQSeries::MQGMO_CONVERT +
MQSeries::MQGMO_BROWSE_FIRST +
MQSeries::MQGMO_NO_WAIT,);

# get the messages
while ($message .= '') {
$o_message = MQSeries::Message->new();

# get the data from the queue
eval { $o_q->Get (
Message => $o_message,
GetMsgOpts => \%msg_opts,)
};

# check whether an error was returned from eval or if MQ completion code = -1 or 2
# suppress error reason 2033 as it is "normal" when there are no more records to process
if ($@ || $o_q->CompCode() == -1 || $o_q->CompCode() == 2 && $o_q->Reason() != 2033) {
die "Unable to get message " .
"CompCode => " . $o_q->CompCode() . " " .
"Reason => " . $o_q->Reason()."\n";
}

# MQ warning comp code = 1 treat as OK but issue warning
if ($o_q->CompCode() == 1) {
print "MQ warning issued ".
"CompCode => ".$o_q->CompCode()." Reason => ".$o_q->Reason()."\n";
}

$message = $o_message->Data();

if ($message .= '') {
push(@q_contents, $message);
$message_count++;
}

# set up more options for the GETting
%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING +
MQSeries::MQGMO_CONVERT +
MQSeries::MQGMO_BROWSE_NEXT +
MQSeries::MQGMO_NO_WAIT,);
}

print "$message_count message(s) read\n";


J.
Back to top
View user's profile Send private message
bduncan
PostPosted: Fri May 21, 2004 9:39 am    Post subject: Reply with quote

Padawan

Joined: 11 Apr 2001
Posts: 1554
Location: Silicon Valley

Hmm... It's been about two years since I worked with the Perl API, but I recall having trouble with browse myself. I believe I had to add some additional options to the MQOPEN call to get it to work.
Perhaps you had to specify both browse and input?
MQSeries::MQOO_BROWSE + MQSeries::MQOO_INPUT
??

There's this section from the programming guide:
Quote:

Removing a message you have browsed
You can remove from the queue a message you have already browsed provided you have opened the queue for removing messages as well as for browsing. (You must specify one of the MQOO_INPUT_* options, as well as the MQOO_BROWSE option, on your MQOPEN call.)

To remove the message, call MQGET again, but in the Options field of the MQGMO structure, specify MQGMO_MSG_UNDER_CURSOR. In this case, the MQGET call ignores the MsgId, CorrelId, and GroupId fields of the MQMD structure.

In the time between your browsing and removal steps, another program may have removed messages from the queue, including the message under your browse cursor. In this case, your MQGET call returns a reason code to say that the message is not available.


So perhaps the Perl API is a little squirrely in that it requires you to specify both even if you don't plan on removing messages that you browse...

Amazing how fast things go when you aren't doing them everyday
_________________
Brandon Duncan
IBM Certified MQSeries Specialist
MQSeries.net forum moderator
Back to top
View user's profile Send private message Visit poster's website AIM Address
clindsey
PostPosted: Fri May 21, 2004 10:58 am    Post subject: Reply with quote

Knight

Joined: 12 Jul 2002
Posts: 586
Location: Dallas, Tx

I ran mqtrace to see what your open options and get options were and the trace went from MQOpen to MQClose. I had to change "while ($message .= '') {" to get into drop into the get loop. This could be just my level of perl though.

The trace also showed that the open with MQOO_BROWSE was ok, but the GMO options were not getting picked up.

With the following changes, it started working for me:
Code:

# set up the options for the GETting
#%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING +
#MQSeries::MQGMO_CONVERT +
#MQSeries::MQGMO_BROWSE_FIRST +
#MQSeries::MQGMO_NO_WAIT,);
my $GetMsgOpts = { Options => MQGMO_FAIL_IF_QUIESCING | MQGMO_NO_WAIT | MQGMO_BROWSE_NEXT,
                   MatchOptions => MQMO_NONE, };


eval { $o_q->Get (
Message => $o_message,
GetMsgOpts => $GetMsgOpts,)
};

# set up more options for the GETting
#%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING +
#MQSeries::MQGMO_CONVERT +
#MQSeries::MQGMO_BROWSE_NEXT +
#MQSeries::MQGMO_NO_WAIT,);


Without setting MatchOptions to none, you have to reset msgid and correlid after each get or you won't match. It's easier to just override the default match options.

Hope this helps,
Charlie
Back to top
View user's profile Send private message
any2xml
PostPosted: Sat May 22, 2004 6:53 pm    Post subject: Web-based MQ monitor using MQSeries module Reply with quote

Apprentice

Joined: 18 May 2004
Posts: 42

I am interested in developing a web-based monitor for MQ using the MQSeries module. Looks like you folks have gone along that path a little. Is it possible to link with you so we can all contribute a little and come up with a generalized monitor?
_________________
A Perl Hacker
http://www.goreliance.com
http://www.any2xml.com
Back to top
View user's profile Send private message
bduncan
PostPosted: Sun May 23, 2004 9:08 am    Post subject: Reply with quote

Padawan

Joined: 11 Apr 2001
Posts: 1554
Location: Silicon Valley

I wrote such a tool (although it wasn't web based, but could easily be made so) called heartbeat.pl that appeared in the MQUpdate journal a year or two ago...
_________________
Brandon Duncan
IBM Certified MQSeries Specialist
MQSeries.net forum moderator
Back to top
View user's profile Send private message Visit poster's website AIM Address
jgooch
PostPosted: Mon May 24, 2004 7:00 am    Post subject: Reply with quote

Acolyte

Joined: 29 May 2002
Posts: 63
Location: UK

Guys,

Thanks for the help. I've now got it working, using Charlie's settings. You don't need to add MQOO_INPUT_SHARED to the queue open unless you're going to remove the messages once browsed.

I've also got this working where the browsing is limited to a given correlId (which are used at our site to identify batches of messages). The function also sets MQGMO_BROWSE_FIRST for the first iteration of the loop, before changing the option to use MQGMO_BROWSE_NEXT, so that each call to the function starts at the top of the queue (rather than wherever the cursor was when the last call finished).

For reference, here's the function code. We also have an "openq" function, that accepts MQOO_BROWSE and from which is returned a queue object that must be passed into "browseq"
Quote:
sub browseq {
# ---------------------------------------------------------------
# Subroutine : browseq
# Function : Browses the contents of a queue, returns an array.
# : If correl_id is provided, only matching messages are returned.
# Calling syntax : &browseq($o_q, $log_file, $correl_id);
# ---------------------------------------------------------------
my ($o_q, $log_file, $correl_id) = @_;
my $o_message;
my $message = 'start';
my $message_count = 0;
my @q_contents;
my %msg_desc;
my %msg_opts;

# check parameters
if ($#_ > 2) {
return ($STD::PARAMERROR, "browseq: Usage : browseq(queue_object, log_file, correl_id);");
}

if ($correl_id) {
%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING |
MQSeries::MQGMO_NO_WAIT |
MQSeries::MQGMO_BROWSE_FIRST,
MatchOptions => MQSeries::MQMO_MATCH_CORREL_ID, );
%msg_desc = ( CorrelId => $correl_id,
MsgId => MQSeries::MQMI_NONE );
}
else {
%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING |
MQSeries::MQGMO_NO_WAIT |
MQSeries::MQGMO_BROWSE_FIRST,
MatchOptions => MQSeries::MQMO_NONE, );
}

# get the messages
while ($message .= '') {
$o_message = MQSeries::Message->new(
MsgDesc => \%msg_desc );

# get the data from the queue
eval { $o_q->Get (
Message => $o_message,
GetMsgOpts => \%msg_opts,)
};

# check whether an error was returned from eval or if MQ completion code = -1 or 2
# suppress error reason 2033 as it is "normal" when there are no more records to process
if ($@ || $o_q->CompCode() == -1 || $o_q->CompCode() == 2 && $o_q->Reason() != 2033) {
return ($STD::MQERROR,
"browseq: Unable to get message " .
"CompCode => " . $o_q->CompCode() . " " .
"Reason => " . $o_q->Reason(), $log_file);
}

# MQ warning comp code = 1 treat as OK but issue warning to log file
if ($o_q->CompCode() == 1) {
&writelog($STD::WARNING,
"browseq: MQ warning issued ".
"CompCode => ".$o_q->CompCode()." Reason => ".$o_q->Reason(),
$log_file);
}

$message = $o_message->Data();

if ($message .= '') {
push(@q_contents, $message);
$message_count++;
}

if ($correl_id) {
%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING |
MQSeries::MQGMO_NO_WAIT |
MQSeries::MQGMO_BROWSE_NEXT,
MatchOptions => MQSeries::MQMO_MATCH_CORREL_ID, );
%msg_desc = ( CorrelId => $correl_id,
MsgId => MQSeries::MQMI_NONE );
}
else {
%msg_opts = ( Options => MQSeries::MQGMO_FAIL_IF_QUIESCING |
MQSeries::MQGMO_NO_WAIT |
MQSeries::MQGMO_BROWSE_NEXT,
MatchOptions => MQSeries::MQMO_NONE, );
}
}

&writelog($STD::INFO, "browseq: $message_count message(s) read", $log_file);
return (0,"",@q_contents);
}
# ---------------------------------------------------------------
# - end of browseq
# ---------------------------------------------------------------


J.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » IBM MQ API Support » [Solved] Browsing messages in Perl.
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.