Search in sources :

Example 51 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class JmsBasedCredentialsClient method sendRequest.

/**
 * Sends a request for an operation.
 *
 * @param tenantId The tenant to send the message for.
 * @param operation The name of the operation to invoke or {@code null} if the message
 *                  should not have a subject.
 * @param applicationProperties Application properties to set on the request message or
 *                              {@code null} if no properties should be set.
 * @param payload Payload to include or {@code null} if the message should have no body.
 * @return A future indicating the outcome of the operation.
 */
public Future<CredentialsObject> sendRequest(final String tenantId, final String operation, final Map<String, Object> applicationProperties, final Buffer payload) {
    final Message request;
    try {
        request = createMessage(payload);
        addProperties(request, applicationProperties);
        if (operation != null) {
            request.setJMSType(operation);
        }
        if (applicationProperties != null) {
            for (Map.Entry<String, Object> entry : applicationProperties.entrySet()) {
                if (entry.getValue() instanceof String) {
                    request.setStringProperty(entry.getKey(), (String) entry.getValue());
                } else {
                    request.setObjectProperty(entry.getKey(), entry.getValue());
                }
            }
        }
    } catch (final JMSException e) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, e));
    }
    final Future<JmsBasedRequestResponseClient<CredentialsResult<CredentialsObject>>> client = JmsBasedRequestResponseClient.forEndpoint(connection, CredentialsConstants.CREDENTIALS_ENDPOINT, tenantId);
    return client.compose(c -> c.send(request, this::getResult)).compose(credentialsResult -> {
        final Promise<CredentialsObject> result = Promise.promise();
        switch(credentialsResult.getStatus()) {
            case HttpURLConnection.HTTP_OK:
            case HttpURLConnection.HTTP_CREATED:
                result.complete(credentialsResult.getPayload());
                break;
            case HttpURLConnection.HTTP_NOT_FOUND:
                result.fail(new ClientErrorException(credentialsResult.getStatus(), "no such credentials"));
                break;
            default:
                result.fail(StatusCodeMapper.from(credentialsResult));
        }
        return result.future();
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Logger(org.slf4j.Logger) CredentialsResult(org.eclipse.hono.util.CredentialsResult) DecodeException(io.vertx.core.json.DecodeException) Promise(io.vertx.core.Promise) LoggerFactory(org.slf4j.LoggerFactory) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) JMSException(javax.jms.JMSException) Future(io.vertx.core.Future) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) Buffer(io.vertx.core.buffer.Buffer) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) Map(java.util.Map) CredentialsClient(org.eclipse.hono.client.registry.CredentialsClient) JsonObject(io.vertx.core.json.JsonObject) Message(javax.jms.Message) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) CredentialsAction(org.eclipse.hono.util.CredentialsConstants.CredentialsAction) CredentialsObject(org.eclipse.hono.util.CredentialsObject) Message(javax.jms.Message) CredentialsObject(org.eclipse.hono.util.CredentialsObject) ClientErrorException(org.eclipse.hono.client.ClientErrorException) JsonObject(io.vertx.core.json.JsonObject) CredentialsObject(org.eclipse.hono.util.CredentialsObject) JMSException(javax.jms.JMSException) Map(java.util.Map)

Example 52 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class TelemetryHttpIT method testUploadQos1MessageFailsIfDeliveryStateNotUpdated.

/**
 * Verifies that the upload of a QoS 1 telemetry message fails with a 503 status code
 * when the consumer doesn't update the message delivery state and the
 * <em>sendMessageTimeout</em> has elapsed.
 *
 * @param vertx The vert.x instance.
 * @param ctx The test context
 * @throws InterruptedException if test is interrupted while running.
 */
@Test
@AssumeMessagingSystem(type = MessagingType.amqp)
public void testUploadQos1MessageFailsIfDeliveryStateNotUpdated(final Vertx vertx, final VertxTestContext ctx) throws InterruptedException {
    final AmqpApplicationClient amqpApplicationClient = (AmqpApplicationClient) helper.applicationClient;
    // GIVEN a device and a north bound message consumer that doesn't update the message delivery state
    final Tenant tenant = new Tenant();
    final Checkpoint messageReceived = ctx.checkpoint();
    final Checkpoint deliveryStateCheckDone = ctx.checkpoint();
    final Checkpoint httpResponseReceived = ctx.checkpoint();
    final VertxTestContext setup = new VertxTestContext();
    final AtomicReference<ProtonDelivery> deliveryRef = new AtomicReference<>();
    helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, PWD).compose(ok -> amqpApplicationClient.createTelemetryConsumer(tenantId, msg -> {
        final Promise<Void> result = Promise.promise();
        final var delivery = msg.getMessageContext().getDelivery();
        deliveryRef.set(delivery);
        logger.debug("received message: {}", msg.getMessageContext().getRawMessage());
        ctx.verify(() -> {
            assertThat(delivery.remotelySettled()).isFalse();
            assertThat(delivery.getRemoteState()).isNull();
        });
        messageReceived.flag();
        // don't update the delivery state here
        return result.future();
    }, remoteClose -> {
    })).onComplete(setup.succeedingThenComplete());
    assertThat(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    // WHEN the device tries to upload a telemetry message
    final MultiMap requestHeaders = MultiMap.caseInsensitiveMultiMap().add(HttpHeaders.CONTENT_TYPE, "binary/octet-stream").add(HttpHeaders.AUTHORIZATION, authorization).add(HttpHeaders.ORIGIN, ORIGIN_URI).add(Constants.HEADER_QOS_LEVEL, "1");
    final Future<HttpResponse<Buffer>> httpResponseFuture = httpClient.create(getEndpointUri(), Buffer.buffer("hello"), requestHeaders, // THEN the message gets rejected by the HTTP adapter with a 503
    ResponsePredicate.status(HttpURLConnection.HTTP_UNAVAILABLE));
    httpResponseFuture.onComplete(ctx.succeeding(response -> {
        ctx.verify(() -> {
            final var body = response.bodyAsJsonObject();
            assertThat(body.getString(RequestResponseApiConstants.FIELD_ERROR)).isEqualTo(ServiceInvocationException.getLocalizedMessage(SendMessageTimeoutException.CLIENT_FACING_MESSAGE_KEY));
        });
        httpResponseReceived.flag();
        // verify that the telemetry message delivery is remotely settled via the timeout handling in the adapter
        vertx.setTimer(50, tid -> {
            ctx.verify(() -> {
                final ProtonDelivery delivery = deliveryRef.get();
                assertThat(delivery).isNotNull();
                assertThat(delivery.remotelySettled()).isTrue();
                assertThat(delivery.getRemoteState()).isNotNull();
                assertThat(delivery.getRemoteState().getType()).isEqualTo(DeliveryState.DeliveryStateType.Released);
            });
            deliveryStateCheckDone.flag();
        });
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) ResponsePredicate(io.vertx.ext.web.client.predicate.ResponsePredicate) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) HttpResponse(io.vertx.ext.web.client.HttpResponse) ProtonDelivery(io.vertx.proton.ProtonDelivery) MultiMap(io.vertx.core.MultiMap) RequestOptions(io.vertx.core.http.RequestOptions) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) NoConsumerException(org.eclipse.hono.client.NoConsumerException) Tenant(org.eclipse.hono.service.management.tenant.Tenant) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) MessagingType(org.eclipse.hono.util.MessagingType) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Tenants(org.eclipse.hono.tests.Tenants) MessageContext(org.eclipse.hono.application.client.MessageContext) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) HttpHeaders(io.vertx.core.http.HttpHeaders) Truth.assertThat(com.google.common.truth.Truth.assertThat) RequestResponseApiConstants(org.eclipse.hono.util.RequestResponseApiConstants) VertxExtension(io.vertx.junit5.VertxExtension) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) Buffer(io.vertx.core.buffer.Buffer) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) Checkpoint(io.vertx.junit5.Checkpoint) Handler(io.vertx.core.Handler) QoS(org.eclipse.hono.util.QoS) ProtonDelivery(io.vertx.proton.ProtonDelivery) VertxTestContext(io.vertx.junit5.VertxTestContext) HttpResponse(io.vertx.ext.web.client.HttpResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) MultiMap(io.vertx.core.MultiMap) Checkpoint(io.vertx.junit5.Checkpoint) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Test(org.junit.jupiter.api.Test) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem)

Example 53 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class MqttPublishTestBase 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 String tenantId = helper.getRandomTenantId();
    final Tenant tenant = new Tenant();
    final String gatewayId = helper.getRandomDeviceId(tenantId);
    final Device gateway = new Device().setAuthorities(Set.of(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, password)).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(gatewayId, tenantId), password)).compose(ok -> {
        customizeConnectedClient();
        return send(tenantId, edgeDeviceId, Buffer.buffer("hello".getBytes()), false, null);
    }).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();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) HashMap(java.util.HashMap) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ServiceConfigProperties(org.eclipse.hono.config.ServiceConfigProperties) Tenant(org.eclipse.hono.service.management.tenant.Tenant) CompositeFuture(io.vertx.core.CompositeFuture) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) Tenants(org.eclipse.hono.tests.Tenants) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) MqttConnAckMessage(io.vertx.mqtt.messages.MqttConnAckMessage) Device(org.eclipse.hono.service.management.device.Device) QueryStringEncoder(io.netty.handler.codec.http.QueryStringEncoder) MessageContext(org.eclipse.hono.application.client.MessageContext) Promise(io.vertx.core.Promise) Set(java.util.Set) ServerErrorException(org.eclipse.hono.client.ServerErrorException) DownstreamMessageAssertions(org.eclipse.hono.tests.DownstreamMessageAssertions) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) MessageHelper(org.eclipse.hono.util.MessageHelper) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) Optional(java.util.Optional) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) Handler(io.vertx.core.Handler) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Device(org.eclipse.hono.service.management.device.Device) Test(org.junit.jupiter.api.Test)

Example 54 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class MqttConnectionIT method testDeviceConnectionIsClosedOnDeviceOrTenantDisabledOrDeleted.

private void testDeviceConnectionIsClosedOnDeviceOrTenantDisabledOrDeleted(final VertxTestContext ctx, final Supplier<Future<?>> deviceRegistryChangeOperation) {
    final Promise<Void> connectionClosedPromise = Promise.promise();
    // GIVEN a connected device
    helper.registry.addDeviceForTenant(tenantId, new Tenant(), deviceId, password).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password)).compose(conAckMsg -> {
        ctx.verify(() -> assertThat(conAckMsg.code()).isEqualTo(MqttConnectReturnCode.CONNECTION_ACCEPTED));
        mqttClient.closeHandler(remoteClose -> connectionClosedPromise.complete());
        // WHEN corresponding device/tenant is removed/disabled
        return deviceRegistryChangeOperation.get();
    }).compose(ok -> connectionClosedPromise.future()).onComplete(ctx.succeedingThenComplete());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) BeforeEach(org.junit.jupiter.api.BeforeEach) X500Principal(javax.security.auth.x500.X500Principal) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) X509CertificateCredential(org.eclipse.hono.service.management.credentials.X509CertificateCredential) Supplier(java.util.function.Supplier) Constants(org.eclipse.hono.util.Constants) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) JsonObject(io.vertx.core.json.JsonObject) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) Tenants(org.eclipse.hono.tests.Tenants) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) ValueSource(org.junit.jupiter.params.provider.ValueSource) Device(org.eclipse.hono.service.management.device.Device) Promise(io.vertx.core.Promise) X509CertificateSecret(org.eclipse.hono.service.management.credentials.X509CertificateSecret) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) List(java.util.List) Adapter(org.eclipse.hono.util.Adapter) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Collections(java.util.Collections) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) Tenant(org.eclipse.hono.service.management.tenant.Tenant)

Example 55 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class CredentialsApiAuthProvider method validateCredentials.

/**
 * Verifies that the credentials provided by a device during the authentication
 * process match the credentials on record for that device.
 *
 * @param deviceCredentials The credentials provided by the device.
 * @param credentialsOnRecord The credentials to match against.
 * @param spanContext The OpenTracing context to use for tracking the operation.
 * @return A future that is succeeded with the authenticated device if the
 *         credentials have been validated successfully. Otherwise, the
 *         future is failed with a {@link ServiceInvocationException}.
 */
private Future<Device> validateCredentials(final T deviceCredentials, final CredentialsObject credentialsOnRecord, final SpanContext spanContext) {
    final Span currentSpan = TracingHelper.buildServerChildSpan(tracer, spanContext, "validate credentials", getClass().getSimpleName()).withTag(MessageHelper.APP_PROPERTY_TENANT_ID, deviceCredentials.getTenantId()).withTag(TracingHelper.TAG_AUTH_ID.getKey(), deviceCredentials.getAuthId()).withTag(TracingHelper.TAG_CREDENTIALS_TYPE.getKey(), deviceCredentials.getType()).start();
    final Promise<Device> result = Promise.promise();
    if (!deviceCredentials.getAuthId().equals(credentialsOnRecord.getAuthId())) {
        currentSpan.log(String.format("Credentials service returned wrong credentials-on-record [auth-id: %s]", credentialsOnRecord.getAuthId()));
        result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
    } else if (!deviceCredentials.getType().equals(credentialsOnRecord.getType())) {
        currentSpan.log(String.format("Credentials service returned wrong credentials-on-record [type: %s]", credentialsOnRecord.getType()));
        result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
    } else if (!credentialsOnRecord.isEnabled()) {
        currentSpan.log("credentials-on-record are disabled");
        result.fail(new ClientErrorException(HttpURLConnection.HTTP_UNAUTHORIZED));
    } else {
        doValidateCredentials(deviceCredentials, credentialsOnRecord).onComplete(result);
    }
    return result.future().map(device -> {
        currentSpan.log("validation of credentials succeeded");
        currentSpan.finish();
        return device;
    }).recover(t -> {
        currentSpan.log("validation of credentials failed");
        TracingHelper.logError(currentSpan, t);
        currentSpan.finish();
        return Future.failedFuture(t);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) LoggerFactory(org.slf4j.LoggerFactory) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) DeviceUser(org.eclipse.hono.service.auth.DeviceUser) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) User(io.vertx.ext.auth.User) CredentialsClient(org.eclipse.hono.client.registry.CredentialsClient) Span(io.opentracing.Span) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) AsyncResult(io.vertx.core.AsyncResult) Handler(io.vertx.core.Handler) CredentialsObject(org.eclipse.hono.util.CredentialsObject) Device(org.eclipse.hono.auth.Device) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Span(io.opentracing.Span)

Aggregations

Promise (io.vertx.core.Promise)155 Future (io.vertx.core.Future)122 Handler (io.vertx.core.Handler)95 List (java.util.List)86 Vertx (io.vertx.core.Vertx)85 Buffer (io.vertx.core.buffer.Buffer)83 TimeUnit (java.util.concurrent.TimeUnit)79 HttpURLConnection (java.net.HttpURLConnection)66 Logger (org.slf4j.Logger)63 LoggerFactory (org.slf4j.LoggerFactory)63 Optional (java.util.Optional)62 AsyncResult (io.vertx.core.AsyncResult)61 Truth.assertThat (com.google.common.truth.Truth.assertThat)60 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)60 VertxTestContext (io.vertx.junit5.VertxTestContext)59 Test (org.junit.jupiter.api.Test)58 Map (java.util.Map)54 UUID (java.util.UUID)52 ArrayList (java.util.ArrayList)51 JsonObject (io.vertx.core.json.JsonObject)50