Search in sources :

Example 1 with HttpContext

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

the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadTelemetryWithTtdClosesCommandConsumerIfSendingFails.

/**
 * Verifies that the adapter closes the command consumer created as part of
 * handling a request with a TTD parameter if sending of the telemetry
 * message fails.
 */
@Test
public void testUploadTelemetryWithTtdClosesCommandConsumerIfSendingFails() {
    // GIVEN an adapter
    givenAnAdapter(properties);
    // with the downstream telemetry sender unable to forward messages
    final Promise<Void> sendResult = Promise.promise();
    sendResult.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE));
    givenATelemetrySenderForAnyTenant(sendResult);
    // WHEN a device publishes a telemetry message with a TTD
    final Buffer payload = Buffer.buffer("some payload");
    final HttpServerResponse response = mock(HttpServerResponse.class);
    final HttpServerRequest request = mock(HttpServerRequest.class);
    when(request.getHeader(eq(Constants.HEADER_TIME_TILL_DISCONNECT))).thenReturn("10");
    final HttpContext ctx = newHttpContext(payload, "text/plain", request, response);
    when(ctx.getRoutingContext().addBodyEndHandler(VertxMockSupport.anyHandler())).thenAnswer(invocation -> {
        final Handler<Void> handler = invocation.getArgument(0);
        handler.handle(null);
        return 0;
    });
    // and the creation of the command consumer completes at a later point
    final Promise<CommandConsumer> commandConsumerPromise = Promise.promise();
    when(commandConsumerFactory.createCommandConsumer(anyString(), anyString(), VertxMockSupport.anyHandler(), any(), any())).thenReturn(commandConsumerPromise.future());
    adapter.uploadTelemetryMessage(ctx, "tenant", "device");
    commandConsumerPromise.complete(commandConsumer);
    // THEN the request fails immediately
    verify(ctx.getRoutingContext()).fail(any());
    // the message has been reported
    verify(metrics).reportTelemetry(eq(EndpointType.TELEMETRY), eq("tenant"), any(), eq(ProcessingOutcome.UNDELIVERABLE), eq(MetricsTags.QoS.AT_MOST_ONCE), eq(payload.length()), eq(TtdStatus.NONE), any());
    // and the command consumer is closed
    verify(commandConsumer).close(any());
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpServerResponse(io.vertx.core.http.HttpServerResponse) HttpServerRequest(io.vertx.core.http.HttpServerRequest) HttpContext(org.eclipse.hono.service.http.HttpContext) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Test(org.junit.jupiter.api.Test)

Example 2 with HttpContext

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

the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadTelemetryDoesNotWaitForAcceptedOutcome.

/**
 * Verifies that the adapter does not wait for a telemetry message being settled and accepted
 * by a downstream peer before responding with a 202 status to the device.
 */
@Test
public void testUploadTelemetryDoesNotWaitForAcceptedOutcome() {
    // GIVEN an adapter with a downstream telemetry consumer attached
    givenAnAdapter(properties);
    givenATelemetrySenderForAnyTenant();
    // WHEN a device publishes a telemetry message
    final Buffer payload = Buffer.buffer("some payload");
    final HttpServerResponse response = mock(HttpServerResponse.class);
    final HttpContext ctx = newHttpContext(payload, "application/text", mock(HttpServerRequest.class), response);
    when(ctx.getRoutingContext().addBodyEndHandler(VertxMockSupport.anyHandler())).thenAnswer(invocation -> {
        final Handler<Void> handler = invocation.getArgument(0);
        handler.handle(null);
        return 0;
    });
    adapter.uploadTelemetryMessage(ctx, "tenant", "device");
    // THEN the device receives a 202 response immediately
    verify(response).setStatusCode(202);
    verify(response).end();
    assertTelemetryMessageHasBeenSentDownstream(QoS.AT_MOST_ONCE, "tenant", "device", "application/text");
    // and the message has been reported as processed
    verify(metrics).reportTelemetry(eq(MetricsTags.EndpointType.TELEMETRY), eq("tenant"), any(), eq(MetricsTags.ProcessingOutcome.FORWARDED), eq(MetricsTags.QoS.AT_MOST_ONCE), eq(payload.length()), eq(MetricsTags.TtdStatus.NONE), any());
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpServerResponse(io.vertx.core.http.HttpServerResponse) HttpServerRequest(io.vertx.core.http.HttpServerRequest) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Example 3 with HttpContext

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

the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadCommandResponseWaitsForAcceptedOutcome.

/**
 * Verifies that the adapter waits for a command response being settled and accepted
 * by a downstream peer before responding with a 202 status to the device.
 */
@Test
public void testUploadCommandResponseWaitsForAcceptedOutcome() {
    // GIVEN an adapter with a downstream application attached
    givenAnAdapter(properties);
    final Promise<Void> outcome = Promise.promise();
    givenACommandResponseSenderForAnyTenant(outcome);
    // WHEN a device publishes a command response
    final Buffer payload = Buffer.buffer("some payload");
    final HttpServerResponse response = mock(HttpServerResponse.class);
    final HttpContext ctx = newHttpContext(payload, "application/text", mock(HttpServerRequest.class), response);
    when(ctx.getRoutingContext().addBodyEndHandler(VertxMockSupport.anyHandler())).thenAnswer(invocation -> {
        final Handler<Void> handler = invocation.getArgument(0);
        handler.handle(null);
        return 0;
    });
    adapter.uploadCommandResponseMessage(ctx, "tenant", "device", CMD_REQ_ID, 200);
    // THEN the device does not get a response
    verify(response, never()).end();
    // and the response has not been reported as forwarded
    verify(metrics, never()).reportCommand(eq(Direction.RESPONSE), eq("tenant"), any(), eq(ProcessingOutcome.FORWARDED), anyInt(), any());
    // until the command response has been accepted by the application
    outcome.complete();
    verify(response).setStatusCode(202);
    verify(response).end();
    verify(metrics).reportCommand(eq(Direction.RESPONSE), eq("tenant"), any(), eq(ProcessingOutcome.FORWARDED), eq(payload.length()), any());
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpServerResponse(io.vertx.core.http.HttpServerResponse) HttpServerRequest(io.vertx.core.http.HttpServerRequest) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Example 4 with HttpContext

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

the class AbstractVertxBasedHttpProtocolAdapterTest method testMessageLimitExceededForATelemetryMessage.

/**
 * Verifies that a telemetry message is rejected due to the limit exceeded.
 */
@Test
public void testMessageLimitExceededForATelemetryMessage() {
    // GIVEN an adapter with a downstream telemetry consumer attached
    givenAnAdapter(properties);
    givenATelemetrySenderForAnyTenant();
    final Buffer payload = Buffer.buffer("some payload");
    final HttpContext routingContext = newHttpContext(payload);
    // WHEN the message limit exceeds
    when(resourceLimitChecks.isMessageLimitReached(any(TenantObject.class), anyLong(), any(SpanContext.class))).thenReturn(Future.succeededFuture(Boolean.TRUE));
    // WHEN a device that belongs to "my-tenant" publishes a telemetry message
    adapter.uploadTelemetryMessage(routingContext, "my-tenant", "the-device", payload, "application/text");
    // THEN the device gets a 429
    assertContextFailedWithClientError(routingContext, HttpUtils.HTTP_TOO_MANY_REQUESTS);
    assertNoTelemetryMessageHasBeenSentDownstream();
    // the message has been reported
    verify(metrics).reportTelemetry(eq(EndpointType.TELEMETRY), eq("my-tenant"), any(), eq(ProcessingOutcome.UNPROCESSABLE), eq(MetricsTags.QoS.AT_MOST_ONCE), eq(payload.length()), eq(TtdStatus.NONE), any());
}
Also used : Buffer(io.vertx.core.buffer.Buffer) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Example 5 with HttpContext

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

the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadTelemetryUsesConfiguredMaxTtd.

/**
 * Verifies that the adapter uses the max TTD configured for the adapter if a device provides
 * a TTD value that is greater than the max value.
 */
@Test
public void testUploadTelemetryUsesConfiguredMaxTtd() {
    // GIVEN an adapter with a downstream telemetry consumer attached
    givenAnAdapter(properties);
    givenATelemetrySenderForAnyTenant();
    // WHEN a device publishes a telemetry message that belongs to a tenant with
    // a max TTD of 20 secs
    final TenantObject tenant = TenantObject.from("tenant", true).addAdapter(new Adapter(ADAPTER_TYPE).setEnabled(Boolean.TRUE).setExtensions(Map.of(TenantConstants.FIELD_MAX_TTD, 20)));
    when(tenantClient.get(eq("tenant"), any())).thenReturn(Future.succeededFuture(tenant));
    // and includes a TTD value of 40 in its request
    final Buffer payload = Buffer.buffer("some payload");
    final HttpServerResponse response = mock(HttpServerResponse.class);
    final HttpServerRequest request = mock(HttpServerRequest.class);
    when(request.getHeader(eq(Constants.HEADER_TIME_TILL_DISCONNECT))).thenReturn("40");
    final HttpContext ctx = newHttpContext(payload, "text/plain", request, response);
    adapter.uploadTelemetryMessage(ctx, "tenant", "device");
    // THEN the device receives a 202 response immediately
    verify(response).setStatusCode(202);
    verify(response).end();
    // and the downstream message contains the configured max TTD
    verify(telemetrySender).sendTelemetry(eq(tenant), argThat(assertion -> assertion.getDeviceId().equals("device")), eq(org.eclipse.hono.util.QoS.AT_MOST_ONCE), eq("text/plain"), any(Buffer.class), argThat(props -> props.get(MessageHelper.APP_PROPERTY_DEVICE_TTD).equals(20)), any());
}
Also used : Buffer(io.vertx.core.buffer.Buffer) HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) TenantConstants(org.eclipse.hono.util.TenantConstants) HttpServer(io.vertx.core.http.HttpServer) Router(io.vertx.ext.web.Router) MIMEHeader(io.vertx.ext.web.MIMEHeader) RoutingContext(io.vertx.ext.web.RoutingContext) Context(io.vertx.core.Context) Timeout(io.vertx.junit5.Timeout) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) TtdStatus(org.eclipse.hono.service.metric.MetricsTags.TtdStatus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Map(java.util.Map) ParsedHeaderValues(io.vertx.ext.web.ParsedHeaderValues) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) Buffer(io.vertx.core.buffer.Buffer) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) HttpServerResponse(io.vertx.core.http.HttpServerResponse) Optional(java.util.Optional) Span(io.opentracing.Span) QoS(org.eclipse.hono.util.QoS) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) VertxTestContext(io.vertx.junit5.VertxTestContext) HttpContext(org.eclipse.hono.service.http.HttpContext) HttpServerRequest(io.vertx.core.http.HttpServerRequest) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) DeviceUser(org.eclipse.hono.service.auth.DeviceUser) TracingHandler(org.eclipse.hono.service.http.TracingHandler) ProtocolAdapterTestSupport(org.eclipse.hono.adapter.test.ProtocolAdapterTestSupport) ArgumentCaptor(org.mockito.ArgumentCaptor) HttpUtils(org.eclipse.hono.service.http.HttpUtils) AsyncResult(io.vertx.core.AsyncResult) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) TimeUnit(java.util.concurrent.TimeUnit) Mockito.never(org.mockito.Mockito.never) Adapter(org.eclipse.hono.util.Adapter) ResourceLimitChecks(org.eclipse.hono.adapter.resourcelimits.ResourceLimitChecks) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) TenantObject(org.eclipse.hono.util.TenantObject) HttpServerResponse(io.vertx.core.http.HttpServerResponse) HttpServerRequest(io.vertx.core.http.HttpServerRequest) HttpContext(org.eclipse.hono.service.http.HttpContext) Adapter(org.eclipse.hono.util.Adapter) 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