Search in sources :

Example 11 with HttpContext

use of org.eclipse.hono.service.http.HttpContext in project hono by eclipse.

the class AbstractVertxBasedHttpProtocolAdapter method uploadCommandResponseMessage.

/**
 * Uploads a command response message to Hono.
 *
 * @param ctx The routing context of the HTTP request.
 * @param tenant The tenant of the device from which the command response was received.
 * @param deviceId The device from which the command response was received.
 * @param commandRequestId The id of the command that the response has been sent in reply to.
 * @param responseStatus The HTTP status code that the device has provided in its request to indicate
 *                       the outcome of processing the command (may be {@code null}).
 * @throws NullPointerException if ctx, tenant or deviceId are {@code null}.
 */
public final void uploadCommandResponseMessage(final HttpContext ctx, final String tenant, final String deviceId, final String commandRequestId, final Integer responseStatus) {
    Objects.requireNonNull(ctx);
    Objects.requireNonNull(tenant);
    Objects.requireNonNull(deviceId);
    final Buffer payload = ctx.getRoutingContext().getBody();
    final String contentType = ctx.getContentType();
    log.debug("processing response to command [tenantId: {}, deviceId: {}, cmd-req-id: {}, status code: {}]", tenant, deviceId, commandRequestId, responseStatus);
    final Device authenticatedDevice = ctx.getAuthenticatedDevice();
    final Span currentSpan = TracingHelper.buildChildSpan(tracer, TracingHandler.serverSpanContext(ctx.getRoutingContext()), "upload Command response", getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, tenant).withTag(TracingHelper.TAG_DEVICE_ID, deviceId).withTag(Constants.HEADER_COMMAND_RESPONSE_STATUS, responseStatus).withTag(Constants.HEADER_COMMAND_REQUEST_ID, commandRequestId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), authenticatedDevice != null).start();
    final CommandResponse cmdResponseOrNull = CommandResponse.fromRequestId(commandRequestId, tenant, deviceId, payload, contentType, responseStatus);
    final Future<TenantObject> tenantTracker = getTenantConfiguration(tenant, currentSpan.context());
    final Future<CommandResponse> commandResponseTracker = cmdResponseOrNull != null ? Future.succeededFuture(cmdResponseOrNull) : Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, String.format("command-request-id [%s] or status code [%s] is missing/invalid", commandRequestId, responseStatus)));
    final int payloadSize = Optional.ofNullable(payload).map(Buffer::length).orElse(0);
    CompositeFuture.all(tenantTracker, commandResponseTracker).compose(commandResponse -> {
        final Future<RegistrationAssertion> deviceRegistrationTracker = getRegistrationAssertion(tenant, deviceId, authenticatedDevice, currentSpan.context());
        final Future<Void> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantTracker.result()), checkMessageLimit(tenantTracker.result(), payloadSize, currentSpan.context())).map(ok -> null);
        return CompositeFuture.all(tenantValidationTracker, deviceRegistrationTracker).compose(ok -> sendCommandResponse(tenantTracker.result(), deviceRegistrationTracker.result(), commandResponseTracker.result(), currentSpan.context())).map(delivery -> {
            log.trace("delivered command response [command-request-id: {}] to application", commandRequestId);
            currentSpan.log("delivered command response to application");
            currentSpan.finish();
            metrics.reportCommand(Direction.RESPONSE, tenant, tenantTracker.result(), ProcessingOutcome.FORWARDED, payloadSize, getMicrometerSample(ctx.getRoutingContext()));
            ctx.response().setStatusCode(HttpURLConnection.HTTP_ACCEPTED);
            ctx.response().end();
            return delivery;
        });
    }).otherwise(t -> {
        log.debug("could not send command response [command-request-id: {}] to application", commandRequestId, t);
        TracingHelper.logError(currentSpan, t);
        currentSpan.finish();
        metrics.reportCommand(Direction.RESPONSE, tenant, tenantTracker.result(), ProcessingOutcome.from(t), payloadSize, getMicrometerSample(ctx.getRoutingContext()));
        ctx.fail(t);
        return null;
    });
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) HttpServer(io.vertx.core.http.HttpServer) Router(io.vertx.ext.web.Router) RoutingContext(io.vertx.ext.web.RoutingContext) BodyHandler(io.vertx.ext.web.handler.BodyHandler) Tags(io.opentracing.tag.Tags) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) TtdStatus(org.eclipse.hono.service.metric.MetricsTags.TtdStatus) DeviceCredentials(org.eclipse.hono.adapter.auth.device.DeviceCredentials) References(io.opentracing.References) Duration(java.time.Duration) Map(java.util.Map) WebSpanDecorator(org.eclipse.hono.service.http.WebSpanDecorator) TracingHelper(org.eclipse.hono.tracing.TracingHelper) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) Objects(java.util.Objects) List(java.util.List) ComponentMetaDataDecorator(org.eclipse.hono.service.http.ComponentMetaDataDecorator) TenantTraceSamplingHelper(org.eclipse.hono.tracing.TenantTraceSamplingHelper) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) HttpServerResponse(io.vertx.core.http.HttpServerResponse) DefaultFailureHandler(org.eclipse.hono.service.http.DefaultFailureHandler) Optional(java.util.Optional) Span(io.opentracing.Span) HttpContext(org.eclipse.hono.service.http.HttpContext) Command(org.eclipse.hono.client.command.Command) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) TracingHandler(org.eclipse.hono.service.http.TracingHandler) CompositeFuture(io.vertx.core.CompositeFuture) HttpUtils(org.eclipse.hono.service.http.HttpUtils) AsyncResult(io.vertx.core.AsyncResult) Strings(org.eclipse.hono.util.Strings) Route(io.vertx.ext.web.Route) CredentialsApiAuthProvider(org.eclipse.hono.adapter.auth.device.CredentialsApiAuthProvider) AbstractProtocolAdapterBase(org.eclipse.hono.adapter.AbstractProtocolAdapterBase) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Sample(io.micrometer.core.instrument.Timer.Sample) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) HttpServerOptions(io.vertx.core.http.HttpServerOptions) NoopSpan(io.opentracing.noop.NoopSpan) Handler(io.vertx.core.Handler) TenantObject(org.eclipse.hono.util.TenantObject) Device(org.eclipse.hono.auth.Device) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Future(io.vertx.core.Future) CompositeFuture(io.vertx.core.CompositeFuture) CommandResponse(org.eclipse.hono.client.command.CommandResponse) Span(io.opentracing.Span) NoopSpan(io.opentracing.noop.NoopSpan)

Example 12 with HttpContext

use of org.eclipse.hono.service.http.HttpContext in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteDiscardsJoinMessages.

/**
 * Verifies that the provider route discards join messages.
 */
@Test
public void handleProviderRouteDiscardsJoinMessages() {
    givenATelemetrySenderForAnyTenant();
    final LoraMessage message = mock(LoraMessage.class);
    when(message.getType()).thenReturn(LoraMessageType.JOIN);
    final LoraProvider providerMock = getLoraProviderMock(message);
    final HttpContext httpContext = newHttpContext();
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verify(httpContext.getRoutingContext().response()).setStatusCode(HttpResponseStatus.ACCEPTED.code());
    verify(processMessageSpan).finish();
}
Also used : LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Example 13 with HttpContext

use of org.eclipse.hono.service.http.HttpContext in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteCausesBadRequestForFailureToParseBody.

/**
 * Verifies that the provider route rejects a request if the request body cannot
 * be parsed.
 */
@Test
public void handleProviderRouteCausesBadRequestForFailureToParseBody() {
    givenATelemetrySenderForAnyTenant();
    final LoraProvider providerMock = getLoraProviderMock();
    when(providerMock.getMessage(any(RoutingContext.class))).thenThrow(new LoraProviderMalformedPayloadException("no device ID"));
    final HttpContext httpContext = newHttpContext();
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verifyBadRequest(httpContext.getRoutingContext());
    verify(processMessageSpan).finish();
}
Also used : RoutingContext(io.vertx.ext.web.RoutingContext) LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) LoraProviderMalformedPayloadException(org.eclipse.hono.adapter.lora.providers.LoraProviderMalformedPayloadException) Test(org.junit.jupiter.api.Test)

Example 14 with HttpContext

use of org.eclipse.hono.service.http.HttpContext in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteDiscardsDownlinkMessages.

/**
 * Verifies that the provider route discards downlink messages.
 */
@Test
public void handleProviderRouteDiscardsDownlinkMessages() {
    givenATelemetrySenderForAnyTenant();
    final LoraMessage message = mock(LoraMessage.class);
    when(message.getType()).thenReturn(LoraMessageType.DOWNLINK);
    final LoraProvider providerMock = getLoraProviderMock(message);
    final HttpContext httpContext = newHttpContext();
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verify(httpContext.response()).setStatusCode(HttpResponseStatus.ACCEPTED.code());
    verify(processMessageSpan).finish();
}
Also used : LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Example 15 with HttpContext

use of org.eclipse.hono.service.http.HttpContext in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteCausesUnauthorizedForInvalidGatewayCredentials.

/**
 * Verifies that the provider route rejects invalid gateway credentials with unauthorized.
 */
@Test
public void handleProviderRouteCausesUnauthorizedForInvalidGatewayCredentials() {
    givenATelemetrySenderForAnyTenant();
    final LoraProvider providerMock = getLoraProviderMock();
    final HttpContext httpContext = newHttpContext();
    when(httpContext.getRoutingContext().user()).thenReturn(null);
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verifyUnauthorized(httpContext.getRoutingContext());
    verify(processMessageSpan).finish();
}
Also used : LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Aggregations

HttpContext (org.eclipse.hono.service.http.HttpContext)31 Test (org.junit.jupiter.api.Test)27 Buffer (io.vertx.core.buffer.Buffer)21 HttpServerResponse (io.vertx.core.http.HttpServerResponse)18 HttpServerRequest (io.vertx.core.http.HttpServerRequest)15 TenantObject (org.eclipse.hono.util.TenantObject)11 SpanContext (io.opentracing.SpanContext)9 ClientErrorException (org.eclipse.hono.client.ClientErrorException)9 Handler (io.vertx.core.Handler)8 RoutingContext (io.vertx.ext.web.RoutingContext)8 LoraProvider (org.eclipse.hono.adapter.lora.providers.LoraProvider)8 CommandConsumer (org.eclipse.hono.client.command.CommandConsumer)8 EndpointType (org.eclipse.hono.service.metric.MetricsTags.EndpointType)8 TtdStatus (org.eclipse.hono.service.metric.MetricsTags.TtdStatus)8 Future (io.vertx.core.Future)6 HashMap (java.util.HashMap)6 Span (io.opentracing.Span)5 AsyncResult (io.vertx.core.AsyncResult)5 HttpURLConnection (java.net.HttpURLConnection)5 ServerErrorException (org.eclipse.hono.client.ServerErrorException)5