Skip to content

Commit

Permalink
Added support for multiple notification topics in NotificationReceiver
Browse files Browse the repository at this point in the history
In order to receive notificatins for multiple notification topic
types (e.g. both audit-notification and security-notification),
it was necessary to add support for specifying mnore than just
a single topic name when creating a NotificationReceiver object.

Signed-off-by: Andreas Maier <[email protected]>
  • Loading branch information
andy-maier committed Aug 6, 2019
1 parent 64e6559 commit c105d0f
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 18 deletions.
3 changes: 3 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ Released: not yet
compatibility. This allows displaying HMC timestamps in local time rather
than just UTC time.

* Added support for specifying multiple notification topics to
`zhmcclient.NotificationReceiver`.

**Known issues:**

* See `list of open issues`_.
Expand Down
55 changes: 48 additions & 7 deletions tests/unit/zhmcclient/test_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ def __init__(self, *args, **kwargs):
self._connect_userid = None
self._connect_password = None
self._connect_wait = None
self._subscribe_destination = None
self._subscribe_id = None
self._subscribe_ack = None
self._subscriptions = [] # items: tuple(dest, id, ack)
self._queued_messages = [] # items: tuple(headers, message_str)
self._sender_thread = None

Expand All @@ -70,9 +68,7 @@ def connect(self, userid, password, wait):
def subscribe(self, destination, id, ack):
"""Mocks the same-named method of stomp.Connection."""
assert self._state_connected
self._subscribe_destination = destination
self._subscribe_id = id
self._subscribe_ack = ack
self._subscriptions.append((destination, id, ack))

def disconnect(self):
"""Mocks the same-named method of stomp.Connection."""
Expand Down Expand Up @@ -123,7 +119,7 @@ def receive_notifications(receiver):
return msg_items


class TestNotification(object):
class TestNotification_OneTopic(object):

def setup_method(self):
self.topic = 'fake-topic'
Expand Down Expand Up @@ -166,3 +162,48 @@ def test_one_message(self):
msg0 = msg_items[0]
assert msg0[0] == self.std_headers
assert msg0[1] == message_obj


class TestNotification_TwoTopics(object):

def setup_method(self):
self.topics = ('fake-topic1', 'fake-topic2')
self.hmc = 'fake-hmc'
self.userid = 'fake-userid'
self.password = 'fake-password'
self.std_headers = {
'notification-type': 'fake-type'
}

@patch(target='stomp.Connection', new=MockedStompConnection)
def test_no_messages(self):
receiver = NotificationReceiver(self.topics, self.hmc, self.userid,
self.password)

conn = receiver._conn

# We do not add any STOMP messages

conn.mock_start()
msg_items = receive_notifications(receiver)

assert msg_items == []

@patch(target='stomp.Connection', new=MockedStompConnection)
def test_one_message(self):
receiver = NotificationReceiver(self.topics, self.hmc, self.userid,
self.password)
conn = receiver._conn

# Add one STOMP message to be sent
message_obj = dict(a=1, b=2)
conn.mock_add_message(self.std_headers, message_obj)

conn.mock_start()
msg_items = receive_notifications(receiver)

assert len(msg_items) == 1

msg0 = msg_items[0]
assert msg0[0] == self.std_headers
assert msg0[1] == message_obj
35 changes: 24 additions & 11 deletions zhmcclient/_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@

class NotificationReceiver(object):
"""
A class for receiving HMC notifications that are published to a particular
single HMC notification topic.
A class for receiving HMC notifications that are published to particular
HMC notification topics.
**Experimental:** This class is considered experimental at this point, and
its API may change incompatibly as long as it is experimental.
Creating an object of this class establishes a JMS session with the
HMC and subscribes for a particular HMC notification topic.
HMC and subscribes for the specified HMC notification topic(s).
Notification topic strings are created by the HMC in context of a
particular client session (i.e. :class:`~zhmcclient.Session` object).
Expand All @@ -94,11 +94,13 @@ class NotificationReceiver(object):
originally created.
"""

def __init__(self, topic, host, userid, password, port=DEFAULT_STOMP_PORT):
def __init__(self, topic_names, host, userid, password,
port=DEFAULT_STOMP_PORT):
"""
Parameters:
topic (:term:`string`): Name of the HMC notification topic.
topic_names (:term:`string` or list/tuple thereof): Name(s) of the
HMC notification topic(s).
Must not be `None`.
host (:term:`string`):
Expand All @@ -118,7 +120,9 @@ def __init__(self, topic, host, userid, password, port=DEFAULT_STOMP_PORT):
STOMP TCP port. Defaults to
:attr:`~zhmcclient._constants.DEFAULT_STOMP_PORT`.
"""
self._topic = topic
if not isinstance(topic_names, (list, tuple)):
topic_names = [topic_names]
self._topic_names = topic_names
self._host = host
self._port = port
self._userid = userid
Expand Down Expand Up @@ -149,8 +153,9 @@ def __init__(self, topic, host, userid, password, port=DEFAULT_STOMP_PORT):
self._conn.start()
self._conn.connect(self._userid, self._password, wait=True)

dest = "/topic/" + topic
self._conn.subscribe(destination=dest, id=self._sub_id, ack='auto')
for topic_name in self._topic_names:
dest = "/topic/" + topic_name
self._conn.subscribe(destination=dest, id=self._sub_id, ack='auto')

@logged_api_call
def notifications(self):
Expand All @@ -160,10 +165,18 @@ def notifications(self):
Example::
receiver = zhmcclient.NotificationReceiver(topic, hmc, userid,
password)
desired_topic_types = ('security-notification',
'audit-notification')
topics = session.get_notification_topics()
topic_names = [t['topic-name']
for t in topics
if t['topic-type'] in desired_topic_types]
receiver = zhmcclient.NotificationReceiver(
topic_names, hmc, userid, password)
for headers, message in receiver.notifications():
. . .
. . . # processing of topic-specific message format
Yields:
Expand Down

0 comments on commit c105d0f

Please sign in to comment.