in DeviceBridge/Services/SubscriptionCallbackFactory.cs [107:173]
public MethodCallback GetMethodCallback(string deviceId, DeviceSubscription methodSubscription)
{
return async (methodRequest, _) =>
{
_logger.Info("Got method request for device {deviceId}. Callback URL {callbackUrl}. Method: {methodName}. Payload: {payload}", deviceId, methodSubscription.CallbackUrl, methodRequest.Name, methodRequest.DataAsJson);
try
{
var body = new MethodInvocationEventBody()
{
DeviceId = deviceId,
DeviceReceivedAt = DateTime.UtcNow,
MethodName = methodRequest.Name,
RequestData = new JRaw(methodRequest.DataAsJson),
};
// Send request to callback URL
var requestPayload = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
using var httpResponse = await _httpClientFactory.CreateClient("RetryClient").PostAsync(methodSubscription.CallbackUrl, requestPayload);
httpResponse.EnsureSuccessStatusCode();
// Read method response from callback response
using var responseStream = await httpResponse.Content.ReadAsStreamAsync();
MethodResponseBody responseBody = null;
try
{
responseBody = await System.Text.Json.JsonSerializer.DeserializeAsync<MethodResponseBody>(responseStream, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
});
}
catch (System.Text.Json.JsonException e)
{
_logger.Error(e, "Received malformed JSON response when executing method callback for device {deviceId}", deviceId);
}
MethodResponse methodResponse;
string serializedResponsePayload = null;
int status = 200;
// If we got a custom response, return the custom payload and status. If not, just respond with a 200.
if (responseBody != null && responseBody.Status != null)
{
status = responseBody.Status.Value;
}
if (responseBody != null && responseBody.Payload != null)
{
serializedResponsePayload = System.Text.Json.JsonSerializer.Serialize(responseBody.Payload);
methodResponse = new MethodResponse(Encoding.UTF8.GetBytes(serializedResponsePayload), status);
}
else
{
methodResponse = new MethodResponse(status);
}
_logger.Info("Successfully executed method callback for device {deviceId}. Response status: {responseStatus}. Response payload: {responsePayload}", deviceId, status, serializedResponsePayload);
return methodResponse;
}
catch (Exception e)
{
_logger.Error(e, "Failed to execute method callback for device {deviceId}", deviceId);
return new MethodResponse(500);
}
};
}