def test_dynamic_receiver(self, uuid, properties): url = 'test-url' address = 'test' uuid.return_value = '1234' connection = Connection(url) connection._impl = Mock() # test receiver = connection.receiver(address, dynamic=True) # validation properties.assert_called_once_with({'x-opt-qd.address': address}) connection._impl.create_receiver.assert_called_once_with( None, dynamic=True, name=uuid.return_value, options=properties.return_value) self.assertEqual(receiver, connection._impl.create_receiver.return_value)
def test_receiver(self, uuid, properties): url = 'test-url' address = 'test' uuid.return_value = '1234' connection = Connection(url) connection._impl = Mock() # test receiver = connection.receiver(address) # validation connection._impl.create_receiver.assert_called_once_with( address, dynamic=False, name=uuid.return_value, options=None) self.assertEqual(receiver, connection._impl.create_receiver.return_value) self.assertFalse(properties.called)
def test_receiver(self, uuid, properties): url = 'test-url' address = 'test' uuid.return_value = '1234' connection = Connection(url) connection._impl = Mock() # test receiver = connection.receiver(address) # validation connection._impl.create_receiver.assert_called_once_with( address, dynamic=False, name=uuid.return_value, options=None) self.assertEqual(receiver, connection._impl.create_receiver.return_value) self.assertFalse(properties.called)
def test_dynamic_receiver(self, uuid, properties): url = 'test-url' address = 'test' uuid.return_value = '1234' connection = Connection(url) connection._impl = Mock() # test receiver = connection.receiver(address, dynamic=True) # validation properties.assert_called_once_with({'x-opt-qd.address': address}) connection._impl.create_receiver.assert_called_once_with( None, dynamic=True, name=uuid.return_value, options=properties.return_value) self.assertEqual(receiver, connection._impl.create_receiver.return_value)
class Reader(BaseReader): """ An AMQP message reader. :ivar connection: A proton connection :type connection: Connection :ivar receiver: An AMQP receiver to read. :type receiver: proton.utils.BlockingReceiver """ def __init__(self, node, url): """ :param node: The AMQP node to read. :type node: gofer.messaging.adapter.model.Node :param url: The broker url. :type url: str :see: gofer.messaging.adapter.url.URL """ BaseReader.__init__(self, node, url) self.connection = Connection(url) self.receiver = None def is_open(self): """ Get whether the messenger has been opened. :return: True if open. :rtype bool """ return self.receiver is not None @reliable def open(self): """ Open the reader. """ if self.is_open(): # already open return self.connection.open() self.receiver = self.connection.receiver(self.node.address) def repair(self): """ Repair the reader. """ self.close() self.connection.close() self.connection.open() self.receiver = self.connection.receiver(self.node.address) def close(self): """ Close the reader. :raise: NotFound """ receiver = self.receiver self.receiver = None try: receiver.close() except Exception: pass @reliable def get(self, timeout=None): """ Get the next message from the queue. :param timeout: The read timeout in seconds. :type timeout: int :return: The next message or None. :rtype: Message """ try: impl = self.receiver.receive(timeout or NO_DELAY) return Message(self, impl, impl.body) except Timeout: pass @reliable def ack(self, message): """ Acknowledge all messages received on the session. :param message: The message to acknowledge. :type message: proton.Message """ self.receiver.accept() @reliable def reject(self, message, requeue=True): """ Reject the specified message. :param message: The message to reject. :type message: proton.Message :param requeue: Requeue the message or discard it. :type requeue: bool """ if requeue: self.receiver.release() else: self.receiver.reject()
class Reader(BaseReader): """ An AMQP message reader. :ivar connection: A proton connection :type connection: Connection :ivar receiver: An AMQP receiver to read. :type receiver: proton.utils.BlockingReceiver """ def __init__(self, node, url): """ :param node: The AMQP node to read. :type node: gofer.messaging.adapter.model.Node :param url: The broker url. :type url: str :see: gofer.messaging.adapter.url.URL """ BaseReader.__init__(self, node, url) self.connection = Connection(url) self.receiver = None def is_open(self): """ Get whether the messenger has been opened. :return: True if open. :rtype bool """ return self.receiver is not None @reliable def open(self): """ Open the reader. """ if self.is_open(): # already open return self.connection.open() self.receiver = self.connection.receiver(self.node.address) def repair(self): """ Repair the reader. """ self.close() self.connection.close() self.connection.open() self.receiver = self.connection.receiver(self.node.address) def close(self): """ Close the reader. :raise: NotFound """ receiver = self.receiver self.receiver = None try: receiver.close() except Exception: pass @reliable def get(self, timeout=None): """ Get the next message from the queue. :param timeout: The read timeout in seconds. :type timeout: int :return: The next message or None. :rtype: Message """ try: impl = self.receiver.receive(timeout or NO_DELAY) return Message(self, impl, impl.body) except Timeout: pass @reliable def ack(self, message): """ Acknowledge all messages received on the session. :param message: The message to acknowledge. :type message: proton.Message """ self.receiver.accept() @reliable def reject(self, message, requeue=True): """ Reject the specified message. :param message: The message to reject. :type message: proton.Message :param requeue: Requeue the message or discard it. :type requeue: bool """ if requeue: self.receiver.release() else: self.receiver.reject()
class Method(Messenger): """ QMF method. :ivar url: The broker url. :type url: str :ivar name: The method name. :type name: str :ivar arguments: The method arguments. :type arguments: dict :ivar connection: A broker connection. :type connection: Connection :ivar sender: A message sender. :type sender: proton.utils.BlockingSender :ivar receiver: A message sender. :type receiver: proton.utils.BlockingReceiver """ def __init__(self, url, name, arguments): """ :param url: The broker url. :type url: str :param name: The method name. :type name: str :param arguments: The method arguments. :type arguments: dict """ super(Method, self).__init__(url) self.name = name self.arguments = arguments self.connection = Connection(url) self.sender = None self.receiver = None @property def body(self): return { '_object_id': OBJECT_ID, '_method_name': self.name, '_arguments': self.arguments } @property def properties(self): return { 'qmf.opcode': '_method_request', 'x-amqp-0-10.app-id': 'qmf2', 'method': 'request' } @resend def send(self, request): """ Send the request. :param request: A QMF request. """ self.sender.send(request) def on_reply(self, reply): """ Process the QMF reply. :param reply: The reply. :type reply: Message :raise: Error on failures. """ body = dict(reply.body) opcode = reply.properties['qmf.opcode'] if opcode != '_exception': # succeeded return values = body['_values'] code = values['error_code'] description = values['error_text'] if code == EEXIST: return raise Error(description, code) def is_open(self): """ Get whether the method is open. :return: True if open. :rtype: bool """ return self.sender is not None def open(self): """ Open a connection and get a sender and receiver. """ if self.is_open(): # already open return self.connection.open() self.receiver = self.connection.receiver(ADDRESS, dynamic=True) self.sender = self.connection.sender(ADDRESS) def repair(self): """ Repair the connection and get a sender and receiver. """ self.close() self.connection.close() self.connection.open() self.receiver = self.connection.receiver(ADDRESS, dynamic=True) self.sender = self.connection.sender(ADDRESS) def close(self): """ Close the sender and receiver. """ sender = self.sender self.sender = None receiver = self.receiver self.receiver = None try: sender.close() except Exception: pass try: receiver.close() except Exception: pass @reliable def __call__(self): """ Invoke the method. :raise: Error on failure. """ self.open() try: reply_to = self.receiver.remote_source.address request = Message(body=self.body, reply_to=reply_to, properties=self.properties, correlation_id=utf8(uuid4()), subject=SUBJECT) self.send(request) reply = self.receiver.receive() self.on_reply(reply) finally: self.close()
class Method(Messenger): """ QMF method. :ivar url: The broker url. :type url: str :ivar name: The method name. :type name: str :ivar arguments: The method arguments. :type arguments: dict :ivar connection: A broker connection. :type connection: Connection :ivar sender: A message sender. :type sender: proton.utils.BlockingSender :ivar receiver: A message sender. :type receiver: proton.utils.BlockingReceiver """ def __init__(self, url, name, arguments): """ :param url: The broker url. :type url: str :param name: The method name. :type name: str :param arguments: The method arguments. :type arguments: dict """ super(Method, self).__init__(url) self.name = name self.arguments = arguments self.connection = Connection(url) self.sender = None self.receiver = None @property def body(self): return { '_object_id': OBJECT_ID, '_method_name': self.name, '_arguments': self.arguments } @property def properties(self): return { 'qmf.opcode': '_method_request', 'x-amqp-0-10.app-id': 'qmf2', 'method': 'request' } @resend def send(self, request): """ Send the request. :param request: A QMF request. """ self.sender.send(request) def on_reply(self, reply): """ Process the QMF reply. :param reply: The reply. :type reply: Message :raise: Error on failures. """ body = dict(reply.body) opcode = reply.properties['qmf.opcode'] if opcode != '_exception': # succeeded return values = body['_values'] code = values['error_code'] description = values['error_text'] if code == EEXIST: return raise Error(description, code) def is_open(self): """ Get whether the method is open. :return: True if open. :rtype: bool """ return self.sender is not None def open(self): """ Open a connection and get a sender and receiver. """ if self.is_open(): # already open return self.connection.open() self.receiver = self.connection.receiver(ADDRESS, dynamic=True) self.sender = self.connection.sender(ADDRESS) def repair(self): """ Repair the connection and get a sender and receiver. """ self.close() self.connection.close() self.connection.open() self.receiver = self.connection.receiver(ADDRESS, dynamic=True) self.sender = self.connection.sender(ADDRESS) def close(self): """ Close the sender and receiver. """ sender = self.sender self.sender = None receiver = self.receiver self.receiver = None try: sender.close() except Exception: pass try: receiver.close() except Exception: pass @reliable def __call__(self): """ Invoke the method. :raise: Error on failure. """ self.open() try: reply_to = self.receiver.remote_source.address request = Message( body=self.body, reply_to=reply_to, properties=self.properties, correlation_id=utf8(uuid4()), subject=SUBJECT) self.send(request) reply = self.receiver.receive() self.on_reply(reply) finally: self.close()