Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Retreiving message from MQseries with Msg_Id

Status
Not open for further replies.

sajohn52

Programmer
May 12, 2008
4
US
Hi

I'm having problems retreiving an MQ message from a queue by msg_ID. Here is the situation. I receive two messages from a main frame where the data is stored in EBCDIC. The first message stores the data queue name and the msg_id of the second message I'm suppose to pick up. I parse the first msg open up a second queue and attempt to grab the second message by msg id. Below is the code:

my $dqueue = MQSeries::Queue->new
(
QueueManager => $qmgr,
Queue => $arg{getQ},
Options => MQOO_INPUT_SHARED,
GetConvert => \&Convert::EBCDIC::ebcdic2ascii,
) or die("Unable to open data queue $DQueue.\n") ;


$getmessage = MQSeries::Message->new( MsgDesc => { MsgId => $MsgID,
Encoding => MQSeries::MQENC_NATIVE,
CodedCharSetID => MQSeries::MQCCSI_Q_MGR
format => MQSeries::MQFMT_STRING
}
) ;

$rslt = $dqueue->Get
(
Message => $getmessage ,
GetMsgOpts => { Options => MQSeries::MQGMO_ACCEPT_TRUNCATED_MSG |
MQSeries::MQGMO_FAIL_IF_QUIESCING,
MatchOptions => MQSeries::MQMO_MATCH_MSG_ID
}

) or die("Unable to get message\n" .
"CompCode = " . $dqueue->CompCode() . "\n" .
"Reason = " . $dqueue->Reason()." ".MQReasonToText($dqueue->Reason())."\n");


I'm hoping someone can spot what I'm doing wrong or point me in right direction on what to try next.

TIA
 
I know nothing about MQSeries, but I don't see where you "open a second queue".
 
Like flowcontrol, I can't see where you read the second queue,either. Can you be a bit more specific about the 'problems' you are having? Which operation fails, and what are the return and reason codes?

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
I only included the last part of the code because it was the section that was giving me problems. The complete code is listed below.

I keep getting a "2033 No message to available" error message. The problem is that a message does exisit in the Dqueue but for some reason I am unable to extract it by msg_id. I think it may be somthing simple like I don't have the message option setup correctly or maybe its the way I'm unpacking the msg_id from the cqueue.

use MQSeries;
use MQSeries::QueueManager;
use MQSeries::Queue;
use MQSeries::Message;
use Convert::EBCDIC ;
use File::Spec::Functions ;
use strict ;


my ( $MsgTyp, $DQueue, $MsgID ) ;
my ( $AMsgTyp, $ADQueue, $AMsgID ) ;
my ( $getmessage, $rslt ) ;

my $mgr = 'Qmng' ;
my $channel = 'QChannel' ;
my $transport = 'TCP' ;
my $conn = 'Qmach' ;
my $getQ = 'QgetQ' ;

print <<EOM;
Opening Queue Manager...
Channel => $channel
Transport Type => $transport
Connection => $conn
EOM

my $qmgr = MQSeries::QueueManager->new
(
QueueManager => $mgr,
ClientConn => { 'ChannelName' => $channel,
'TransportType' => $transport,
'ConnectionName' => $conn
},
) || die("Unable to connect to queue manager $mgr\n");


print "Opening Control Queue...$getQ\n" ;

my $cqueue = MQSeries::Queue->new
(
QueueManager => $qmgr,
Queue => $getQ,
Options => MQOO_INPUT_SHARED | MQOO_BROWSE,
# GetConvert => \&Convert::EBCDIC::ebcdic2ascii,
) or die("Unable to open control queue.\n") ;


my $mask = 'MESSAGE_IDENTIFIER' ;

while ( 1 )
{
$getmessage = MQSeries::Message->new( ) ;

$rslt = $cqueue->Get
(
Message => $getmessage ,
GetMsgOpts => { Options => MQSeries::MQGMO_BROWSE_NEXT |
MQSeries::MQGMO_ACCEPT_TRUNCATED_MSG |
MQSeries::MQGMO_FAIL_IF_QUIESCING
}

) or die("Unable to get message\n" .
"CompCode = " . $cqueue->CompCode() . "\n" .
"Reason = " . $cqueue->Reason() . "\n");

if( $rslt <= 0 )
{
if( $rslt == 0 )
{
my $ReasonText = MQReasonToText($cqueue->Reason());
print "Error occurred retrieving data...\n" ;
print "CompCode = " . $cqueue->CompCode() . "\n" ;
print "Reason = " . $cqueue->Reason() . " $ReasonText\n" ;
print
exit 1 ;
}
else
{
my $ReasonText = MQReasonToText($cqueue->Reason());
print "No data found...\n" ;
print "CompCode = " . $cqueue->CompCode() . "\n" ;
print "Reason = " . $cqueue->Reason() . " $ReasonText\n" ;
print
exit 1 ;
}
}
else
{
( $MsgTyp, $DQueue, $MsgID ) = unpack 'x28A32x56x63x26x233x7x8x8x8A48x48x48x48A24', $getmessage->Data() ;
$AMsgTyp = Convert::EBCDIC::ebcdic2ascii( $MsgTyp ) ;
$ADQueue = Convert::EBCDIC::ebcdic2ascii( $DQueue ) ;
$AMsgID = Convert::EBCDIC::ebcdic2ascii( $MsgID ) ;
last if( $AMsgTyp =~ /^$mask/ ) ;
}
}



print <<EOM ;
Found message of type => <$AMsgTyp>
Dest Queue => <$ADQueue>
and ID of => <$AMsgID>
Removing message from control queue...
EOM

$getmessage = MQSeries::Message->new( ) ;

$rslt = $cqueue->Get
(
Message => $getmessage ,
GetMsgOpts => { Options => MQSeries::MQGMO_MSG_UNDER_CURSOR |
MQSeries::MQGMO_ACCEPT_TRUNCATED_MSG |
MQSeries::MQGMO_FAIL_IF_QUIESCING
}
) or die("Unable to get message\n" .
"CompCode = " . $cqueue->CompCode() . "\n" .
"Reason = " . $cqueue->Reason() . "\n") ;

###########################################################################
###########################################################################
###########################################################################


print "Opening Data Queue $ADQueue...\n" ;

my $dqueue = MQSeries::Queue->new
(
QueueManager => $qmgr,
Queue => $getQ,
Options => MQOO_INPUT_SHARED,
GetConvert => \&Convert::EBCDIC::ebcdic2ascii,
) or die("Unable to open data queue $DQueue.\n") ;


$getmessage = MQSeries::Message->new( MsgDesc => { MsgId => $MsgID,
Encoding => MQSeries::MQENC_NATIVE,
CodedCharSetID => MQSeries::MQCCSI_Q_MGR
format => MQSeries::MQFMT_STRING
}
) ;

$rslt = $dqueue->Get
(
Message => $getmessage ,
GetMsgOpts => { Options => MQSeries::MQGMO_ACCEPT_TRUNCATED_MSG |
MQSeries::MQGMO_FAIL_IF_QUIESCING,
MatchOptions => MQSeries::MQMO_MATCH_MSG_ID
}

) or die("Unable to get message\n" .
"CompCode = " . $dqueue->CompCode() . "\n" .
"Reason = " . $dqueue->Reason()." ".MQReasonToText($dqueue->Reason())."\n");

if( $rslt == 0 )
{
print " Error occurred retrieving data from data queue...\n" ;
exit 1 ;
}
if( $rslt == -1 )
{
print " No data found in data queue...\n" ;
print " CompCode = ".$dqueue->CompCode()."\n" ;
print " Reason = ".$dqueue->Reason()." ".MQReasonToText($dqueue->Reason())."\n" ;
print
exit 1 ;
}

print " Found msg!!!\n" ;
 
MQMSGID is a byte string, not character. So it doesn't get converted. If you GET from your control queue without MQGMO_CONVERT (as you seem to be doing) then the data will be in EBCDIC. So I'm not sure you want to be converting the message ID to ASCII after you unpack it, prior to doing the second GET.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
I have two mesasge variables one is called $MsgID and the other is called $AMsgID. I am converting $MsgID to ascii into the $AMsgID for debugging purposes. So $MsgID is used in the second Message->New is still in EBCDIC. Do you suppose that maybe I should unpacking the data using another option instead of 'A'?
 
I'm a bit confused by your application design. Normally you have a trigger queue to kick off a reader for another queue, but in this case the message on queue #1 doesn't seem to be in MQTM format. So I don't see the point of having one message that tells you that you have another message. But I digress.

Whatever you are doing with the queue name seems to be working OK, as otherwise you'd get a different error code back indicating an unknown queue. Try unpacking the MSGID with 'a' instead of 'A' and see what happens.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
stevexff

Boy is my face red! I found out that whole the problem was caused because I wasn't using the correct queue name when I opened up the second queue. After I made the fix everything worked fine. Thanks for your help.

BTW
Your right this a crummy why to retrive messages from MQ but the design was done by another group and I have no control over what they do.
 
C'est la vie...

At least it's sorted out!

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top