Search in sources :

Example 6 with AssumeMessagingSystem

use of org.eclipse.hono.tests.AssumeMessagingSystem in project hono by eclipse.

the class CommandAndControlAmqpIT method testSendCommandViaAmqpFailsForMalformedMessage.

/**
 * Verifies that the adapter rejects malformed command messages sent by applications.
 * <p>
 * This test is applicable only if the messaging network type is AMQP.
 *
 * @param endpointConfig The endpoints to use for sending/receiving commands.
 * @param ctx The vert.x test context.
 * @throws InterruptedException if not all commands and responses are exchanged in time.
 */
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("allCombinations")
@Timeout(timeUnit = TimeUnit.SECONDS, value = 10)
@AssumeMessagingSystem(type = MessagingType.amqp)
public void testSendCommandViaAmqpFailsForMalformedMessage(final AmqpCommandEndpointConfiguration endpointConfig, final VertxTestContext ctx) throws InterruptedException {
    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
    final AtomicReference<GenericSenderLink> amqpCmdSenderRef = new AtomicReference<>();
    final VertxTestContext setup = new VertxTestContext();
    final Checkpoint setupDone = setup.checkpoint();
    final Checkpoint preconditions = setup.checkpoint(2);
    connectToAdapter(tenantId, deviceId, password, () -> createEventConsumer(tenantId, msg -> {
        // expect empty notification with TTD -1
        setup.verify(() -> assertThat(msg.getContentType()).isEqualTo(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION));
        final TimeUntilDisconnectNotification notification = msg.getTimeUntilDisconnectNotification().orElse(null);
        log.debug("received notification [{}]", notification);
        setup.verify(() -> assertThat(notification).isNotNull());
        if (notification.getTtd() == -1) {
            preconditions.flag();
        }
    })).compose(con -> subscribeToCommands(endpointConfig, tenantId, commandTargetDeviceId).map(recv -> {
        recv.handler((delivery, msg) -> ctx.failNow(new IllegalStateException("should not have received command")));
        return null;
    })).compose(ok -> helper.createGenericAmqpMessageSender(endpointConfig.getNorthboundEndpoint(), tenantId)).map(s -> {
        log.debug("created generic sender for sending commands [target address: {}]", endpointConfig.getSenderLinkTargetAddress(tenantId));
        amqpCmdSenderRef.set(s);
        preconditions.flag();
        return s;
    }).onComplete(setup.succeeding(v -> setupDone.flag()));
    assertWithMessage("setup of adapter finished within %s seconds", IntegrationTestSupport.getTestSetupTimeout()).that(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    final Checkpoint expectedFailures = ctx.checkpoint(2);
    log.debug("sending command message lacking subject");
    final Message messageWithoutSubject = ProtonHelper.message("input data");
    messageWithoutSubject.setAddress(endpointConfig.getCommandMessageAddress(tenantId, commandTargetDeviceId));
    messageWithoutSubject.setMessageId("message-id");
    messageWithoutSubject.setReplyTo("reply/to/address");
    amqpCmdSenderRef.get().sendAndWaitForOutcome(messageWithoutSubject, NoopSpan.INSTANCE).onComplete(ctx.failing(t -> {
        ctx.verify(() -> assertThat(t).isInstanceOf(ClientErrorException.class));
        expectedFailures.flag();
    }));
    log.debug("sending command message lacking message ID and correlation ID");
    final Message messageWithoutId = ProtonHelper.message("input data");
    messageWithoutId.setAddress(endpointConfig.getCommandMessageAddress(tenantId, commandTargetDeviceId));
    messageWithoutId.setSubject("setValue");
    messageWithoutId.setReplyTo("reply/to/address");
    amqpCmdSenderRef.get().sendAndWaitForOutcome(messageWithoutId, NoopSpan.INSTANCE).onComplete(ctx.failing(t -> {
        ctx.verify(() -> assertThat(t).isInstanceOf(ClientErrorException.class));
        expectedFailures.flag();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) BiFunction(java.util.function.BiFunction) Tenant(org.eclipse.hono.service.management.tenant.Tenant) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) Timeout(io.vertx.junit5.Timeout) MessagingType(org.eclipse.hono.util.MessagingType) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) Duration(java.time.Duration) Map(java.util.Map) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) MethodSource(org.junit.jupiter.params.provider.MethodSource) ResourceLimits(org.eclipse.hono.util.ResourceLimits) MessageContext(org.eclipse.hono.application.client.MessageContext) SubscriberRole(org.eclipse.hono.tests.CommandEndpointConfiguration.SubscriberRole) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) DownstreamMessageAssertions(org.eclipse.hono.tests.DownstreamMessageAssertions) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Stream(java.util.stream.Stream) Buffer(io.vertx.core.buffer.Buffer) Optional(java.util.Optional) ProtonSender(io.vertx.proton.ProtonSender) Checkpoint(io.vertx.junit5.Checkpoint) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) VertxTestContext(io.vertx.junit5.VertxTestContext) GenericKafkaSender(org.eclipse.hono.tests.GenericKafkaSender) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) ClientErrorException(org.eclipse.hono.client.ClientErrorException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Constants(org.eclipse.hono.util.Constants) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) Message(org.apache.qpid.proton.message.Message) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) KafkaRecordHelper(org.eclipse.hono.client.kafka.KafkaRecordHelper) Truth.assertThat(com.google.common.truth.Truth.assertThat) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) NoopSpan(io.opentracing.noop.NoopSpan) GenericSenderLink(org.eclipse.hono.client.amqp.GenericSenderLink) Handler(io.vertx.core.Handler) Checkpoint(io.vertx.junit5.Checkpoint) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) Message(org.apache.qpid.proton.message.Message) VertxTestContext(io.vertx.junit5.VertxTestContext) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) GenericSenderLink(org.eclipse.hono.client.amqp.GenericSenderLink) AtomicReference(java.util.concurrent.atomic.AtomicReference) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) Timeout(io.vertx.junit5.Timeout) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 7 with AssumeMessagingSystem

use of org.eclipse.hono.tests.AssumeMessagingSystem in project hono by eclipse.

the class TelemetryJmsQoS1IT method testTelemetryUpload.

/**
 * Verifies that telemetry messages uploaded to the Hono server are all received
 * by a downstream consumer.
 *
 * @throws Exception if the test fails.
 */
@Test
@AssumeMessagingSystem(type = MessagingType.amqp)
public void testTelemetryUpload() throws Exception {
    final String tenantId = helper.getRandomTenantId();
    final String deviceId = helper.getRandomDeviceId(tenantId);
    final String username = IntegrationTestSupport.getUsername(deviceId, tenantId);
    final String pwd = "secret";
    final Tenant tenant = new Tenant();
    final VertxTestContext setup = new VertxTestContext();
    helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, pwd).compose(ok -> getAmqpAdapterConnection(username, pwd)).onComplete(setup.succeeding(connection -> {
        amqpAdapter = connection;
        setup.completeNow();
    }));
    assertTrue(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS));
    if (setup.failed()) {
        fail(setup.causeOfFailure());
    }
    final CountDownLatch latch = new CountDownLatch(IntegrationTestSupport.MSG_COUNT);
    final LongSummaryStatistics stats = new LongSummaryStatistics();
    givenATelemetryConsumer(tenantId);
    downstreamConsumer.setMessageListener(message -> {
        latch.countDown();
        gatherStatistics(stats, message);
        if (LOG.isInfoEnabled()) {
            final long messagesReceived = IntegrationTestSupport.MSG_COUNT - latch.getCount();
            if (messagesReceived % 100 == 0) {
                LOG.info("Received {} messages.", messagesReceived);
            }
        }
    });
    final MessageProducer messageProducer = amqpAdapter.createAnonymousProducer();
    final Destination telemetryEndpoint = JmsBasedHonoConnection.getDestination(TelemetryConstants.TELEMETRY_ENDPOINT);
    IntStream.range(1, IntegrationTestSupport.MSG_COUNT + 1).forEach(i -> {
        try {
            final Message message = amqpAdapter.newMessage("msg " + i, deviceId);
            messageProducer.send(telemetryEndpoint, message, DELIVERY_MODE, Message.DEFAULT_PRIORITY, Message.DEFAULT_TIME_TO_LIVE);
            if (i % 100 == 0) {
                LOG.info("Sent {} messages", i);
            }
        } catch (final JMSException e) {
            LOG.error("Error occurred while sending message: {}", e.getMessage(), e);
        }
    });
    final long timeToWait = Math.max(DEFAULT_TEST_TIMEOUT, Math.round(IntegrationTestSupport.MSG_COUNT * 1.2));
    // wait for messages to arrive
    assertTrue(latch.await(timeToWait, TimeUnit.MILLISECONDS), () -> "did not receive all " + IntegrationTestSupport.MSG_COUNT + " messages");
    LOG.info("Delivery statistics: {}", stats);
}
Also used : Assertions.fail(org.junit.jupiter.api.Assertions.fail) IntStream(java.util.stream.IntStream) VertxTestContext(io.vertx.junit5.VertxTestContext) BeforeEach(org.junit.jupiter.api.BeforeEach) LoggerFactory(org.slf4j.LoggerFactory) NamingException(javax.naming.NamingException) 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) MessageProducer(javax.jms.MessageProducer) DeliveryMode(javax.jms.DeliveryMode) Message(javax.jms.Message) LongSummaryStatistics(java.util.LongSummaryStatistics) Logger(org.slf4j.Logger) Vertx(io.vertx.core.Vertx) JmsBasedHonoConnection(org.eclipse.hono.tests.jms.JmsBasedHonoConnection) VertxExtension(io.vertx.junit5.VertxExtension) JMSException(javax.jms.JMSException) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) Future(io.vertx.core.Future) TestInfo(org.junit.jupiter.api.TestInfo) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AfterEach(org.junit.jupiter.api.AfterEach) MessageConsumer(javax.jms.MessageConsumer) Destination(javax.jms.Destination) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Checkpoint(io.vertx.junit5.Checkpoint) LongSummaryStatistics(java.util.LongSummaryStatistics) Destination(javax.jms.Destination) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Message(javax.jms.Message) VertxTestContext(io.vertx.junit5.VertxTestContext) JMSException(javax.jms.JMSException) MessageProducer(javax.jms.MessageProducer) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem)

Example 8 with AssumeMessagingSystem

use of org.eclipse.hono.tests.AssumeMessagingSystem in project hono by eclipse.

the class DeviceRegistryNotificationsIT method testReceiveNotificationViaAmqp.

/**
 * Verifies that AMQP-based notifications for adding tenant/device/credentials resources are received by a local
 * client.
 *
 * @param ctx The vert.x test context.
 * @throws InterruptedException if test is interrupted while running.
 */
@Test
@AssumeMessagingSystem(type = MessagingType.amqp)
public void testReceiveNotificationViaAmqp(final VertxTestContext ctx) throws InterruptedException {
    final ClientConfigProperties messagingNetworkProperties = IntegrationTestSupport.getMessagingNetworkProperties();
    // use user that may open receiver links on "notification/*" addresses
    messagingNetworkProperties.setUsername(NOTIFICATION_TEST_USER);
    messagingNetworkProperties.setPassword(NOTIFICATION_TEST_PWD);
    receiver = new ProtonBasedNotificationReceiver(HonoConnection.newConnection(vertx, messagingNetworkProperties));
    testReceiveNotification(ctx);
}
Also used : ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) ProtonBasedNotificationReceiver(org.eclipse.hono.client.notification.amqp.ProtonBasedNotificationReceiver) Test(org.junit.jupiter.api.Test) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem)

Example 9 with AssumeMessagingSystem

use of org.eclipse.hono.tests.AssumeMessagingSystem in project hono by eclipse.

the class CommandAndControlMqttIT method testSendCommandViaKafkaFailsForMalformedMessage.

/**
 * Verifies that the adapter rejects malformed command messages sent by applications.
 * <p>
 * This test is applicable only if the messaging network type is Kafka.
 *
 * @param endpointConfig The endpoints to use for sending/receiving commands.
 * @param ctx The vert.x test context.
 * @throws InterruptedException if not all commands and responses are exchanged in time.
 */
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("allCombinations")
@Timeout(timeUnit = TimeUnit.SECONDS, value = 20)
@AssumeMessagingSystem(type = MessagingType.kafka)
public void testSendCommandViaKafkaFailsForMalformedMessage(final MqttCommandEndpointConfiguration endpointConfig, final VertxTestContext ctx) throws InterruptedException {
    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
    final AtomicReference<GenericKafkaSender> kafkaSenderRef = new AtomicReference<>();
    final CountDownLatch expectedCommandResponses = new CountDownLatch(1);
    final VertxTestContext setup = new VertxTestContext();
    final Checkpoint ready = setup.checkpoint(2);
    final Future<MessageConsumer> kafkaAsyncErrorResponseConsumer = helper.createDeliveryFailureCommandResponseConsumer(ctx, tenantId, HttpURLConnection.HTTP_BAD_REQUEST, response -> expectedCommandResponses.countDown(), null);
    createConsumer(tenantId, msg -> {
        // expect empty notification with TTD -1
        setup.verify(() -> assertThat(msg.getContentType()).isEqualTo(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION));
        final TimeUntilDisconnectNotification notification = msg.getTimeUntilDisconnectNotification().orElse(null);
        LOGGER.info("received notification [{}]", notification);
        if (notification.getTtd() == -1) {
            ready.flag();
        }
    }).compose(consumer -> helper.registry.addDeviceToTenant(tenantId, deviceId, password)).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password)).compose(conAck -> subscribeToCommands(commandTargetDeviceId, msg -> {
        // all commands should get rejected because they fail to pass the validity check
        ctx.failNow(new IllegalStateException("should not have received command"));
    }, endpointConfig, MqttQoS.AT_MOST_ONCE)).compose(ok -> helper.createGenericKafkaSender().onSuccess(kafkaSenderRef::set).mapEmpty()).compose(ok -> kafkaAsyncErrorResponseConsumer).onComplete(setup.succeeding(v -> ready.flag()));
    assertWithMessage("setup of adapter finished within %s seconds", IntegrationTestSupport.getTestSetupTimeout()).that(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    final String commandTopic = new HonoTopic(HonoTopic.Type.COMMAND, tenantId).toString();
    LOGGER.debug("sending command message lacking subject and correlation ID - no failure response expected here");
    final Map<String, Object> properties1 = Map.of(MessageHelper.APP_PROPERTY_DEVICE_ID, deviceId, MessageHelper.SYS_PROPERTY_CONTENT_TYPE, MessageHelper.CONTENT_TYPE_OCTET_STREAM, KafkaRecordHelper.HEADER_RESPONSE_REQUIRED, true);
    kafkaSenderRef.get().sendAndWaitForOutcome(commandTopic, tenantId, deviceId, Buffer.buffer(), properties1).onComplete(ctx.succeeding(ok -> {
    }));
    LOGGER.debug("sending command message lacking subject");
    final String correlationId = "1";
    final Map<String, Object> properties2 = Map.of(MessageHelper.SYS_PROPERTY_CORRELATION_ID, correlationId, MessageHelper.APP_PROPERTY_DEVICE_ID, deviceId, MessageHelper.SYS_PROPERTY_CONTENT_TYPE, MessageHelper.CONTENT_TYPE_OCTET_STREAM, KafkaRecordHelper.HEADER_RESPONSE_REQUIRED, true);
    kafkaSenderRef.get().sendAndWaitForOutcome(commandTopic, tenantId, deviceId, Buffer.buffer(), properties2).onComplete(ctx.succeeding(ok -> {
    }));
    final long timeToWait = 2500;
    if (!expectedCommandResponses.await(timeToWait, TimeUnit.MILLISECONDS)) {
        LOGGER.info("Timeout of {} milliseconds reached, stop waiting for command response", timeToWait);
    }
    kafkaAsyncErrorResponseConsumer.result().close().onComplete(ar -> {
        if (expectedCommandResponses.getCount() == 0) {
            ctx.completeNow();
        } else {
            ctx.failNow(new java.lang.IllegalStateException("did not receive command response"));
        }
    });
}
Also used : GenericKafkaSender(org.eclipse.hono.tests.GenericKafkaSender) HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) Timeout(io.vertx.junit5.Timeout) MessagingType(org.eclipse.hono.util.MessagingType) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) ChannelPromise(io.netty.channel.ChannelPromise) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) MqttClientImpl(io.vertx.mqtt.impl.MqttClientImpl) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Method(java.lang.reflect.Method) MethodSource(org.junit.jupiter.params.provider.MethodSource) ChannelOutboundHandlerAdapter(io.netty.channel.ChannelOutboundHandlerAdapter) MessageContext(org.eclipse.hono.application.client.MessageContext) SubscriberRole(org.eclipse.hono.tests.CommandEndpointConfiguration.SubscriberRole) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) IllegalStateException(javax.jms.IllegalStateException) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) CountDownLatch(java.util.concurrent.CountDownLatch) Stream(java.util.stream.Stream) Buffer(io.vertx.core.buffer.Buffer) Checkpoint(io.vertx.junit5.Checkpoint) NetSocketInternal(io.vertx.core.net.impl.NetSocketInternal) VertxTestContext(io.vertx.junit5.VertxTestContext) GenericKafkaSender(org.eclipse.hono.tests.GenericKafkaSender) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Message(org.apache.qpid.proton.message.Message) MqttPubAckMessage(io.netty.handler.codec.mqtt.MqttPubAckMessage) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) KafkaRecordHelper(org.eclipse.hono.client.kafka.KafkaRecordHelper) Truth.assertThat(com.google.common.truth.Truth.assertThat) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) NoopSpan(io.opentracing.noop.NoopSpan) GenericSenderLink(org.eclipse.hono.client.amqp.GenericSenderLink) Handler(io.vertx.core.Handler) IllegalStateException(javax.jms.IllegalStateException) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) VertxTestContext(io.vertx.junit5.VertxTestContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) CountDownLatch(java.util.concurrent.CountDownLatch) Checkpoint(io.vertx.junit5.Checkpoint) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) Timeout(io.vertx.junit5.Timeout) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 10 with AssumeMessagingSystem

use of org.eclipse.hono.tests.AssumeMessagingSystem in project hono by eclipse.

the class TelemetryMqttQoS1IT method testUploadMessagesWithNoConsumerSendsErrors.

/**
 * Verifies that sending a number of telemetry messages to Hono's MQTT adapter while there is no consumer causes
 * corresponding error messages to be published to the client if it is subscribed on the error topic.
 *
 * @param ctx The test context.
 * @throws InterruptedException if the test fails.
 */
@Test
@AssumeMessagingSystem(type = MessagingType.amqp)
public void testUploadMessagesWithNoConsumerSendsErrors(final VertxTestContext ctx) throws InterruptedException {
    final String tenantId = helper.getRandomTenantId();
    final String deviceId = helper.getRandomDeviceId(tenantId);
    final Tenant tenant = new Tenant();
    final VertxTestContext setup = new VertxTestContext();
    helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, password).onComplete(setup.succeedingThenComplete());
    assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    // timeout value should be higher than the "hono.messaging.flowLatency" MQTT adapter configuration value
    // so that no timeout doesn't while the MQTT adapter waits for credit after having created the first downstream
    // sender link
    final long publishCompletionTimeout = 1500;
    doTestUploadMessages(ctx, tenantId, connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password), (payload) -> send(tenantId, deviceId, payload, true, null, publishCompletionTimeout).map(String::valueOf), // no consumer created here (future succeeded with null value)
    (messageHandler) -> Future.succeededFuture(), (msg) -> {
        final JsonObject payload = new JsonObject(msg.payload());
        final String correlationId = payload.getString(MessageHelper.SYS_PROPERTY_CORRELATION_ID);
        ctx.verify(() -> {
            assertThat(payload.getInteger("code")).isEqualTo(HttpURLConnection.HTTP_UNAVAILABLE);
            // error message should be the localized NoConsumerException message
            assertThat(payload.getString("message")).isEqualTo(ServiceInvocationException.getLocalizedMessage(NoConsumerException.CLIENT_FACING_MESSAGE_KEY));
            // validate topic segments; example: error//myDeviceId/telemetry/4/503
            final String[] topicSegments = msg.topicName().split("/");
            assertThat(topicSegments.length).isEqualTo(6);
            assertThat(topicSegments[0]).isEqualTo("e");
            assertThat(topicSegments[1]).isEqualTo(tenantId);
            // device
            assertThat(topicSegments[2]).isEmpty();
            assertThat(topicSegments[3]).isEqualTo(TelemetryConstants.TELEMETRY_ENDPOINT_SHORT);
            assertThat(topicSegments[4]).isEqualTo(correlationId);
            assertThat(topicSegments[5]).isEqualTo(Integer.toString(HttpURLConnection.HTTP_UNAVAILABLE));
        });
        return Future.succeededFuture(correlationId);
    }, String.format("e/%s//#", tenantId));
}
Also used : Tenant(org.eclipse.hono.service.management.tenant.Tenant) VertxTestContext(io.vertx.junit5.VertxTestContext) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.jupiter.api.Test) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem)

Aggregations

AssumeMessagingSystem (org.eclipse.hono.tests.AssumeMessagingSystem)10 VertxTestContext (io.vertx.junit5.VertxTestContext)8 Test (org.junit.jupiter.api.Test)8 Future (io.vertx.core.Future)7 Checkpoint (io.vertx.junit5.Checkpoint)7 VertxExtension (io.vertx.junit5.VertxExtension)7 TimeUnit (java.util.concurrent.TimeUnit)7 IntegrationTestSupport (org.eclipse.hono.tests.IntegrationTestSupport)7 MessagingType (org.eclipse.hono.util.MessagingType)7 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)7 Truth.assertThat (com.google.common.truth.Truth.assertThat)6 Handler (io.vertx.core.Handler)6 Promise (io.vertx.core.Promise)6 Buffer (io.vertx.core.buffer.Buffer)6 HttpURLConnection (java.net.HttpURLConnection)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 DownstreamMessage (org.eclipse.hono.application.client.DownstreamMessage)6 MessageConsumer (org.eclipse.hono.application.client.MessageConsumer)6 MessageContext (org.eclipse.hono.application.client.MessageContext)6 SendMessageTimeoutException (org.eclipse.hono.client.SendMessageTimeoutException)6