Search in sources :

Example 11 with CommandResponse

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());
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) ResponseCode(org.eclipse.californium.core.coap.CoAP.ResponseCode) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) LoggerFactory(org.slf4j.LoggerFactory) Vertx(io.vertx.core.Vertx) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) Tags(io.opentracing.tag.Tags) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) Objects(java.util.Objects) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) CompositeFuture(io.vertx.core.CompositeFuture) Buffer(io.vertx.core.buffer.Buffer) Optional(java.util.Optional) Span(io.opentracing.Span) TracingHelper(org.eclipse.hono.tracing.TracingHelper) CommandConstants(org.eclipse.hono.util.CommandConstants) Device(org.eclipse.hono.auth.Device) CommandResponse(org.eclipse.hono.client.command.CommandResponse) Span(io.opentracing.Span) TenantObject(org.eclipse.hono.util.TenantObject) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ClientErrorException(org.eclipse.hono.client.ClientErrorException)

Aggregations

CommandResponse (org.eclipse.hono.client.command.CommandResponse)11 RegistrationAssertion (org.eclipse.hono.util.RegistrationAssertion)11 TenantObject (org.eclipse.hono.util.TenantObject)11 Span (io.opentracing.Span)8 Future (io.vertx.core.Future)7 HttpURLConnection (java.net.HttpURLConnection)6 Objects (java.util.Objects)6 ClientErrorException (org.eclipse.hono.client.ClientErrorException)6 CommandConstants (org.eclipse.hono.util.CommandConstants)6 Tags (io.opentracing.tag.Tags)5 Optional (java.util.Optional)5 TracingHelper (org.eclipse.hono.tracing.TracingHelper)5 MessageHelper (org.eclipse.hono.util.MessageHelper)5 SpanContext (io.opentracing.SpanContext)4 CompositeFuture (io.vertx.core.CompositeFuture)4 Buffer (io.vertx.core.buffer.Buffer)4 Map (java.util.Map)4 Message (org.apache.qpid.proton.message.Message)4 Test (org.junit.jupiter.api.Test)4 Sample (io.micrometer.core.instrument.Timer.Sample)3