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;
});
}
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();
}
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();
}
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();
}
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();
}
Aggregations