use of org.eclipse.hono.client.command.CommandResponse in project hono by eclipse.
the class CommandResponseResource method uploadCommandResponseMessage.
/**
* Forwards a command response to a downstream application.
*
* @param context The context representing the command response to be forwarded.
* @return A future indicating the outcome of the operation.
* The future will be succeeded if the message has been forwarded successfully.
* In this case one of the context's <em>respond</em> methods will have been invoked to send a CoAP response
* back to the device.
* Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}.
* @throws NullPointerException if context is {@code null}.
*/
public final Future<Void> uploadCommandResponseMessage(final CoapContext context) {
Objects.requireNonNull(context);
final Device device = context.getOriginDevice();
final Device authenticatedDevice = context.getAuthenticatedDevice();
if (!context.isConfirmable()) {
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "command response endpoint supports confirmable request messages only"));
}
final Buffer payload = context.getPayload();
final String contentType = context.getContentType();
final String commandRequestId = context.getCommandRequestId();
final Integer responseStatus = context.getCommandResponseStatus();
LOG.debug("processing response to command [tenantId: {}, deviceId: {}, cmd-req-id: {}, status code: {}]", device.getTenantId(), device.getDeviceId(), commandRequestId, responseStatus);
final Span currentSpan = TracingHelper.buildChildSpan(getTracer(), context.getTracingContext(), "upload Command response", getAdapter().getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, device.getTenantId()).withTag(TracingHelper.TAG_DEVICE_ID, device.getDeviceId()).withTag(Constants.HEADER_COMMAND_RESPONSE_STATUS, responseStatus).withTag(Constants.HEADER_COMMAND_REQUEST_ID, commandRequestId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), authenticatedDevice != null).start();
final Future<RegistrationAssertion> deviceRegistrationTracker = getAdapter().getRegistrationAssertion(device.getTenantId(), device.getDeviceId(), authenticatedDevice, currentSpan.context());
final Future<TenantObject> tenantTracker = getAdapter().getTenantClient().get(device.getTenantId(), currentSpan.context());
final Optional<CommandResponse> cmdResponse = Optional.ofNullable(CommandResponse.fromRequestId(commandRequestId, device.getTenantId(), device.getDeviceId(), payload, contentType, responseStatus));
final Future<CommandResponse> commandResponseTracker = cmdResponse.map(res -> Future.succeededFuture(res)).orElseGet(() -> Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, String.format("command-request-id [%s] or status code [%s] is missing/invalid", commandRequestId, responseStatus))));
return CompositeFuture.all(tenantTracker, commandResponseTracker, deviceRegistrationTracker).compose(ok -> CompositeFuture.all(getAdapter().isAdapterEnabled(tenantTracker.result()), getAdapter().checkMessageLimit(tenantTracker.result(), payload.length(), currentSpan.context())).mapEmpty()).compose(ok -> getAdapter().getCommandResponseSender(commandResponseTracker.result().getMessagingType(), tenantTracker.result()).sendCommandResponse(tenantTracker.result(), deviceRegistrationTracker.result(), commandResponseTracker.result(), currentSpan.context())).onSuccess(ok -> {
LOG.trace("forwarded command response [command-request-id: {}] to downstream application", commandRequestId);
currentSpan.log("forwarded command response to application");
getAdapter().getMetrics().reportCommand(Direction.RESPONSE, device.getTenantId(), tenantTracker.result(), ProcessingOutcome.FORWARDED, payload.length(), context.getTimer());
context.respondWithCode(ResponseCode.CHANGED);
}).onFailure(t -> {
LOG.debug("could not send command response [command-request-id: {}] to application", commandRequestId, t);
TracingHelper.logError(currentSpan, t);
getAdapter().getMetrics().reportCommand(Direction.RESPONSE, device.getTenantId(), tenantTracker.result(), ProcessingOutcome.from(t), payload.length(), context.getTimer());
}).onComplete(r -> currentSpan.finish());
}
Aggregations