handleRequestNotification method
Not part of API, but visibleForTesting. Receives 'request' notifications, and
- parses and validates
- sends an AtRpcRespType.nack response if deserialization or validation fails
- sends an AtRpcRespType.nack response otherwise
- calls AtRpcCallbacks.handleRequest
- calls sendResponse with the response from AtRpcCallbacks.handleRequest
Implementation
@visibleForTesting
Future<void> handleRequestNotification(AtNotification notification) async {
if (!allowList.contains(notification.from)) {
if (allowAll) {
logger.warning('Will handle request from atSign ${notification.from}'
' which is not on allowList (but allowAll is true)'
' : $notification');
} else {
logger.shout('Ignoring request from atSign ${notification.from}'
' which is not on the allowList (and allowAll is false)'
' : $notification');
return;
}
}
// request key should be like:
// @toAtSign:request.<id>.<domainNameSpace>.<rpcsNameSpace>.<baseNameSpace>@fromAtSign
// strip off the prefix `@toAtSign:request.`
String requestKey =
notification.key.replaceFirst('${notification.to}:request.', '');
// We should now have something like:
// <id>.<domainNameSpace>.<rpcsNameSpace>.<baseNameSpace>@fromAtSign
// We want to keep just the <id> and discard the rest
requestKey = requestKey.replaceAll(
'.$domainNameSpace.$rpcsNameSpace.$baseNameSpace${notification.from}',
'');
int requestId = -1;
try {
requestId = int.parse(requestKey);
} catch (e) {
logger.warning('Failed to get request ID from ${notification.key} - $e');
return;
}
// print('Received request with id ${notification.key} and value ${chalk.brightGreen.bold(notification.value)}');
late AtRpcReq request;
try {
request = AtRpcReq.fromJson(jsonDecode(notification.value!));
} catch (e, st) {
var message =
'Failed to deserialize AtRpcReq from ${notification.value}: $e';
logger.warning(message);
logger.warning(st);
// send NACK
await sendResponse(notification, request,
AtRpcResp.nack(request: request, message: message));
return;
}
if (request.reqId != requestId) {
var message =
'Ignoring request: requestID from the notification key $requestId'
' does not match requestID from notification payload ${request.reqId}';
logger.warning(message);
// send NACK
await sendResponse(notification, request,
AtRpcResp.nack(request: request, message: message));
return;
}
// send ACK
await sendResponse(notification, request, AtRpcResp.ack(request: request));
late AtRpcResp response;
try {
response = await callbacks.handleRequest(request, notification.from);
await sendResponse(notification, request, response);
} catch (e, st) {
var message =
'Exception $e from callbacks.handleRequest for request $request';
logger.warning(message);
logger.warning(st);
await sendResponse(notification, request,
AtRpcResp.nack(request: request, message: message));
}
}