use of io.vertx.core.Promise in project hono by eclipse.
the class EventCoapIT method testEventMessageAlreadySentIsDeliveredWhenConsumerConnects.
/**
* Verifies that an event message from a device has been successfully sent and a north bound application,
* which connects after the event has been sent, can successfully receive those event message.
*
* @param ctx The vert.x test context.
* @throws InterruptedException if test execution gets interrupted.
*/
@Test
public void testEventMessageAlreadySentIsDeliveredWhenConsumerConnects(final VertxTestContext ctx) throws InterruptedException {
final VertxTestContext setup = new VertxTestContext();
final String messagePayload = UUID.randomUUID().toString();
helper.registry.addDeviceForTenant(tenantId, new Tenant(), deviceId, SECRET).onComplete(setup.succeedingThenComplete());
assertThat(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
if (setup.failed()) {
ctx.failNow(setup.causeOfFailure());
return;
}
// WHEN a device that belongs to the tenant publishes an event
final Promise<OptionSet> sendEvent = Promise.promise();
final CoapClient client = getCoapClient();
final Request eventRequest = createCoapRequest(CoAP.Code.PUT, Type.CON, getPutResource(tenantId, deviceId), messagePayload.getBytes());
client.advanced(getHandler(sendEvent), eventRequest);
sendEvent.future().onSuccess(eventSent -> {
logger.debug("event message has been sent");
// THEN create a consumer once the event message has been successfully sent
logger.debug("opening event consumer for tenant [{}]", tenantId);
createConsumer(tenantId, msg -> {
// THEN verify that the event message has been received by the consumer
logger.debug("event message has been received by the consumer");
ctx.verify(() -> assertThat(msg.getPayload().toString()).isEqualTo(messagePayload));
ctx.completeNow();
});
}).onFailure(ctx::failNow);
}
use of io.vertx.core.Promise in project hono by eclipse.
the class TelemetryCoapIT method testUploadFailsForLargePayload.
/**
* Verifies that the upload of a telemetry message containing a payload that
* exceeds the CoAP adapter's configured max payload size fails with a 4.13
* response code.
*
* @param ctx The test context.
* @throws IOException if the CoAP request cannot be sent to the adapter.
* @throws ConnectorException if the CoAP request cannot be sent to the adapter.
*/
@Test
@Timeout(value = 10, timeUnit = TimeUnit.SECONDS)
public void testUploadFailsForLargePayload(final VertxTestContext ctx) throws ConnectorException, IOException {
final Tenant tenant = new Tenant();
helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET).compose(ok -> {
final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET);
final Request request = createCoapsRequest(Code.POST, Type.CON, getPostResource(), IntegrationTestSupport.getPayload(4096));
final Promise<OptionSet> result = Promise.promise();
client.advanced(getHandler(result, ResponseCode.REQUEST_ENTITY_TOO_LARGE), request);
return result.future();
}).onComplete(ctx.succeedingThenComplete());
}
use of io.vertx.core.Promise in project hono by eclipse.
the class TelemetryCoapIT method testUploadMessagesUsingClientCertificateWithAlias.
/**
* Verifies that a number of messages uploaded to Hono's CoAP adapter using TLS_ECDSA based authentication can be
* successfully consumed via the messaging infrastructure.
* <p>
* The device's tenant is being determined using the requested host name contained in the client's SNI TLS
* extension.
*
* @param ctx The test context.
* @throws InterruptedException if the test fails.
*/
@Test
public void testUploadMessagesUsingClientCertificateWithAlias(final VertxTestContext ctx) throws InterruptedException {
assumeTrue(IntegrationTestSupport.isTrustAnchorGroupsSupported(), "device registry does not support trust anchor groups");
assumeTrue(IntegrationTestSupport.isTenantAliasSupported(), "device registry does not support tenant aliases");
final var clientCertLoader = KeyLoader.fromFiles(vertx, PATH_DEVICE_KEY, PATH_DEVICE_CERT);
final var clientCert = (X509Certificate) clientCertLoader.getCertificateChain()[0];
final VertxTestContext setup = new VertxTestContext();
helper.getCertificate(PATH_CA_CERT).compose(caCert -> helper.registry.addTenant(helper.getRandomTenantId(), Tenants.createTenantForTrustAnchor(caCert).setTrustAnchorGroup("test-group")).map(caCert)).compose(caCert -> {
return helper.registry.addDeviceForTenant(tenantId, Tenants.createTenantForTrustAnchor(caCert).setTrustAnchorGroup("test-group").setAlias("test-alias"), deviceId, clientCert);
}).onComplete(setup.succeedingThenComplete());
assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
if (setup.failed()) {
ctx.failNow(setup.causeOfFailure());
return;
}
final CoapClient client = getCoapsClient(clientCertLoader);
testUploadMessages(ctx, tenantId, () -> warmUp(client, createCoapsRequest(Code.POST, getMessageType(), "test-alias." + IntegrationTestSupport.COAP_HOST, getPostResource(), "hello 0".getBytes(StandardCharsets.UTF_8))), count -> {
final Promise<OptionSet> result = Promise.promise();
final String payload = "hello " + count;
final Request request = createCoapsRequest(Code.POST, getMessageType(), "test-alias." + IntegrationTestSupport.COAP_HOST, getPostResource(), payload.getBytes(StandardCharsets.UTF_8));
client.advanced(getHandler(result), request);
return result.future();
});
}
use of io.vertx.core.Promise in project hono by eclipse.
the class KafkaBasedCommandConsumerFactoryImplIT method testCommandsGetForwardedInIncomingOrder.
/**
* Verifies that records, published on the tenant-specific Kafka command topic, get received by
* the consumer created by the factory and get forwarded on the internal command topic in the
* same order they were published.
*
* @param ctx The vert.x test context.
* @throws InterruptedException if test execution gets interrupted.
*/
@Test
@Timeout(value = 10, timeUnit = TimeUnit.SECONDS)
public void testCommandsGetForwardedInIncomingOrder(final VertxTestContext ctx) throws InterruptedException {
final String tenantId = "tenant_" + UUID.randomUUID();
final VertxTestContext setup = new VertxTestContext();
final int numTestCommands = 10;
final List<KafkaConsumerRecord<String, Buffer>> receivedRecords = new ArrayList<>();
final Promise<Void> allRecordsReceivedPromise = Promise.promise();
final List<String> receivedCommandSubjects = new ArrayList<>();
final Handler<KafkaConsumerRecord<String, Buffer>> recordHandler = record -> {
receivedRecords.add(record);
LOG.trace("received {}", record);
receivedCommandSubjects.add(KafkaRecordHelper.getSubject(record.headers()).orElse(""));
if (receivedRecords.size() == numTestCommands) {
allRecordsReceivedPromise.tryComplete();
}
};
final Deque<Promise<Void>> completionPromisesQueue = new LinkedList<>();
// don't let getting the target adapter instance finish immediately
// - let the futures complete in the reverse order
final Supplier<Future<Void>> targetAdapterInstanceGetterCompletionFutureSupplier = () -> {
final Promise<Void> resultPromise = Promise.promise();
completionPromisesQueue.addFirst(resultPromise);
// complete all promises in reverse order when processing the last command
if (completionPromisesQueue.size() == numTestCommands) {
completionPromisesQueue.forEach(Promise::complete);
}
return resultPromise.future();
};
final Context vertxContext = vertx.getOrCreateContext();
vertxContext.runOnContext(v0 -> {
final HonoKafkaConsumer internalConsumer = getInternalCommandConsumer(recordHandler);
final KafkaBasedCommandConsumerFactoryImpl consumerFactory = getKafkaBasedCommandConsumerFactory(targetAdapterInstanceGetterCompletionFutureSupplier, tenantId);
CompositeFuture.join(internalConsumer.start(), consumerFactory.start()).compose(f -> createCommandConsumer(tenantId, consumerFactory)).onComplete(setup.succeedingThenComplete());
});
assertThat(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
if (setup.failed()) {
ctx.failNow(setup.causeOfFailure());
return;
}
LOG.debug("command consumer started");
final List<String> sentCommandSubjects = new ArrayList<>();
IntStream.range(0, numTestCommands).forEach(i -> {
final String subject = "cmd_" + i;
sentCommandSubjects.add(subject);
sendOneWayCommand(tenantId, "myDeviceId", subject);
});
final long timerId = vertx.setTimer(8000, tid -> {
LOG.info("received records:{}{}", System.lineSeparator(), receivedRecords.stream().map(Object::toString).collect(Collectors.joining("," + System.lineSeparator())));
allRecordsReceivedPromise.tryFail(String.format("only received %d out of %d expected messages after 8s", receivedRecords.size(), numTestCommands));
});
allRecordsReceivedPromise.future().onComplete(ctx.succeeding(v -> {
vertx.cancelTimer(timerId);
ctx.verify(() -> {
assertThat(receivedCommandSubjects).isEqualTo(sentCommandSubjects);
});
ctx.completeNow();
}));
}
use of io.vertx.core.Promise in project hono by eclipse.
the class HttpTestBase method testAutoProvisioningViaGateway.
/**
* Verifies that an edge device is auto-provisioned if it connects via a gateway equipped with the corresponding
* authority.
*
* @param ctx The test context.
* @throws InterruptedException if the test fails.
*/
@Test
public void testAutoProvisioningViaGateway(final VertxTestContext ctx) throws InterruptedException {
final Tenant tenant = new Tenant();
final String gatewayId = helper.getRandomDeviceId(tenantId);
final Device gateway = new Device().setAuthorities(Collections.singleton(RegistryManagementConstants.AUTHORITY_AUTO_PROVISIONING_ENABLED));
final String edgeDeviceId = helper.getRandomDeviceId(tenantId);
final Promise<Void> provisioningNotificationReceived = Promise.promise();
helper.createAutoProvisioningMessageConsumers(ctx, provisioningNotificationReceived, tenantId, edgeDeviceId).compose(ok -> helper.registry.addDeviceForTenant(tenantId, tenant, gatewayId, gateway, PWD)).compose(ok -> {
final MultiMap requestHeaders = MultiMap.caseInsensitiveMultiMap().add(HttpHeaders.CONTENT_TYPE, "text/plain").add(HttpHeaders.AUTHORIZATION, getBasicAuth(tenantId, gatewayId, PWD)).add(HttpHeaders.ORIGIN, ORIGIN_URI);
final String uri = String.format("%s/%s/%s", getEndpointUri(), tenantId, edgeDeviceId);
return httpClient.update(uri, Buffer.buffer("hello"), requestHeaders, ResponsePredicate.status(HttpURLConnection.HTTP_ACCEPTED));
}).compose(ok -> provisioningNotificationReceived.future()).compose(ok -> helper.registry.getRegistrationInfo(tenantId, edgeDeviceId)).onComplete(ctx.succeeding(registrationResult -> {
ctx.verify(() -> {
final var info = registrationResult.bodyAsJsonObject();
IntegrationTestSupport.assertDeviceStatusProperties(info.getJsonObject(RegistryManagementConstants.FIELD_STATUS), true);
});
ctx.completeNow();
}));
}
Aggregations