Question regarding commit/backout of a message using the pymqi module

A

Andrew Robert

Hi everyone,

Could someone help explain what I am doing wrong in
this code block?

This code block is an excerpt from a larger file that receives
transmitted files via IBM WebSphere MQSeries an drops it to the local
file system.

Transmission of the file works as designed but it has a flaw.

If the file cannot be created for whatever reason, the transmitted
message is lost.

What I am trying to do is ensure that a file transmit is considered
successful only after the created file's checksum matches.

If not, the code should treat it as an error and roll back the message
to MQSeries without a commit.

The basis for this should be around the pymqi.QueueManager class which
is named mq in the block listed below.

On execution, I get the traceback of:

Traceback (most recent call last):
File "M:\MQ\MQ\Scripts\receiver.py", line 269, in ?
receiver.run()
File "M:\MQ\MQ\Scripts\receiver.py", line 109, in run
self.connect()
File "M:\MQ\MQ\Scripts\receiver.py", line 118, in connect
self.qm.begin()
File "c:\python24\lib\site-packages\pymqi.py", line 738, in begin
raise MQMIError(rv[0], rv[1])
pymqi.MQMIError: MQI Error. Comp: 1, Reason 2121: WARNING:
MQRC_NO_EXTERNAL_PARTICIPANTS



Do you have any idea why this might be occurring?


class Receiver(object):
def __init__(self,qm_name,queue_name):
self.qm_name = qm_name
self.queue_name = queue_name

# Will be set later
self.qm = None
self.message = None

def run(self):
self.connect()
self.get()

def connect(self):
"""
Connect to queue manager
"""
try:
self.qm = mq.QueueManager(options.qmanager.upper() )
self.qm.begin()
except mq.PYIFError, err:
mqevlog.event("error",err)
sys.exit(1)


def get(self):
"""
Get a message from queue.
"""
queue = mq.Queue(self.qm, self.queue_name)
pmo = mq.pmo(Options = CMQC.MQPMO_SYNCPOINT)
md = mq.md()



while True:
try:
var = queue.get(self.message, md, pmo )
except mq.MQMIError,e:
if e.reason != CMQC.MQRC_NO_MSG_AVAILABLE:
mqevlog.event("error",e)
sys.exit(1)
break
else:
buff = StringIO(var)
tree = ElementTree(file=buff)

# Extract required elements and assign to local variables
key = "this should be a well-kept secret"
file_name = tree.find("dest").text
creation_time = tree.find("creation_time").text
contents = tree.find("contents").text
check = tree.find("checksum").text


#Decode temp file
original = file_encoder.decode(contents)


# Drop file to disk
if os.path.exists(file_name) is False:
open(file_name,"wb").write(original)
else:
mqevlog.event(sys.argv[0],"error","Output file path/name already
exists")
sys.exit(1)

# Get checksum of newly created file
sum=csums.getsum(file_name)

# Compare checksum of created file with value transmitted
if csums.checksum_compare(sys.argv[0],sum,check,file_name) == True:
queue.commit()
sys.exit(0)
else:
queue.backout()
mqevlog.event("error","CheckSums of
received/transmitted files do not match")
sys.exit(1)



Any help/insight you can provide on this would be greatly appreciated.
 
J

JonS

Andrew said:
Hi everyone,

Could someone help explain what I am doing wrong in
this code block?

This code block is an excerpt from a larger file that receives
transmitted files via IBM WebSphere MQSeries an drops it to the local
file system.

Transmission of the file works as designed but it has a flaw.

If the file cannot be created for whatever reason, the transmitted
message is lost.

What I am trying to do is ensure that a file transmit is considered
successful only after the created file's checksum matches.

If not, the code should treat it as an error and roll back the message
to MQSeries without a commit.

The basis for this should be around the pymqi.QueueManager class which
is named mq in the block listed below.

pymqi.MQMIError: MQI Error. Comp: 1, Reason 2121: WARNING:
MQRC_NO_EXTERNAL_PARTICIPANTS
Do you have any idea why this might be occurring?

Connect to queue manager
"""
try:
self.qm = mq.QueueManager(options.qmanager.upper() )
self.qm.begin()
except mq.PYIFError, err:
mqevlog.event("error",err)
sys.exit(1)

queue = mq.Queue(self.qm, self.queue_name)
pmo = mq.pmo(Options = CMQC.MQPMO_SYNCPOINT)
md = mq.md()
Any help/insight you can provide on this would be greatly appreciated.
(edited)

Andrew
Don't know if you still need help with the above. I am new to Python
and was searching for MQ interfaces with Python and found your
question. Having some coding (C) experience with MQ Series it appears
that you are performing a local unit of work coodinated by the Queue
Manager only. In this scenario you do not specify the mqbegin as it
implies an external resource manager will be involved. Under your PMOs
you have specified the messages are to be extracted under syncpoint
control which is all you need. The messages should be remain in the
queue if there is an mqback call or the application ends without a
disconnect. In my experience while the messages are preserved in the
queue any partial file write to the OS will be left after the backout
(in the case of space issues). Your code will have to do the
housekeeping.

best regards,
-JonS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top