Skip to content

Commit c25ce9a

Browse files
committed
feat: WIP Use Protocol Registry for DIDComm V2
Signed-off-by: Colton Wolkins (Laptop) <[email protected]>
1 parent b57ad4f commit c25ce9a

File tree

1 file changed

+111
-12
lines changed

1 file changed

+111
-12
lines changed

acapy_agent/core/dispatcher.py

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from ..utils.tracing import get_timer, trace_event
3535
from .error import ProtocolMinorVersionNotSupported
3636
from .protocol_registry import ProtocolRegistry
37+
from ..didcomm_v2.protocol_registry import V2ProtocolRegistry
3738

3839

3940
class ProblemReportParseError(MessageParseError):
@@ -137,6 +138,24 @@ async def handle_v2_message(
137138
):
138139
"""Handle a DIDComm V2 message."""
139140

141+
error_result = None
142+
message = None
143+
144+
try:
145+
message = await self.make_v2_message(profile, inbound_message.payload)
146+
except ProblemReportParseError:
147+
pass # avoid problem report recursion
148+
except MessageParseError as e:
149+
self.logger.error(f"Message parsing failed: {str(e)}, sending problem report")
150+
error_result = ProblemReport(
151+
description={
152+
"en": str(e),
153+
"code": "message-parse-failure",
154+
}
155+
)
156+
if inbound_message.receipt.thread_id:
157+
error_result.assign_thread_id(inbound_message.receipt.thread_id)
158+
140159
# send a DCV2 Problem Report here for testing, and to punt procotol handling down
141160
# the road a bit
142161
context = RequestContext(profile)
@@ -150,18 +169,98 @@ async def handle_v2_message(
150169
)
151170

152171
context.injector.bind_instance(BaseResponder, responder)
153-
error_result = V2AgentMessage(
154-
message={
155-
"type": "https://didcomm.org/report-problem/2.0/problem-report",
156-
"body": {
157-
"comment": "No Handlers Found",
158-
"code": "e.p.msg.not-found",
159-
},
160-
}
161-
)
162-
if inbound_message.receipt.thread_id:
163-
error_result.message["pthid"] = inbound_message.receipt.thread_id
164-
await responder.send_reply(error_result)
172+
if not message:
173+
error_result = V2AgentMessage(
174+
message={
175+
"type": "https://didcomm.org/report-problem/2.0/problem-report",
176+
"body": {
177+
"comment": "No Handlers Found",
178+
"code": "e.p.msg.not-found",
179+
},
180+
}
181+
)
182+
if inbound_message.receipt.thread_id:
183+
error_result.message["pthid"] = inbound_message.receipt.thread_id
184+
185+
# # When processing oob attach message we supply the connection id
186+
# # associated with the inbound message
187+
# if inbound_message.connection_id:
188+
# async with self.profile.session() as session:
189+
# connection = await ConnRecord.retrieve_by_id(
190+
# session, inbound_message.connection_id
191+
# )
192+
# else:
193+
# connection_mgr = BaseConnectionManager(profile)
194+
# connection = await connection_mgr.find_inbound_connection(
195+
# inbound_message.receipt
196+
# )
197+
# del connection_mgr
198+
199+
# if connection:
200+
# inbound_message.connection_id = connection.connection_id
201+
202+
# context.connection_ready = connection and connection.is_ready
203+
# context.connection_record = connection
204+
# responder.connection_id = connection and connection.connection_id
205+
206+
if error_result:
207+
await responder.send_reply(error_result)
208+
elif context.message:
209+
context.injector.bind_instance(BaseResponder, responder)
210+
211+
handler_cls = context.message.Handler
212+
handler = handler_cls().handle
213+
if self.collector:
214+
handler = self.collector.wrap_coro(handler, [handler.__qualname__])
215+
await handler(context, responder)
216+
217+
async def make_v2_message(self, profile: Profile, parsed_msg: dict) -> BaseMessage:
218+
"""Deserialize a message dict into the appropriate message instance.
219+
220+
Given a dict describing a message, this method
221+
returns an instance of the related message class.
222+
223+
Args:
224+
parsed_msg: The parsed message
225+
profile: Profile
226+
227+
Returns:
228+
An instance of the corresponding message class for this message
229+
230+
Raises:
231+
MessageParseError: If the message doesn't specify @type
232+
MessageParseError: If there is no message class registered to handle
233+
the given type
234+
235+
"""
236+
if not isinstance(parsed_msg, dict):
237+
raise MessageParseError("Expected a JSON object")
238+
message_type = parsed_msg.get("type")
239+
240+
if not message_type:
241+
raise MessageParseError("Message does not contain 'type' parameter")
242+
243+
registry: V2ProtocolRegistry = self.profile.inject(V2ProtocolRegistry)
244+
try:
245+
#message_cls = registry.resolve_message_class(message_type)
246+
#if isinstance(message_cls, DeferLoad):
247+
# message_cls = message_cls.resolved
248+
message_cls = V2ProtocolRegistry.protocols_matching_query(message_type)
249+
except ProtocolMinorVersionNotSupported as e:
250+
raise MessageParseError(f"Problem parsing message type. {e}")
251+
252+
if not message_cls:
253+
raise MessageParseError(f"Unrecognized message type {message_type}")
254+
255+
try:
256+
instance = message_cls[0] #message_cls.deserialize(parsed_msg)
257+
except BaseModelError as e:
258+
if "/problem-report" in message_type:
259+
raise ProblemReportParseError("Error parsing problem report message")
260+
raise MessageParseError(f"Error deserializing message: {e}") from e
261+
262+
return instance
263+
165264

166265
async def handle_v1_message(
167266
self,

0 commit comments

Comments
 (0)