use of org.eclipse.hono.util.Adapter 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());
}
use of org.eclipse.hono.util.Adapter in project hono by eclipse.
the class CoapContextTest method testStartAckTimerDoesNotStartTimer.
/**
* Verifies that no ACK timer is started for a timeout value <= 0.
*/
@ParameterizedTest
@ValueSource(longs = { -1L, 0L })
void testStartAckTimerDoesNotStartTimer(final long timeout) {
final CoapExchange exchange = mock(CoapExchange.class);
final Adapter coapConfig = new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_COAP);
// never send separate ACK
coapConfig.putExtension(CoapConstants.TIMEOUT_TO_ACK, -1L);
final TenantObject tenant = TenantObject.from("tenant", true).addAdapter(coapConfig);
final Device authenticatedDevice = new Device(tenant.getTenantId(), "device-id");
final CoapContext ctx = CoapContext.fromRequest(exchange, authenticatedDevice, authenticatedDevice, "4711", span);
ctx.startAcceptTimer(vertx, tenant, timeout);
verify(vertx, never()).setTimer(anyLong(), VertxMockSupport.anyHandler());
}
use of org.eclipse.hono.util.Adapter in project hono by eclipse.
the class CoapContextTest method testStartAckTimerUsesTenantSpecificTimeout.
/**
* Verifies that the tenant specific value set for the ACK timeout gets
* precedence over the global adapter configuration.
*/
@Test
void testStartAckTimerUsesTenantSpecificTimeout() {
final CoapExchange exchange = mock(CoapExchange.class);
final Adapter coapConfig = new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_COAP);
coapConfig.putExtension(CoapConstants.TIMEOUT_TO_ACK, 200);
final TenantObject tenant = TenantObject.from("tenant", true).addAdapter(coapConfig);
final Device authenticatedDevice = new Device(tenant.getTenantId(), "device-id");
final CoapContext ctx = CoapContext.fromRequest(exchange, authenticatedDevice, authenticatedDevice, "4711", span);
ctx.startAcceptTimer(vertx, tenant, 500);
verify(vertx).setTimer(eq(200L), VertxMockSupport.anyHandler());
}
use of org.eclipse.hono.util.Adapter in project hono by eclipse.
the class CoapContextTest method testStartAckTimerHandlesNonNumberPropertyValue.
/**
* Verifies that the global ACK timeout is used if a tenant specific value is configured that is not a number.
*/
@Test
void testStartAckTimerHandlesNonNumberPropertyValue() {
final CoapExchange exchange = mock(CoapExchange.class);
final Adapter coapConfig = new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_COAP);
coapConfig.putExtension(CoapConstants.TIMEOUT_TO_ACK, "not-a-number");
final TenantObject tenant = TenantObject.from("tenant", true).addAdapter(coapConfig);
final Device authenticatedDevice = new Device(tenant.getTenantId(), "device-id");
final CoapContext ctx = CoapContext.fromRequest(exchange, authenticatedDevice, authenticatedDevice, "4711", span);
ctx.startAcceptTimer(vertx, tenant, 500);
verify(vertx).setTimer(eq(500L), VertxMockSupport.anyHandler());
}
use of org.eclipse.hono.util.Adapter in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testMessageLimitExceededForACommandResponseMessage.
/**
* Verifies that a command response message is rejected due to the limit exceeded.
*
* @param ctx The vert.x test context.
*/
@Test
public void testMessageLimitExceededForACommandResponseMessage(final VertxTestContext ctx) {
// GIVEN an adapter
givenAnAdapter(properties);
final CommandResponseSender sender = givenACommandResponseSenderForAnyTenant();
// WHEN the message limit exceeds
when(resourceLimitChecks.isMessageLimitReached(any(TenantObject.class), anyLong(), any(SpanContext.class))).thenReturn(Future.succeededFuture(Boolean.TRUE));
// WHEN a device of "tenant" publishes a command response message
final MqttPublishMessage msg = mock(MqttPublishMessage.class);
when(msg.topicName()).thenReturn("e/tenant/device");
when(msg.qosLevel()).thenReturn(MqttQoS.AT_MOST_ONCE);
when(msg.payload()).thenReturn(Buffer.buffer("test"));
adapter.uploadMessage(newMqttContext(msg, mockEndpoint(), span), ResourceIdentifier.fromString(String.format("%s/tenant/device/res/%s/200", getCommandEndpoint(), Commands.encodeRequestIdParameters("cmd123", "to", "deviceId", MessagingType.amqp))), msg).onComplete(ctx.failing(t -> {
ctx.verify(() -> {
// THEN the request fails with a 429 error
assertThat(((ClientErrorException) t).getErrorCode()).isEqualTo(HttpUtils.HTTP_TOO_MANY_REQUESTS);
// AND the response is not being forwarded
verify(sender, never()).sendCommandResponse(any(TenantObject.class), any(RegistrationAssertion.class), any(CommandResponse.class), (SpanContext) any());
// AND has reported the message as unprocessable
verify(metrics).reportCommand(eq(MetricsTags.Direction.RESPONSE), eq("tenant"), any(), eq(MetricsTags.ProcessingOutcome.UNPROCESSABLE), anyInt(), any());
});
ctx.completeNow();
}));
}
Aggregations