Search in sources :

Example 1 with AmqpApplicationClient

use of org.eclipse.hono.application.client.amqp.AmqpApplicationClient in project hono by eclipse.

the class Receiver method start.

/**
 * Starts this component.
 * <p>
 *
 * @return A future indicating the outcome of the startup process.
 */
@PostConstruct
Future<CompositeFuture> start() {
    final Future<Void> startFuture;
    if (client instanceof AmqpApplicationClient) {
        final AmqpApplicationClient amqpClient = (AmqpApplicationClient) client;
        startFuture = amqpClient.connect().onComplete(con -> amqpClient.addReconnectListener(client -> createConsumer())).mapEmpty();
    } else {
        startFuture = Future.succeededFuture();
    }
    return startFuture.compose(c -> createConsumer()).onComplete(this::handleCreateConsumerStatus);
}
Also used : DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) MessageContext(org.eclipse.hono.application.client.MessageContext) Profile(org.springframework.context.annotation.Profile) Future(io.vertx.core.Future) ArrayList(java.util.ArrayList) Objects(java.util.Objects) Value(org.springframework.beans.factory.annotation.Value) CompositeFuture(io.vertx.core.CompositeFuture) List(java.util.List) Component(org.springframework.stereotype.Component) Buffer(io.vertx.core.buffer.Buffer) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) BiConsumer(java.util.function.BiConsumer) PostConstruct(javax.annotation.PostConstruct) AsyncResult(io.vertx.core.AsyncResult) Handler(io.vertx.core.Handler) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) PostConstruct(javax.annotation.PostConstruct)

Example 2 with AmqpApplicationClient

use of org.eclipse.hono.application.client.amqp.AmqpApplicationClient in project hono by eclipse.

the class ReceiverTest method clientFactoryVariants.

private static Stream<ApplicationClient<? extends MessageContext>> clientFactoryVariants() {
    final AmqpApplicationClient amqpApplicationClientFactory = mock(AmqpApplicationClient.class);
    when(amqpApplicationClientFactory.connect()).thenReturn(Future.succeededFuture());
    when(amqpApplicationClientFactory.createTelemetryConsumer(anyString(), VertxMockSupport.anyHandler(), VertxMockSupport.anyHandler())).thenReturn(Future.succeededFuture(mock(MessageConsumer.class)));
    when(amqpApplicationClientFactory.createEventConsumer(anyString(), VertxMockSupport.anyHandler(), VertxMockSupport.anyHandler())).thenReturn(Future.succeededFuture(mock(MessageConsumer.class)));
    final KafkaApplicationClient kafkaApplicationClientFactory = mock(KafkaApplicationClient.class);
    when(kafkaApplicationClientFactory.createTelemetryConsumer(anyString(), VertxMockSupport.anyHandler(), VertxMockSupport.anyHandler())).thenReturn(Future.succeededFuture(mock(MessageConsumer.class)));
    when(kafkaApplicationClientFactory.createEventConsumer(anyString(), VertxMockSupport.anyHandler(), VertxMockSupport.anyHandler())).thenReturn(Future.succeededFuture(mock(MessageConsumer.class)));
    return Stream.of(amqpApplicationClientFactory, kafkaApplicationClientFactory);
}
Also used : AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) KafkaApplicationClient(org.eclipse.hono.application.client.kafka.KafkaApplicationClient)

Example 3 with AmqpApplicationClient

use of org.eclipse.hono.application.client.amqp.AmqpApplicationClient 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 4 with AmqpApplicationClient

use of org.eclipse.hono.application.client.amqp.AmqpApplicationClient in project hono by eclipse.

the class HonoExampleApplicationBase method consumeData.

/**
 * Start the application client and set the message handling method to treat data that is received.
 */
protected void consumeData() {
    final CompletableFuture<ApplicationClient<? extends MessageContext>> startup = new CompletableFuture<>();
    if (client instanceof AmqpApplicationClient) {
        final AmqpApplicationClient ac = (AmqpApplicationClient) client;
        ac.addDisconnectListener(c -> LOG.info("lost connection to Hono, trying to reconnect ..."));
        ac.addReconnectListener(c -> LOG.info("reconnected to Hono"));
    }
    client.start().compose(v -> CompositeFuture.all(createEventConsumer(), createTelemetryConsumer())).onSuccess(ok -> startup.complete(client)).onFailure(startup::completeExceptionally);
    try {
        startup.join();
        LOG.info("Consumer ready for telemetry and event messages");
        System.in.read();
    } catch (final CompletionException e) {
        LOG.error("{} consumer failed to start [{}:{}]", USE_KAFKA ? "Kafka" : "AMQP", HonoExampleConstants.HONO_MESSAGING_HOST, port, e.getCause());
    } catch (final IOException e) {
    // nothing we can do
    }
    final CompletableFuture<ApplicationClient<? extends MessageContext>> shutDown = new CompletableFuture<>();
    @SuppressWarnings("rawtypes") final List<Future> closeFutures = new ArrayList<>();
    Optional.ofNullable(eventConsumer).map(MessageConsumer::close).ifPresent(closeFutures::add);
    Optional.ofNullable(telemetryConsumer).map(MessageConsumer::close).ifPresent(closeFutures::add);
    Optional.ofNullable(client).map(Lifecycle::stop).ifPresent(closeFutures::add);
    CompositeFuture.join(closeFutures).compose(ok -> vertx.close()).recover(t -> vertx.close()).onComplete(ar -> shutDown.complete(client));
    // wait for clients to be closed
    shutDown.join();
    LOG.info("Consumer has been shut down");
}
Also used : ApplicationClient(org.eclipse.hono.application.client.ApplicationClient) MessagingKafkaConsumerConfigProperties(org.eclipse.hono.client.kafka.consumer.MessagingKafkaConsumerConfigProperties) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) MessagingKafkaProducerConfigProperties(org.eclipse.hono.client.kafka.producer.MessagingKafkaProducerConfigProperties) Lifecycle(org.eclipse.hono.util.Lifecycle) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) ArrayList(java.util.ArrayList) CompositeFuture(io.vertx.core.CompositeFuture) ProtonBasedApplicationClient(org.eclipse.hono.application.client.amqp.ProtonBasedApplicationClient) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) HonoConnection(org.eclipse.hono.client.HonoConnection) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) Logger(org.slf4j.Logger) MessageContext(org.eclipse.hono.application.client.MessageContext) KafkaApplicationClientImpl(org.eclipse.hono.application.client.kafka.impl.KafkaApplicationClientImpl) CachingKafkaProducerFactory(org.eclipse.hono.client.kafka.producer.CachingKafkaProducerFactory) Vertx(io.vertx.core.Vertx) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) Future(io.vertx.core.Future) List(java.util.List) KafkaProducerFactory(org.eclipse.hono.client.kafka.producer.KafkaProducerFactory) Buffer(io.vertx.core.buffer.Buffer) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) Optional(java.util.Optional) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) CommonKafkaClientConfigProperties(org.eclipse.hono.client.kafka.CommonKafkaClientConfigProperties) Handler(io.vertx.core.Handler) ApplicationClient(org.eclipse.hono.application.client.ApplicationClient) ProtonBasedApplicationClient(org.eclipse.hono.application.client.amqp.ProtonBasedApplicationClient) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) ArrayList(java.util.ArrayList) IOException(java.io.IOException) AmqpApplicationClient(org.eclipse.hono.application.client.amqp.AmqpApplicationClient) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) CompletableFuture(java.util.concurrent.CompletableFuture) CompositeFuture(io.vertx.core.CompositeFuture) Future(io.vertx.core.Future) MessageContext(org.eclipse.hono.application.client.MessageContext)

Aggregations

AmqpApplicationClient (org.eclipse.hono.application.client.amqp.AmqpApplicationClient)4 Future (io.vertx.core.Future)3 Handler (io.vertx.core.Handler)3 Buffer (io.vertx.core.buffer.Buffer)3 DownstreamMessage (org.eclipse.hono.application.client.DownstreamMessage)3 MessageContext (org.eclipse.hono.application.client.MessageContext)3 CompositeFuture (io.vertx.core.CompositeFuture)2 Vertx (io.vertx.core.Vertx)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 MessageConsumer (org.eclipse.hono.application.client.MessageConsumer)2 ServiceInvocationException (org.eclipse.hono.client.ServiceInvocationException)2 Truth.assertThat (com.google.common.truth.Truth.assertThat)1 AsyncResult (io.vertx.core.AsyncResult)1 MultiMap (io.vertx.core.MultiMap)1 Promise (io.vertx.core.Promise)1 HttpHeaders (io.vertx.core.http.HttpHeaders)1 RequestOptions (io.vertx.core.http.RequestOptions)1 JsonObject (io.vertx.core.json.JsonObject)1 HttpResponse (io.vertx.ext.web.client.HttpResponse)1