Skip to content

Commit 363555d

Browse files
committed
Merge pull request #3 from dsuch/master
New option for working with WebSphere MQ 7.0 +
2 parents ad065e3 + f87fb13 commit 363555d

File tree

3 files changed

+65
-20
lines changed

3 files changed

+65
-20
lines changed

docs/sphinx/source/jms.rst

+24-10
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ First, let's send a message using nothing but pure Python code::
8484
queue1 = "TEST.1"
8585

8686
# The connection factory we're going to use.
87-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
87+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
8888

8989
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
9090
jms_template = JmsTemplate(factory)
@@ -110,6 +110,7 @@ be saved in::
110110
channel: SVRCONN.1
111111
host: 192.168.1.121
112112
listener_port: "1434"
113+
needs_mcd: False
113114

114115
- object: MyTemplate
115116
class: springpython.jms.core.JmsTemplate
@@ -162,7 +163,7 @@ examples do, they are repeated here for the sake of completness::
162163
queue1 = "TEST.1"
163164

164165
# The connection factory we're going to use.
165-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
166+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
166167

167168
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
168169
jms_template = JmsTemplate(factory)
@@ -189,6 +190,7 @@ that was used in the sending example::
189190
channel: SVRCONN.1
190191
host: 192.168.1.121
191192
listener_port: "1434"
193+
needs_mcd: False
192194

193195
- object: MyTemplate
194196
class: springpython.jms.core.JmsTemplate
@@ -233,6 +235,7 @@ fact of providing the configuration allows for receiving the messages::
233235
channel: SVRCONN.1
234236
host: 192.168.1.121
235237
listener_port: "1434"
238+
needs_mcd: False
236239

237240
- object: message_handler
238241
class: app.MyMessageHandler
@@ -406,6 +409,14 @@ of default values used::
406409
| | client-repo.sth, then ssl_key_repository must be set |
407410
| | to "/var/mqm/security/client-repo". |
408411
+------------------------------+-------------------------------------------------------+
412+
| **needs_mcd** | default: True |
413+
| + +
414+
| | Whether to add the *mcd* JMS folder to outgoing |
415+
| | messages. This defaults to True for |
416+
| | backward-compatibility reasons but should be always |
417+
| | set to False if working with WebSphere MQ 7.0 |
418+
| | or newer. |
419+
+------------------------------+-------------------------------------------------------+
409420

410421
Here's an example of programatically creating a
411422
:ref:`WebSphereMQConnectionFactory <jms-webspheremqconnectionfactory>` object::
@@ -417,7 +428,7 @@ Here's an example of programatically creating a
417428
host = "192.168.1.121"
418429
listener_port = "1434"
419430

420-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
431+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
421432

422433
# ... use factory here.
423434

@@ -437,6 +448,7 @@ inside of an IoC container::
437448
channel: SVRCONN.1
438449
host: 192.168.1.121
439450
listener_port: "1434"
451+
needs_mcd: False
440452

441453
All cached queues will not be closed by a factory until after its .destroy will
442454
have been called which will happen automatically if you're using an IoC container.
@@ -491,7 +503,7 @@ Here's how a JmsTemplate may be instantiated using Python code::
491503
host = "192.168.1.121"
492504
listener_port = "1434"
493505

494-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
506+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
495507
jms_template = JmsTemplate(factory)
496508

497509
# Always destroy the factory when not using IoC
@@ -509,6 +521,7 @@ An example of using YamlConfig to configure a JmsTemplate::
509521
channel: SVRCONN.1
510522
host: 192.168.1.121
511523
listener_port: "1434"
524+
needs_mcd: False
512525

513526
- object: jms_template
514527
class: springpython.jms.core.JmsTemplate
@@ -613,7 +626,7 @@ for encoding into UTF-8::
613626
queue1 = "TEST.1"
614627

615628
# The connection factory we're going to use.
616-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
629+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
617630

618631
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
619632
jms_template = JmsTemplate(factory)
@@ -679,7 +692,7 @@ destination can be specified for an outgoing message::
679692
queue1 = "TEST.1"
680693

681694
# The connection factory we're going to use.
682-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
695+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
683696

684697
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
685698
jms_template = JmsTemplate(factory)
@@ -714,7 +727,7 @@ jms_timestamp and jms_message_id properties::
714727
queue1 = "TEST.1"
715728

716729
# The connection factory we're going to use.
717-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
730+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
718731

719732
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
720733
jms_template = JmsTemplate(factory)
@@ -765,7 +778,7 @@ can explicitly specify the destination's name when you receive messages::
765778
queue2 = "TEST.2"
766779

767780
# The connection factory we're going to use.
768-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
781+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
769782

770783
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
771784
jms_template = JmsTemplate(factory)
@@ -831,7 +844,7 @@ default with Spring Python::
831844
exchange_queue = "TEST.1"
832845

833846
# The connection factory we're going to use.
834-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
847+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
835848

836849
requesting_side = JmsTemplate(factory)
837850
requesting_side.default_destination = exchange_queue
@@ -958,7 +971,7 @@ requests and responses using only one converter object::
958971
return invoice
959972

960973
# The connection factory we're going to use.
961-
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
974+
factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
962975

963976
# Our JmsTemplate.
964977
jms_template = JmsTemplate(factory)
@@ -1058,6 +1071,7 @@ has been set::
10581071
channel: SVRCONN.1
10591072
host: 192.168.1.121
10601073
listener_port: "1434"
1074+
needs_mcd: False
10611075

10621076
- object: message_handler
10631077
class: app.MyMessageHandler

src/springpython/jms/factory.py

+30-10
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class WebSphereMQConnectionFactory(DisposableObject):
9999
def __init__(self, queue_manager=None, channel=None, host=None, listener_port=None,
100100
cache_open_send_queues=True, cache_open_receive_queues=True,
101101
use_shared_connections=True, dynamic_queue_template="SYSTEM.DEFAULT.MODEL.QUEUE",
102-
ssl=False, ssl_cipher_spec=None, ssl_key_repository=None):
102+
ssl=False, ssl_cipher_spec=None, ssl_key_repository=None, needs_mcd=True):
103103
self.queue_manager = queue_manager
104104
self.channel = channel
105105
self.host = host
@@ -112,6 +112,9 @@ def __init__(self, queue_manager=None, channel=None, host=None, listener_port=No
112112
self.ssl = ssl
113113
self.ssl_cipher_spec = ssl_cipher_spec
114114
self.ssl_key_repository = ssl_key_repository
115+
116+
# WMQ >= 7.0 must not use the mcd folder
117+
self.needs_mcd = needs_mcd
115118

116119
self.logger = logging.getLogger("springpython.jms.factory.WebSphereMQConnectionFactory")
117120

@@ -269,7 +272,7 @@ def send(self, message, destination):
269272

270273
# Create MQRFH2 header
271274
now = long(time() * 1000)
272-
mqrfh2jms = MQRFH2JMS().build_header(message, destination, self.CMQC, now)
275+
mqrfh2jms = MQRFH2JMS(self.needs_mcd).build_header(message, destination, self.CMQC, now)
273276

274277
buff.write(mqrfh2jms)
275278
if message.text != None:
@@ -425,7 +428,7 @@ def _get_jms_timestamp_from_md(self, put_date, put_time):
425428
def _build_text_message(self, md, message):
426429
self.logger.log(TRACE1, "Building a text message [%r], md [%r]" % (repr(message), repr(md)))
427430

428-
mqrfh2 = MQRFH2JMS()
431+
mqrfh2 = MQRFH2JMS(self.needs_mcd)
429432
mqrfh2.build_folders_and_payload_from_message(message)
430433

431434
jms_folder = mqrfh2.folders.get("jms", None)
@@ -630,7 +633,12 @@ class MQRFH2JMS(object):
630633
# Size of a folder header is always 4 bytes.
631634
FOLDER_SIZE_HEADER_LENGTH = 4
632635

633-
def __init__(self):
636+
def __init__(self, needs_mcd=True):
637+
638+
# Whether to add the mcd folder. Needs to be False for everything to
639+
# work properly with WMQ >= 7.0
640+
self.needs_mcd = needs_mcd
641+
634642
self.folders = {}
635643
self.payload = None
636644

@@ -682,19 +690,29 @@ def build_folder(self, raw_folder):
682690

683691
folder = etree.fromstring(raw_folder)
684692
root_name = folder.tag
693+
694+
root_names = ["jms", "usr"]
695+
if self.needs_mcd:
696+
root_names.append("mcd")
685697

686-
if root_name in("mcd", "jms", "usr"):
698+
if root_name in root_names:
687699
self.folders[root_name] = folder
688700
else:
689701
self.logger.warn("Ignoring unrecognized JMS folder [%s]=[%s]" % (root_name, raw_folder))
690702

691703

692704
def build_header(self, message, queue_name, CMQC, now):
693-
self.folders["mcd"] = _mcd
705+
706+
if self.needs_mcd:
707+
self.folders["mcd"] = _mcd
708+
mcd = self._pad_folder(etree.tostring(self.folders["mcd"]))
709+
mcd_len = len(mcd)
710+
else:
711+
mcd_len = 0
712+
694713
self.add_jms(message, queue_name, now)
695714
self.add_usr(message)
696715

697-
mcd = self._pad_folder(etree.tostring(self.folders["mcd"]))
698716
jms = self._pad_folder(etree.tostring(self.folders["jms"]))
699717

700718
if "usr" in self.folders:
@@ -703,7 +721,6 @@ def build_header(self, message, queue_name, CMQC, now):
703721
else:
704722
usr_len = 0
705723

706-
mcd_len = len(mcd)
707724
jms_len = len(jms)
708725

709726
total_header_length = 0
@@ -725,8 +742,11 @@ def build_header(self, message, queue_name, CMQC, now):
725742
buff.write(CMQC.MQFMT_STRING)
726743
buff.write(_WMQ_MQRFH_NO_FLAGS_WIRE_FORMAT)
727744
buff.write(_WMQ_DEFAULT_CCSID_WIRE_FORMAT)
728-
buff.write(pack("!l", mcd_len))
729-
buff.write(mcd)
745+
746+
if self.needs_mcd:
747+
buff.write(pack("!l", mcd_len))
748+
buff.write(mcd)
749+
730750
buff.write(pack("!l", jms_len))
731751
buff.write(jms)
732752

test/springpythontest/jms_websphere_mq_test_cases.py

+11
Original file line numberDiff line numberDiff line change
@@ -1683,3 +1683,14 @@ def testSimpleMessageListenerContainerMessageHandler(self):
16831683
handler.handle("foo")
16841684
except NotImplementedError, e:
16851685
self.assertEquals(e.message, "Should be overridden by subclasses.")
1686+
1687+
def testNeedsMCD(self):
1688+
message = TextMessage(get_rand_string(12))
1689+
destination = get_rand_string(12)
1690+
now = long(time() * 1000)
1691+
1692+
has_mcd = MQRFH2JMS(True).build_header(message, destination, CMQC, now)
1693+
has_no_mcd = MQRFH2JMS(False).build_header(message, destination, CMQC, now)
1694+
1695+
self.assertTrue('mcd' in has_mcd)
1696+
self.assertTrue('mcd' not in has_no_mcd)

0 commit comments

Comments
 (0)