def test_close_failed(self): url = 'test-url' c = Connection(url) impl = Mock() impl.close.side_effect = ValueError c._impl = impl c.close()
def test_open(self, connection, find, add_transports, ssl_domain): url = TEST_URL connector = Connector(url) connector.ssl.ca_certificate = 'test-ca' connector.ssl.client_key = 'test-key' connector.ssl.client_certificate = 'test-crt' connector.heartbeat = '4' find.return_value = connector ssl_properties = {'A': 1, 'B': 2} ssl_domain.return_value = ssl_properties # test c = Connection(url) c._ssh = Mock() c.open() # validation add_transports.assert_called_once_with() connection.assert_called_once_with( host=connector.host, port=connector.port, tcp_nodelay=True, transport=connector.scheme, username=connector.userid, password=connector.password, heartbeat=connector.heartbeat, **ssl_properties) ssl_domain.assert_called_once_with(connector) c._impl.open.assert_called_once_with() self.assertEqual(c._impl, connection.return_value)
def test_add_transports(self): transports = {'tcp': Mock(), 'ssl': Mock()} with patch('gofer.messaging.adapter.qpid.connection.TRANSPORTS', transports): Connection.add_transports() self.assertEqual(transports['amqp'], transports['tcp']) self.assertEqual(transports['amqps'], transports['ssl'])
def test_open(self, connection, find, add_transports, ssl_domain): url = TEST_URL connector = Connector(url) connector.ssl.ca_certificate = 'test-ca' connector.ssl.client_key = 'test-key' connector.ssl.client_certificate = 'test-crt' connector.heartbeat = '4' find.return_value = connector ssl_properties = {'A': 1, 'B': 2} ssl_domain.return_value = ssl_properties # test c = Connection(url) c._ssh = Mock() c.open() # validation add_transports.assert_called_once_with() connection.assert_called_once_with(host=connector.host, port=connector.port, tcp_nodelay=True, transport=connector.scheme, username=connector.userid, password=connector.password, heartbeat=connector.heartbeat, **ssl_properties) ssl_domain.assert_called_once_with(connector) c._impl.open.assert_called_once_with() self.assertEqual(c._impl, connection.return_value)
def test_close(self): url = 'test-url' c = Connection(url) impl = Mock() c._impl = impl c.close() impl.close.assert_called_once_with() self.assertEqual(c._impl, None)
def __init__(self, url): """ :param url: The broker url. :type url: str """ BaseSender.__init__(self, url) self.connection = Connection(url) self.session = None
def test_add_transports(self): transports = { 'tcp': Mock(), 'ssl': Mock() } with patch('gofer.messaging.adapter.qpid.connection.TRANSPORTS', transports): Connection.add_transports() self.assertEqual(transports['amqp'], transports['tcp']) self.assertEqual(transports['amqps'], transports['ssl'])
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.session = None self.sender = None self.receiver = None self.reply_to = REPLY_TO % uuid4()
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.session = None self.receiver = None
def test_ssl_domain(self, validate): url = TEST_URL # test b = Connector(url) b.ssl.ca_certificate = 'test-ca' b.ssl.client_key = 'test-key' b.ssl.client_certificate = 'test-crt' ssl = Connection.ssl_domain(b) # validation validate.assert_called_once_with() self.assertEqual( ssl, { 'ssl_trustfile': b.ssl.ca_certificate, 'ssl_keyfile': b.ssl.client_key, 'ssl_certfile': b.ssl.client_certificate, 'ssl_skip_hostname_check': (not b.ssl.host_validation) })
class Sender(BaseSender): """ An AMQP message sender. """ def __init__(self, url): """ :param url: The broker url. :type url: str """ BaseSender.__init__(self, url) self.connection = Connection(url) self.session = None def is_open(self): """ Get whether the sender has been opened. :return: True if open. :rtype bool """ return self.session is not None @reliable def open(self): """ Open the sender. """ if self.is_open(): # already opened return self.connection.open() self.session = self.connection.session() def repair(self): """ Repair the sender. """ self.close() self.connection.close() self.connection.open() self.session = self.connection.session() def close(self): """ Close the reader. """ session = self.session self.session = None try: session.close() except Exception: pass @reliable def send(self, address, content, ttl=None): """ Send a message. :param address: An AMQP address. :type address: str :param content: The message content :type content: buf :param ttl: Time to Live (seconds) :type ttl: float """ sender = self.session.sender(address) try: message = Message(content=content, durable=self.durable, ttl=ttl) sender.send(message) log.debug('sent (%s)', address) finally: sender.close()
class Method(Messenger): """ QMF method. :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 session: An AMQP session. :type session: qpid.messaging.Session. :ivar sender: A message sender. :type sender: qpid.messaging.Sender :ivar receiver: A message sender. :type receiver: qpid.messaging.Receiver """ 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.session = None self.sender = None self.receiver = None self.reply_to = REPLY_TO % uuid4() @property def content(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' } 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.session = self.connection.session() self.sender = self.session.sender(ADDRESS) self.receiver = self.session.receiver(self.reply_to) def repair(self): """ Repair the connection and get a sender and receiver. """ self.close() self.connection.close() self.connection.open() self.session = self.connection.session() self.sender = self.session.sender(ADDRESS) self.receiver = self.session.receiver(self.reply_to) def close(self): """ Close the sender and receiver. """ session = self.session self.session = None sender = self.sender self.sender = None receiver = self.receiver self.receiver = None try: receiver.close() except Exception: pass try: sender.close() except Exception: pass try: session.close() except Exception: pass def on_reply(self, reply): """ Process the QMF reply. :param reply: The reply. :type reply: Message :raise: Error on failures. """ opcode = reply.properties['qmf.opcode'] if opcode != '_exception': # succeeded return body = reply.content values = body['_values'] code = values['error_code'] description = values['error_text'] if code == EEXIST: return raise Error(description, code) @reliable def __call__(self): """ Invoke the method. :raise: Error on failure. """ self.open() try: request = Message( content=self.content, reply_to=self.reply_to, properties=self.properties, correlation_id=utf8(uuid4()), subject=SUBJECT) self.sender.send(request) reply = self.receiver.fetch() self.session.acknowledge() self.on_reply(reply) finally: self.close()
class Reader(BaseReader): """ An AMQP message reader. :ivar receiver: An AMQP receiver to read. :type receiver: qpid.messaging.Receiver """ 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.session = None 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. :raise: NotFound """ if self.is_open(): # already open return self.connection.open() self.session = self.connection.session() self.receiver = self.session.receiver(self.node.address) def repair(self): """ Repair the reader. :raise: NotFound """ self.close() self.connection.close() self.connection.open() self.session = self.connection.session() self.receiver = self.session.receiver(self.node.address) def close(self): """ Close the reader. """ receiver = self.receiver self.receiver = None session = self.session self.session = None try: receiver.close() except Exception: pass try: session.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.fetch(timeout or NO_DELAY) return Message(self, impl, impl.content) except Empty: pass @reliable def ack(self, message): """ Acknowledge all messages received on the session. :param message: The message to acknowledge. :type message: qpid.messaging.Message """ self.session.acknowledge(message=message) @reliable def reject(self, message, requeue=True): """ Reject the specified message. :param message: The message to reject. :type message: qpid.messaging.Message :param requeue: Requeue the message or discard it. :type requeue: bool """ if requeue: disposition = Disposition(RELEASED) else: disposition = Disposition(REJECTED) self.session.acknowledge(message=message, disposition=disposition)
def test_open_already(self): url = TEST_URL c = Connection(url) c._impl = Mock() c.open() self.assertFalse(c._impl.open.called)
def test_session(self): url = TEST_URL c = Connection(url) c._impl = Mock() session = c.session() self.assertEqual(session, c._impl.session.return_value)
def test_init(self): url = TEST_URL c = Connection(url) self.assertTrue(isinstance(c, BaseConnection)) self.assertEqual(c.url, url)