use of org.eclipse.hono.util.ResourceLimits in project hono by eclipse.
the class KafkaBasedCommandResponseSenderTest method testIfValidCommandResponseKafkaRecordIsSent.
@Test
void testIfValidCommandResponseKafkaRecordIsSent(final VertxTestContext ctx, final Vertx vertx) {
// GIVEN a command response sender
final String tenantId = "test-tenant";
final String deviceId = "test-device";
final String correlationId = UUID.randomUUID().toString();
final String contentType = "text/plain";
final String payload = "the-payload";
final int status = 200;
final String additionalHeader1Name = "testHeader1";
final String additionalHeader1Value = "testHeader1Value";
final String additionalHeader2Name = "testHeader2";
final String additionalHeader2Value = "testHeader2Value";
final Map<String, Object> additionalProperties = Map.of(additionalHeader1Name, additionalHeader1Value, additionalHeader2Name, additionalHeader2Value);
final CommandResponse commandResponse = CommandResponse.fromAddressAndCorrelationId(String.format("%s/%s/%s", CommandConstants.COMMAND_RESPONSE_ENDPOINT, tenantId, Commands.getDeviceFacingReplyToId("", deviceId, MessagingType.kafka)), correlationId, Buffer.buffer(payload), contentType, status);
commandResponse.setAdditionalProperties(additionalProperties);
final Span span = TracingMockSupport.mockSpan();
final Tracer tracer = TracingMockSupport.mockTracer(span);
final var mockProducer = KafkaClientUnitTestHelper.newMockProducer(true);
final var factory = CachingKafkaProducerFactory.testFactory(vertx, (n, c) -> KafkaClientUnitTestHelper.newKafkaProducer(mockProducer));
final var sender = new KafkaBasedCommandResponseSender(vertx, factory, kafkaProducerConfig, tracer);
final TenantObject tenant = TenantObject.from(tenantId);
tenant.setResourceLimits(new ResourceLimits().setMaxTtlCommandResponse(10L));
// WHEN sending a command response
sender.sendCommandResponse(tenant, new RegistrationAssertion(deviceId), commandResponse, NoopSpan.INSTANCE.context()).onComplete(ctx.succeeding(t -> {
ctx.verify(() -> {
// THEN the producer record is created from the given values...
final ProducerRecord<String, Buffer> record = mockProducer.history().get(0);
assertThat(record.key()).isEqualTo(deviceId);
assertThat(record.topic()).isEqualTo(new HonoTopic(HonoTopic.Type.COMMAND_RESPONSE, tenantId).toString());
assertThat(record.value().toString()).isEqualTo(payload);
// Verify if the record contains the necessary headers.
final Headers headers = record.headers();
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, MessageHelper.APP_PROPERTY_TENANT_ID, tenantId);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, MessageHelper.APP_PROPERTY_DEVICE_ID, deviceId);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, MessageHelper.SYS_PROPERTY_CORRELATION_ID, correlationId);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, MessageHelper.APP_PROPERTY_STATUS, status);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, MessageHelper.SYS_PROPERTY_CONTENT_TYPE, contentType);
final var creationTimeHeader = headers.headers(MessageHelper.SYS_PROPERTY_CREATION_TIME);
assertThat(creationTimeHeader).hasSize(1);
final Long creationTimeMillis = Json.decodeValue(Buffer.buffer(creationTimeHeader.iterator().next().value()), Long.class);
assertThat(creationTimeMillis).isGreaterThan(0L);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, MessageHelper.SYS_HEADER_PROPERTY_TTL, 10000L);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, additionalHeader1Name, additionalHeader1Value);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(headers, additionalHeader2Name, additionalHeader2Value);
verify(span).finish();
});
ctx.completeNow();
}));
}
use of org.eclipse.hono.util.ResourceLimits in project hono by eclipse.
the class ConnectedDevicesAsyncCacheLoaderTest method testAsyncLoadSucceedsIfUnlimited.
/**
* Verifies that a limited resource with no limit is returned if the tenant has been
* configured with unlimited connections explicitly.
*/
@Test
public void testAsyncLoadSucceedsIfUnlimited() {
givenCurrentConnections(90);
final TenantObject tenant = TenantObject.from(Constants.DEFAULT_TENANT, true).setResourceLimits(new ResourceLimits().setMaxConnections(TenantConstants.UNLIMITED_CONNECTIONS));
assertLimitedResourceResult(tenant, null, 0L);
}
use of org.eclipse.hono.util.ResourceLimits in project hono by eclipse.
the class ProtonBasedDownstreamSenderTest method testDownstreamTelemetryMessageHasCreationTimeAndTtl.
/**
* Verifies that a downstream telemetry message always contains a creation-time
* and a time-to-live as defined at the tenant level.
*
* @param qosLevel The quality of service used for sending the message.
* @param expectedTtl The time to live (in millis) expected to be set on the message.
*/
@ParameterizedTest
@CsvSource(value = { "AT_MOST_ONCE,10000", "AT_LEAST_ONCE,20000" })
public void testDownstreamTelemetryMessageHasCreationTimeAndTtl(final QoS qosLevel, final long expectedTtl) {
final TenantObject tenant = TenantObject.from(Constants.DEFAULT_TENANT, true);
tenant.setResourceLimits(new ResourceLimits().setMaxTtlTelemetryQoS0(10L).setMaxTtlTelemetryQoS1(20L));
final RegistrationAssertion device = new RegistrationAssertion("4711");
// WHEN sending a message without specifying any properties
sender.sendTelemetry(tenant, device, qosLevel, "text/plain", Buffer.buffer("hello"), null, span.context());
// THEN the message contains a creation-time
verify(protonSender).send(argThat(message -> message.getCreationTime() > 0 && message.getTtl() == expectedTtl), VertxMockSupport.anyHandler());
}
use of org.eclipse.hono.util.ResourceLimits in project hono by eclipse.
the class KafkaBasedTelemetrySenderTest method testSendTelemetryCreatesCorrectRecord.
/**
* Verifies that the Kafka record is created as expected when sending telemetry data.
*
* @param qos The quality of service used for sending the message.
* @param expectedTtl The ttl expected in the message.
* @param ctx The vert.x test context.
*/
@ParameterizedTest
@CsvSource(value = { "AT_MOST_ONCE,10000", "AT_LEAST_ONCE,60000" })
public void testSendTelemetryCreatesCorrectRecord(final QoS qos, final long expectedTtl, final VertxTestContext ctx) {
// GIVEN a telemetry sender
final String payload = "the-payload";
final String contentType = "text/plain";
final Map<String, Object> properties = Map.of("foo", "bar");
final var spanFinished = ctx.checkpoint();
final var messageHasHeaders = ctx.checkpoint();
final var span = TracingMockSupport.mockSpan();
doAnswer(invocation -> {
spanFinished.flag();
return null;
}).when(span).finish();
final var tracer = TracingMockSupport.mockTracer(span);
final var mockProducer = KafkaClientUnitTestHelper.newMockProducer(true);
final var factory = CachingKafkaProducerFactory.testFactory(vertxMock, (n, c) -> KafkaClientUnitTestHelper.newKafkaProducer(mockProducer));
final var sender = new KafkaBasedTelemetrySender(vertxMock, factory, kafkaProducerConfig, true, tracer);
tenant.setResourceLimits(new ResourceLimits().setMaxTtlTelemetryQoS0(10L).setMaxTtlTelemetryQoS1(60L));
// WHEN sending telemetry data
sender.sendTelemetry(tenant, device, qos, contentType, Buffer.buffer(payload), properties, null).onComplete(ctx.succeeding(t -> {
ctx.verify(() -> {
// THEN the producer record is created from the given values...
final var producerRecord = mockProducer.history().get(0);
assertThat(producerRecord.key()).isEqualTo(device.getDeviceId());
assertThat(producerRecord.topic()).isEqualTo(new HonoTopic(HonoTopic.Type.TELEMETRY, tenant.getTenantId()).toString());
assertThat(producerRecord.value().toString()).isEqualTo(payload);
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(producerRecord.headers(), "foo", "bar");
KafkaClientUnitTestHelper.assertUniqueHeaderWithExpectedValue(producerRecord.headers(), MessageHelper.SYS_HEADER_PROPERTY_TTL, expectedTtl);
// ...AND contains the standard headers
KafkaClientUnitTestHelper.assertStandardHeaders(producerRecord, device.getDeviceId(), contentType, qos.ordinal());
});
messageHasHeaders.flag();
}));
}
use of org.eclipse.hono.util.ResourceLimits in project hono by eclipse.
the class TenantApiTests method testGetTenant.
/**
* Verifies that an existing tenant can be retrieved.
*
* @param ctx The vert.x test context.
*/
@Timeout(value = 5, timeUnit = TimeUnit.SECONDS)
@Test
public void testGetTenant(final VertxTestContext ctx) {
final JsonObject defaults = new JsonObject().put("ttl", 30);
final Map<String, Object> httpAdapterExtensions = Map.of("deployment", Map.of("maxInstances", 4));
final ResourceLimits resourceLimits = new ResourceLimits().setMaxConnections(100000).setMaxTtl(30L).setDataVolume(new DataVolume(Instant.parse("2019-07-27T14:30:00Z"), new ResourceLimitsPeriod(PeriodMode.days).setNoOfDays(30), 2147483648L));
final String tenantId = getHelper().getRandomTenantId();
final Tenant tenant = new Tenant();
tenant.setEnabled(true);
tenant.setResourceLimits(resourceLimits);
tenant.setDefaults(defaults.getMap());
tenant.putExtension("customer", "ACME Inc.");
tenant.addAdapterConfig(new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_MQTT).setEnabled(true).setDeviceAuthenticationRequired(false)).addAdapterConfig(new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_HTTP).setEnabled(true).setDeviceAuthenticationRequired(true).setExtensions(httpAdapterExtensions));
// expected tenant object
final TenantObject expectedTenantObject = TenantObject.from(tenantId, true).setDefaults(defaults).setResourceLimits(resourceLimits).addAdapter(new org.eclipse.hono.util.Adapter(Constants.PROTOCOL_ADAPTER_TYPE_MQTT).setEnabled(Boolean.TRUE).setDeviceAuthenticationRequired(Boolean.FALSE)).addAdapter(new org.eclipse.hono.util.Adapter(Constants.PROTOCOL_ADAPTER_TYPE_HTTP).setEnabled(Boolean.TRUE).setDeviceAuthenticationRequired(Boolean.TRUE).setExtensions(httpAdapterExtensions));
getHelper().registry.addTenant(tenantId, tenant).compose(ok -> getAdminClient().get(tenantId, NoopSpan.INSTANCE.context())).onComplete(ctx.succeeding(tenantObject -> {
ctx.verify(() -> {
assertThat(tenantObject.getDefaults()).isEqualTo(expectedTenantObject.getDefaults());
Assertions.assertThat(tenantObject.getAdapters()).usingRecursiveFieldByFieldElementComparator().containsAll(expectedTenantObject.getAdapters());
assertThat(tenantObject.getResourceLimits().getMaxConnections()).isEqualTo(expectedTenantObject.getResourceLimits().getMaxConnections());
assertThat(tenantObject.getResourceLimits().getMaxTtl()).isEqualTo(expectedTenantObject.getResourceLimits().getMaxTtl());
assertThat(tenantObject.getResourceLimits().getDataVolume().getMaxBytes()).isEqualTo(expectedTenantObject.getResourceLimits().getDataVolume().getMaxBytes());
assertThat(tenantObject.getResourceLimits().getDataVolume().getEffectiveSince()).isEqualTo(expectedTenantObject.getResourceLimits().getDataVolume().getEffectiveSince());
assertThat(tenantObject.getResourceLimits().getDataVolume().getPeriod().getMode()).isEqualTo(expectedTenantObject.getResourceLimits().getDataVolume().getPeriod().getMode());
assertThat(tenantObject.getResourceLimits().getDataVolume().getPeriod().getNoOfDays()).isEqualTo(expectedTenantObject.getResourceLimits().getDataVolume().getPeriod().getNoOfDays());
final JsonObject extensions = tenantObject.getProperty("ext", JsonObject.class);
assertThat(extensions.getString("customer")).isEqualTo("ACME Inc.");
// implicitly added by DeviceRegistryHttpClient
assertThat(extensions.getString(TenantConstants.FIELD_EXT_MESSAGING_TYPE)).isEqualTo(IntegrationTestSupport.getConfiguredMessagingType().name());
});
ctx.completeNow();
}));
}
Aggregations