def test_register_handler_subscription(self): src = entry_point.EntryPointFactory().create("src_service.src_method") dst = entry_point.EntryPointFactory().create("dst_service.rpl_method") @dispatcher.rpc_service(dst.service) class SomeControllerClass(service.ServiceController): @dispatcher.subscription_method(service=src.service, method=src.method) def handler(self): pass headers = { "source": str(src), "destination": "", "reply_to": "", "correlation_id": "123", "message_type": "notification" } context = {} payload = {} message = messages.IncomingNotification(headers, context, payload) service_classes = router.Router().get_subscription_cls(message) self.assertEqual(service_classes, [SomeControllerClass]) controller = SomeControllerClass(mock.MagicMock()) disp = controller.get_dispatcher() handler = controller.get_dispatcher().get_handler( disp._get_dispatching_entry_point(message), "notification") self.assertEqual("handler", handler)
def __init__(self, headers, context, payload): super(Message, self).__init__() if not headers.get("message_id"): headers["message_id"] = uuid.uuid4().hex self.correlation_id = headers.get("correlation_id") self.request_id = headers.get("request_id") self.message_id = headers.get("message_id") self.message_type = headers.get("message_type") self.reply_to = entry_point.EntryPointFactory().create( headers.get("reply_to")) self.source = entry_point.EntryPointFactory().create( headers.get("source"), source=True) self.destination = entry_point.EntryPointFactory().create( headers.get("destination"), destination=True) self._headers = copy.copy(headers) self._context = context or {} self._payload = payload if not isinstance(self.source, entry_point.EntryPoint): raise TypeError('source must be EntryPoint') if not isinstance(payload, dict): raise TypeError('payload must be dict, received {}'.format( type(payload)))
def create(self, amqp_message): """ Create corresponding message object by AMQP message :param amqp_message: AMQP message :type amqp_message: messages.AMQPMessage :return: message object :rtype: messages.Message """ headers = amqp_message.headers reply_to = entry_point.EntryPointFactory().create(headers["reply_to"]) message_cls = self.get_class(headers["message_type"], reply_to) body = amqp_message.body_deserialize() payload = body["payload"] context = body["context"] if issubclass(message_cls, IncomingRequestCall): return self._create_request_call(headers, context, payload) elif issubclass(message_cls, Error): return self._create_error(headers, context, payload) elif issubclass(message_cls, IncomingNotification): return self.create_notification(headers, context, payload) else: return self._create_message(message_cls, headers, context, payload)
def get_request_entry_services(self): """ Generates entry points for requests :return: generator of EntryPoints """ for ep in self._handlers["request"].keys(): yield entry_point.EntryPointFactory().create(ep).service
def get_publishers(self): """ Generates entry points for notifications :return: generator of EntryPoints """ for ep in self.subscriptions.keys(): yield entry_point.EntryPointFactory().create(ep)
def __getattr__(self, item): if isinstance(self._source, entry_point.EntryPoint): source = self._source else: source = entry_point.EntryPointFactory().create(self._source) postproc = self._get_postprocessor() proxy = proxies.RPCProxy(postproc, source, context=self._context, headers=self._headers) return getattr(proxy, item)
def _send(self, message): """ Sends AMQP message to exchange via writer :param message: AMQP message to send :type message: messages.AMQPMessage :return: """ discovery_service = self.discovery_service if message.headers["message_type"] == "notification": source = message.headers["source"] ep = entry_point.EntryPointFactory().create(source) exchange = discovery_service.get_local_publisher(ep.service) elif message.headers["message_type"] in ("response", "error"): rk = message.headers["destination"] ep = entry_point.EntryPointFactory().create(rk) exchange = discovery_service.get_remote(ep.service) else: dst = message.headers["destination"] ep = entry_point.EntryPointFactory().create(dst) exchange = discovery_service.get_remote(ep.service) routing_key = ep.to_routing_key() self._driver.publish_message(exchange, routing_key, message)
def _get_source_context(self, message, service_instance): """ Prepares 'source' value for RPC proxy :param message: incoming message :type message: Message :param service_instance: Service controller instance :type service_instance: service.ServiceController :rtype: EntryPoint """ if isinstance(message, (messages.IncomingError, messages.IncomingResponse)): return message.destination elif isinstance(message, messages.IncomingNotification): return entry_point.EntryPointFactory().create( service_instance.service_name) else: return message.destination
def test_process_notification_by_service_instance(self, create_proxy_mock): """ Tests that service instance processes message """ headers = { "source": "src_service.src_method", "destination": "dst_service.dst_method", "reply_to": "rpl_service.rpl_method", "correlation_id": "123", "message_type": "notification" } context = {} payload = {} service_instance = mock.MagicMock() msg = messages.IncomingNotification(headers, context, payload) ep = entry_point.EntryPointFactory().create(msg.source) message_type = "notification" method_name = "some_handler" self.dispatcher.register(ep, message_type, method_name) res = self.dispatcher.process(msg, service_instance) service_instance.process.assert_called_once_with( method_name, msg, create_proxy_mock()) self.assertEqual(res, service_instance.process())
def setUp(self): super(EntryPointFactoryTestCase, self).setUp() self.ep_factory = entry_point.EntryPointFactory()