Files
amq-adapter-python/amqp/service/amq_service.py
T

113 lines
4.6 KiB
Python

import logging
import logging.config
import os
import asyncio
from asyncio import Future
from aio_pika.abc import AbstractRobustExchange
from amqp.adapter.data_message_factory import DataMessageFactory
from amqp.adapter.amq_route_factory import AMQRouteFactory
from amqp.adapter.service_message_factory import ServiceMessageFactory
from amqp.config.amq_configuration import AMQConfiguration
from amqp.model.model import DataMessage
from amqp.rabbitmq.rabbit_mq_client import RabbitMQClient
from amqp.service.amq_message_handler import DataMessageHandler
from amqp.service.tracing import initialize_trace
logging.basicConfig(level=logging.DEBUG)
logging.info(f"CWD = {os.getcwd()}")
logging_conf_path = os.path.join(os.getcwd(), "amqp", "service", "logging.conf")
if os.path.exists(logging_conf_path):
logging.config.fileConfig(logging_conf_path)
else:
logging_conf_path = os.path.join(os.getcwd(), "logging.conf")
if os.path.exists(logging_conf_path):
logging.config.fileConfig(logging_conf_path)
class AMQService:
CLEVER_AMQP_CLIENT_VERSION = os.getenv("CLEVER_AMQP_CLIENT_VERSION")
MAX_WAIT = 300 # defaults to 5 minutes (300 seconds)
def __init__(self, amq_configuration: AMQConfiguration, service_adapter):
logging.info("***********************************************")
logging.info("********** AMQ Service *******************")
logging.info("***********************************************")
self.loop = asyncio.get_event_loop()
self.amq_configuration = amq_configuration
self.data_message_factory = DataMessageFactory.get_instance(
self.amq_configuration.amq_adapter.generator_id
)
self.rabbit_mq_client = RabbitMQClient(self.amq_configuration)
self.tracer = initialize_trace(name=amq_configuration.amq_adapter.service_name)
self.amq_data_message_handler = None
self.service_message_factory = ServiceMessageFactory(
self.amq_configuration.amq_adapter.service_name
)
# self.init(loop) will initialize RabbitMQ connection
self.loop.run_until_complete(self.init(self.loop, service_adapter))
logging.info("***********************************************")
logging.info("****** AMQ Service Init Complete *********")
logging.info("***********************************************")
self.loop.run_forever()
async def init(self, loop, service_adapter):
_reply_to_exchange: AbstractRobustExchange = await self.rabbit_mq_client.init(
loop
)
self.amq_data_message_handler = DataMessageHandler(
service_adapter,
self.tracer,
self.data_message_factory,
self.service_message_factory,
_reply_to_exchange,
self.rabbit_mq_client,
self.amq_configuration,
loop=loop,
)
await self.register_routes()
await self.rabbit_mq_client.request_routes()
def cleanup(self):
logging.info(" [DBG] AMQService.cleanup() rmqc=%s", self.rabbit_mq_client)
if self.rabbit_mq_client:
self.rabbit_mq_client.cleanup()
async def reinitialize_if_disconnected(self):
if not self.rabbit_mq_client.channel or self.rabbit_mq_client.channel.is_closed:
self.rabbit_mq_client = RabbitMQClient(self.amq_configuration)
await self.rabbit_mq_client.init(loop=self.loop)
await self.register_routes()
await self.rabbit_mq_client.request_routes()
async def register_routes(self) -> AbstractRobustExchange | None:
route_mapping = self.amq_configuration.amq_adapter.route_mapping
if AMQRouteFactory.validate(route_mapping):
try:
await self.rabbit_mq_client.register_inbound_routes(
route_mapping,
self.amq_data_message_handler.inbound_data_message_callback,
)
return await self.rabbit_mq_client.register_data_reply_callback(
self.amq_data_message_handler.reply_received_callback
)
except Exception as e:
raise RuntimeError(e)
elif route_mapping:
logging.info(
" [W] route [%s] failed validation, no routes were registered.",
route_mapping,
)
return None
def send_message(self, message: DataMessage, future: Future):
self.amq_data_message_handler.outstanding[str(message.id)] = future
def remove_outstanding_future(self, message_id: str):
self.amq_data_message_handler.outstanding.pop(message_id, None)