Esempio n. 1
0
async def test_amqp_reconnection_success():
    connection = AMQPConnection(**amqp_config)
    await connection.connect(reconnect_timeout=20)

    assert connection.is_connected()
    await connection.close()
    assert not connection.is_connected()
Esempio n. 2
0
def aconnection(event_loop):
    connection = AMQPConnection(ioloop=event_loop, **amqp_config)
    coroutine = connection.connect()
    event_loop.run_until_complete(coroutine)
    yield connection
    coroutine = connection.close()
    event_loop.run_until_complete(coroutine)
Esempio n. 3
0
 async def connect_to_amqp(self):
     """Try to connect to the AMQP broker."""
     self._status = StatusCodes.CONNECTING
     rabbitmq_config = await self.get_rabbitmq_configuration()
     await self.set_queues_prefix_iostreams()
     self.amqp_connection = AMQPConnection(
         **rabbitmq_config,
         ioloop=self.loop,
         on_error_callback=self.on_error_callback)
     await self.amqp_connection.connect(
         rabbitmq_config["connection_timeout"])
Esempio n. 4
0
async def test_amqp_reconnection_fail(event_loop):
    with mock.patch(
        "tamarco_amqp.connection.AMQPConnection._connect_to_amqp_broker",
        new_callable=ConnectionAsyncMock,
        side_effect=sleep_and_raise_socket_error,
    ) as initialize:
        reconnect_timeout = 1
        connection = AMQPConnection(ioloop=event_loop)
        with pytest.raises(ConnectionError):
            await connection.connect(reconnect_timeout=reconnect_timeout)
        initialize.assert_called()
        assert not connection.is_connected()
Esempio n. 5
0
async def test_register_without_connecting():
    @AMQPPullInput(queue="cat")
    async def cat_consumer(message):
        pass

    conn = AMQPConnection(**amqp_config)
    await conn.register(cat_consumer)
    await conn.connect()
    assert cat_consumer in conn.inputs
Esempio n. 6
0
class AMQPResource(IOResource):
    depends_on = []
    loggers_names = ["tamarco.amqp"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.logger = logging.getLogger("tamarco.amqp")
        self.amqp_connection = None
        self.task_manager = TasksManager()
        self.loop = asyncio.get_event_loop()

    async def get_rabbitmq_configuration(self):
        rabbitmq_config = {
            "host": await self.settings.get("host"),
            "port": await self.settings.get("port"),
            "vhost": await self.settings.get("vhost"),
            "user": await self.settings.get("user"),
            "password": await self.settings.get("password"),
            "connection_timeout": await
            self.settings.get("connection_timeout"),
            "queues_prefix": await self.settings.get("queues_prefix", ""),
        }
        return rabbitmq_config

    async def bind(self, *args, **kwargs):
        await super().bind(*args, **kwargs)
        self.task_manager.set_loop(self.microservice.loop)
        self.loop = self.microservice.loop

    async def connect_to_amqp(self):
        """Try to connect to the AMQP broker."""
        self._status = StatusCodes.CONNECTING
        rabbitmq_config = await self.get_rabbitmq_configuration()
        await self.set_queues_prefix_iostreams()
        self.amqp_connection = AMQPConnection(
            **rabbitmq_config,
            ioloop=self.loop,
            on_error_callback=self.on_error_callback)
        await self.amqp_connection.connect(
            rabbitmq_config["connection_timeout"])

    async def on_error_callback(self, exception):
        if self._status != StatusCodes.STOPPING:
            self.logger.critical(
                f"Received error callback from AMQP connection, reporting failed status in AMQP  "
                f"resource. Exception: {exception}")
            self._status = StatusCodes.FAILED

    @property
    def io_streams(self):
        return tuple(chain(self.outputs.values(), self.inputs.values()))

    async def set_queues_prefix_iostreams(self):
        rabbitmq_config = await self.get_rabbitmq_configuration()
        prefix = rabbitmq_config["queues_prefix"]

        for io_elements in self.io_streams:
            io_elements.set_queues_prefix(prefix)
            self.logger.info(f"AMQP queues prefix: {prefix}")

    async def start(self):
        try:
            await self.connect_to_amqp()
        except ConnectionError:
            self.logger.critical(
                "AMQP resource cannot connect to RabbitMQ. Reporting failed status",
                exc_info=True)
            self._status = StatusCodes.FAILED
        else:
            try:
                await self.amqp_connection.register(*self.io_streams)
            except Exception:
                self.logger.critical(
                    "Error registering handlers in AMQP resource. Reporting failed status",
                    exc_info=True)
                self._status = StatusCodes.FAILED
            else:
                for input_element in self.inputs.values():
                    self.register_on_message_callback_trigger_task(
                        input_element)
                await super().start()

    async def post_start(self):
        self.task_manager.start_all()
        await super().post_start()

    def register_on_message_callback_trigger_task(self, new_input):
        """Register a task that reads the messages from amqp. This task triggers others tasks.

        Args:
            new_input: AMQP input where to read messages.
        """
        input_name = new_input.name
        task_name = f"callback_trigger_{input_name}"
        if new_input.on_message_callback:
            self.task_manager.register_task(
                task_name, new_input.callback_trigger(self.task_manager))

    async def stop(self):
        self.logger.info(f"Stopping AMQP resource")
        if self._status == StatusCodes.STARTED:
            self._status = StatusCodes.STOPPING
            await self.amqp_connection.close()
        self.task_manager.stop_all()
        await super().stop()

    async def status(self):
        status = {"status": self._status}
        if self._status == StatusCodes.STARTED:
            connection_status = self.amqp_connection.is_connected()
            amqp_configuration = self.amqp_connection.conn_parameters
            inputs = [str(amqp_input) for amqp_input in self.inputs]
            outputs = [str(amqp_output) for amqp_output in self.outputs]
            status.update({
                "connection_status": connection_status,
                "amqp_config": amqp_configuration,
                "inputs": inputs,
                "outputs": outputs,
            })
        return status
Esempio n. 7
0
async def test_bad_connection():
    incorrect_ip = "192.168.10.1"
    conn = AMQPConnection(host=incorrect_ip)
    with pytest.raises(ConnectionError):
        await conn.connect(reconnect_timeout=0)
Esempio n. 8
0
async def test_publish_without_connecting():
    with pytest.raises(Exception):
        conn = AMQPConnection()
        await conn._publish(None, None, None, None)