async def find_inbound_connection( self, receipt: MessageReceipt) -> ConnectionRecord: """ Deserialize an incoming message and further populate the request context. Args: receipt: The message receipt Returns: The `ConnectionRecord` associated with the expanded message, if any """ cache_key = None connection = None resolved = False if receipt.sender_verkey and receipt.recipient_verkey: cache_key = (f"connection_by_verkey::{receipt.sender_verkey}" f"::{receipt.recipient_verkey}") cache: BaseCache = await self.context.inject(BaseCache, required=False) if cache: async with cache.acquire(cache_key) as entry: if entry.result: cached = entry.result receipt.sender_did = cached["sender_did"] receipt.recipient_did_public = cached[ "recipient_did_public"] receipt.recipient_did = cached["recipient_did"] connection = await ConnectionRecord.retrieve_by_id( self.context, cached["id"]) else: connection = await self.resolve_inbound_connection( receipt) if connection: cache_val = { "id": connection.connection_id, "sender_did": receipt.sender_did, "recipient_did": receipt.recipient_did, "recipient_did_public": receipt.recipient_did_public, } await entry.set_result(cache_val, 3600) resolved = True if not connection and not resolved: connection = await self.resolve_inbound_connection(receipt) return connection
async def test_handle(self): self.context.message_receipt = MessageReceipt( recipient_verkey=TEST_VERKEY) handler = test_module.ForwardHandler() responder = MockResponder() with async_mock.patch.object( test_module, "RoutingManager", autospec=True) as mock_mgr, async_mock.patch.object( test_module, "ConnectionManager", autospec=True) as mock_connection_mgr: mock_mgr.return_value.get_recipient = async_mock.CoroutineMock( return_value=RouteRecord(connection_id="dummy")) mock_connection_mgr.return_value.get_connection_targets = ( async_mock.CoroutineMock(return_value=[ ConnectionTarget(recipient_keys=["recip_key"], ) ])) await handler.handle(self.context, responder) messages = responder.messages assert len(messages) == 1 (result, target) = messages[0] assert json.loads(result) == self.context.message.msg assert target["connection_id"] == "dummy"
async def session(): """Fixture for session used in tests.""" # pylint: disable=W0621 context = RequestContext.test_context() context.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY) context.connection_record = ConnRecord(connection_id=TEST_CONN_ID) yield await context.session()
async def resolve_inbound_connection( self, receipt: MessageReceipt) -> ConnectionRecord: """ Populate the receipt DID information and find the related `ConnectionRecord`. Args: receipt: The message receipt Returns: The `ConnectionRecord` associated with the expanded message, if any """ if receipt.sender_verkey: try: receipt.sender_did = await self.find_did_for_key( receipt.sender_verkey) except StorageNotFoundError: self._logger.warning( "No corresponding DID found for sender verkey: %s", receipt.sender_verkey, ) if receipt.recipient_verkey: try: wallet: BaseWallet = await self.context.inject(BaseWallet) my_info = await wallet.get_local_did_for_verkey( receipt.recipient_verkey) receipt.recipient_did = my_info.did if "public" in my_info.metadata and my_info.metadata[ "public"] is True: receipt.recipient_did_public = True except InjectorError: self._logger.warning( "Cannot resolve recipient verkey, no wallet defined by " "context: %s", receipt.recipient_verkey, ) except WalletNotFoundError: self._logger.warning( "No corresponding DID found for recipient verkey: %s", receipt.recipient_verkey, ) return await self.find_connection(receipt.sender_did, receipt.recipient_did, receipt.recipient_verkey, True)
async def setUp(self): self.context = RequestContext( base_context=InjectionContext(enforce_typing=False) ) self.context.connection_ready = True self.context.connection_record = ConnectionRecord(connection_id="conn-id") self.context.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY) self.context.injector.bind_instance(BaseStorage, BasicStorage())
async def test_ping_not_ready(self, request_context): request_context.message_receipt = MessageReceipt() request_context.message = Ping(response_requested=False) request_context.connection_ready = False handler = PingHandler() responder = MockResponder() assert not await handler.handle(request_context, responder) messages = responder.messages assert len(messages) == 0
async def setUp(self): self.context = RequestContext(base_context=InjectionContext( enforce_typing=False)) self.context.message_receipt = MessageReceipt( sender_verkey=TEST_VERKEY) self.storage = BasicStorage() self.context.injector.bind_instance(BaseStorage, self.storage) self.manager = RoutingManager(self.context) assert self.manager.context
async def test_ping(self, request_context): request_context.message_receipt = MessageReceipt() request_context.message = Ping(response_requested=False) request_context.settings["debug.monitor_ping"] = True request_context.connection_ready = True handler = PingHandler() responder = MockResponder() await handler.handle(request_context, responder) messages = responder.messages assert len(messages) == 0
async def test_ping_response(self, request_context): request_context.message_receipt = MessageReceipt() request_context.message = Ping(response_requested=True) request_context.connection_ready = True handler = PingHandler() responder = MockResponder() await handler.handle(request_context, responder) messages = responder.messages assert len(messages) == 1 result, target = messages[0] assert isinstance(result, PingResponse) assert result._thread_id == request_context.message._thread_id assert not target
async def test_problem_report(self, request_context): request_context.message_receipt = MessageReceipt() request_context.message = ProblemReport() request_context.connection_ready = True handler = ProblemReportHandler() responder = MockResponder() await handler.handle(request_context, responder) messages = responder.messages assert len(messages) == 0 hooks = responder.webhooks assert len(hooks) == 1 assert hooks[0] == ("problem_report", request_context.message.serialize())
async def test_handle_cannot_resolve_recipient(self): self.context.message_receipt = MessageReceipt(recipient_verkey=TEST_VERKEY) handler = test_module.ForwardHandler() responder = MockResponder() with async_mock.patch.object( test_module, "RoutingManager", autospec=True ) as mock_mgr: mock_mgr.return_value.get_recipient = async_mock.CoroutineMock( side_effect=test_module.RoutingManagerError() ) await handler.handle(self.context, responder) messages = responder.messages assert not messages
def request_context() -> RequestContext: ctx = RequestContext() ctx.message_receipt = MessageReceipt() yield ctx
async def test_handle_receipt_no_recipient_verkey(self): self.context.message_receipt = MessageReceipt() handler = test_module.ForwardHandler() with self.assertRaises(HandlerException): await handler.handle(self.context, None)
def manager() -> RoutingManager: ctx = RequestContext() ctx.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY) ctx.injector.bind_instance(BaseStorage, BasicStorage()) return RoutingManager(ctx)
def request_context() -> RequestContext: ctx = RequestContext() ctx.message_receipt = MessageReceipt(sender_verkey=TEST_VERKEY) ctx.injector.bind_instance(BaseStorage, BasicStorage()) yield ctx