Permalink
Browse files

Merge pull request #3 from dsuch/master

New option for working with WebSphere MQ 7.0 +
  • Loading branch information...
2 parents ad065e3 + f87fb13 commit 363555da6813f9c2c131ed8cec39deaf372e750c @gregturn gregturn committed Dec 5, 2011
Showing with 65 additions and 20 deletions.
  1. +24 −10 docs/sphinx/source/jms.rst
  2. +30 −10 src/springpython/jms/factory.py
  3. +11 −0 test/springpythontest/jms_websphere_mq_test_cases.py
View
@@ -84,7 +84,7 @@ First, let's send a message using nothing but pure Python code::
queue1 = "TEST.1"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
jms_template = JmsTemplate(factory)
@@ -110,6 +110,7 @@ be saved in::
channel: SVRCONN.1
host: 192.168.1.121
listener_port: "1434"
+ needs_mcd: False
- object: MyTemplate
class: springpython.jms.core.JmsTemplate
@@ -162,7 +163,7 @@ examples do, they are repeated here for the sake of completness::
queue1 = "TEST.1"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
jms_template = JmsTemplate(factory)
@@ -189,6 +190,7 @@ that was used in the sending example::
channel: SVRCONN.1
host: 192.168.1.121
listener_port: "1434"
+ needs_mcd: False
- object: MyTemplate
class: springpython.jms.core.JmsTemplate
@@ -233,6 +235,7 @@ fact of providing the configuration allows for receiving the messages::
channel: SVRCONN.1
host: 192.168.1.121
listener_port: "1434"
+ needs_mcd: False
- object: message_handler
class: app.MyMessageHandler
@@ -406,6 +409,14 @@ of default values used::
| | client-repo.sth, then ssl_key_repository must be set |
| | to "/var/mqm/security/client-repo". |
+------------------------------+-------------------------------------------------------+
+| **needs_mcd** | default: True |
+| + +
+| | Whether to add the *mcd* JMS folder to outgoing |
+| | messages. This defaults to True for |
+| | backward-compatibility reasons but should be always |
+| | set to False if working with WebSphere MQ 7.0 |
+| | or newer. |
++------------------------------+-------------------------------------------------------+
Here's an example of programatically creating a
:ref:`WebSphereMQConnectionFactory <jms-webspheremqconnectionfactory>` object::
@@ -417,7 +428,7 @@ Here's an example of programatically creating a
host = "192.168.1.121"
listener_port = "1434"
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# ... use factory here.
@@ -437,6 +448,7 @@ inside of an IoC container::
channel: SVRCONN.1
host: 192.168.1.121
listener_port: "1434"
+ needs_mcd: False
All cached queues will not be closed by a factory until after its .destroy will
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::
host = "192.168.1.121"
listener_port = "1434"
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
jms_template = JmsTemplate(factory)
# Always destroy the factory when not using IoC
@@ -509,6 +521,7 @@ An example of using YamlConfig to configure a JmsTemplate::
channel: SVRCONN.1
host: 192.168.1.121
listener_port: "1434"
+ needs_mcd: False
- object: jms_template
class: springpython.jms.core.JmsTemplate
@@ -613,7 +626,7 @@ for encoding into UTF-8::
queue1 = "TEST.1"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
jms_template = JmsTemplate(factory)
@@ -679,7 +692,7 @@ destination can be specified for an outgoing message::
queue1 = "TEST.1"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
jms_template = JmsTemplate(factory)
@@ -714,7 +727,7 @@ jms_timestamp and jms_message_id properties::
queue1 = "TEST.1"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
jms_template = JmsTemplate(factory)
@@ -765,7 +778,7 @@ can explicitly specify the destination's name when you receive messages::
queue2 = "TEST.2"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Every JmsTemplate uses a connection factory for actually communicating with a JMS provider.
jms_template = JmsTemplate(factory)
@@ -831,7 +844,7 @@ default with Spring Python::
exchange_queue = "TEST.1"
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
requesting_side = JmsTemplate(factory)
requesting_side.default_destination = exchange_queue
@@ -958,7 +971,7 @@ requests and responses using only one converter object::
return invoice
# The connection factory we're going to use.
- factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port)
+ factory = WebSphereMQConnectionFactory(qm_name, channel, host, listener_port, needs_mcd=False)
# Our JmsTemplate.
jms_template = JmsTemplate(factory)
@@ -1058,6 +1071,7 @@ has been set::
channel: SVRCONN.1
host: 192.168.1.121
listener_port: "1434"
+ needs_mcd: False
- object: message_handler
class: app.MyMessageHandler
@@ -99,7 +99,7 @@ class WebSphereMQConnectionFactory(DisposableObject):
def __init__(self, queue_manager=None, channel=None, host=None, listener_port=None,
cache_open_send_queues=True, cache_open_receive_queues=True,
use_shared_connections=True, dynamic_queue_template="SYSTEM.DEFAULT.MODEL.QUEUE",
- ssl=False, ssl_cipher_spec=None, ssl_key_repository=None):
+ ssl=False, ssl_cipher_spec=None, ssl_key_repository=None, needs_mcd=True):
self.queue_manager = queue_manager
self.channel = channel
self.host = host
@@ -112,6 +112,9 @@ def __init__(self, queue_manager=None, channel=None, host=None, listener_port=No
self.ssl = ssl
self.ssl_cipher_spec = ssl_cipher_spec
self.ssl_key_repository = ssl_key_repository
+
+ # WMQ >= 7.0 must not use the mcd folder
+ self.needs_mcd = needs_mcd
self.logger = logging.getLogger("springpython.jms.factory.WebSphereMQConnectionFactory")
@@ -269,7 +272,7 @@ def send(self, message, destination):
# Create MQRFH2 header
now = long(time() * 1000)
- mqrfh2jms = MQRFH2JMS().build_header(message, destination, self.CMQC, now)
+ mqrfh2jms = MQRFH2JMS(self.needs_mcd).build_header(message, destination, self.CMQC, now)
buff.write(mqrfh2jms)
if message.text != None:
@@ -425,7 +428,7 @@ def _get_jms_timestamp_from_md(self, put_date, put_time):
def _build_text_message(self, md, message):
self.logger.log(TRACE1, "Building a text message [%r], md [%r]" % (repr(message), repr(md)))
- mqrfh2 = MQRFH2JMS()
+ mqrfh2 = MQRFH2JMS(self.needs_mcd)
mqrfh2.build_folders_and_payload_from_message(message)
jms_folder = mqrfh2.folders.get("jms", None)
@@ -630,7 +633,12 @@ class MQRFH2JMS(object):
# Size of a folder header is always 4 bytes.
FOLDER_SIZE_HEADER_LENGTH = 4
- def __init__(self):
+ def __init__(self, needs_mcd=True):
+
+ # Whether to add the mcd folder. Needs to be False for everything to
+ # work properly with WMQ >= 7.0
+ self.needs_mcd = needs_mcd
+
self.folders = {}
self.payload = None
@@ -682,19 +690,29 @@ def build_folder(self, raw_folder):
folder = etree.fromstring(raw_folder)
root_name = folder.tag
+
+ root_names = ["jms", "usr"]
+ if self.needs_mcd:
+ root_names.append("mcd")
- if root_name in("mcd", "jms", "usr"):
+ if root_name in root_names:
self.folders[root_name] = folder
else:
self.logger.warn("Ignoring unrecognized JMS folder [%s]=[%s]" % (root_name, raw_folder))
def build_header(self, message, queue_name, CMQC, now):
- self.folders["mcd"] = _mcd
+
+ if self.needs_mcd:
+ self.folders["mcd"] = _mcd
+ mcd = self._pad_folder(etree.tostring(self.folders["mcd"]))
+ mcd_len = len(mcd)
+ else:
+ mcd_len = 0
+
self.add_jms(message, queue_name, now)
self.add_usr(message)
- mcd = self._pad_folder(etree.tostring(self.folders["mcd"]))
jms = self._pad_folder(etree.tostring(self.folders["jms"]))
if "usr" in self.folders:
@@ -703,7 +721,6 @@ def build_header(self, message, queue_name, CMQC, now):
else:
usr_len = 0
- mcd_len = len(mcd)
jms_len = len(jms)
total_header_length = 0
@@ -725,8 +742,11 @@ def build_header(self, message, queue_name, CMQC, now):
buff.write(CMQC.MQFMT_STRING)
buff.write(_WMQ_MQRFH_NO_FLAGS_WIRE_FORMAT)
buff.write(_WMQ_DEFAULT_CCSID_WIRE_FORMAT)
- buff.write(pack("!l", mcd_len))
- buff.write(mcd)
+
+ if self.needs_mcd:
+ buff.write(pack("!l", mcd_len))
+ buff.write(mcd)
+
buff.write(pack("!l", jms_len))
buff.write(jms)
@@ -1683,3 +1683,14 @@ def testSimpleMessageListenerContainerMessageHandler(self):
handler.handle("foo")
except NotImplementedError, e:
self.assertEquals(e.message, "Should be overridden by subclasses.")
+
+ def testNeedsMCD(self):
+ message = TextMessage(get_rand_string(12))
+ destination = get_rand_string(12)
+ now = long(time() * 1000)
+
+ has_mcd = MQRFH2JMS(True).build_header(message, destination, CMQC, now)
+ has_no_mcd = MQRFH2JMS(False).build_header(message, destination, CMQC, now)
+
+ self.assertTrue('mcd' in has_mcd)
+ self.assertTrue('mcd' not in has_no_mcd)

0 comments on commit 363555d

Please sign in to comment.