Search in sources :

Example 36 with TIMEOUT

use of org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT in project hono by eclipse.

the class RequestResponseClientTest method testCreateAndSendRequestFailsOnRejectedMessage.

private void testCreateAndSendRequestFailsOnRejectedMessage(final VertxTestContext ctx, final Symbol errorCondition, final Consumer<Throwable> failureAssertions) {
    // WHEN sending a request message with some headers and payload
    final JsonObject payload = new JsonObject().put("key", "value");
    client.compose(c -> c.createAndSendRequest("get", null, payload.toBuffer(), "application/json", SimpleRequestResponseResult::from, span)).onComplete(ctx.failing(t -> {
        ctx.verify(() -> {
            // THEN the result handler is failed with the expected error
            failureAssertions.accept(t);
            verify(sample).completed(isA(Rejected.class));
            // and a timer has been set to time out the request
            final ArgumentCaptor<Handler<Long>> timeoutHandlerCaptor = VertxMockSupport.argumentCaptorHandler();
            verify(vertx).setTimer(eq(clientConfig.getRequestTimeout()), timeoutHandlerCaptor.capture());
            // triggering the timer now that the request has been handled should not invoke the sampler timeout method
            timeoutHandlerCaptor.getValue().handle(1L);
            verify(sample, never()).timeout();
        });
        ctx.completeNow();
    }));
    // and the peer rejects the message
    final Rejected rejected = new Rejected();
    rejected.setError(ProtonHelper.condition(errorCondition, "request message cannot be processed"));
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    when(delivery.getRemoteState()).thenReturn(rejected);
    final ArgumentCaptor<Handler<ProtonDelivery>> dispositionHandlerCaptor = VertxMockSupport.argumentCaptorHandler();
    verify(sender).send(any(Message.class), dispositionHandlerCaptor.capture());
    dispositionHandlerCaptor.getValue().handle(delivery);
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Timeout(io.vertx.junit5.Timeout) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) Data(org.apache.qpid.proton.amqp.messaging.Data) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) Buffer(io.vertx.core.buffer.Buffer) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) AmqpClientUnitTestHelper(org.eclipse.hono.client.amqp.test.AmqpClientUnitTestHelper) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) ArgumentCaptor(org.mockito.ArgumentCaptor) Symbol(org.apache.qpid.proton.amqp.Symbol) Message(org.apache.qpid.proton.message.Message) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) HonoConnection(org.eclipse.hono.client.HonoConnection) ArgumentMatchers.isA(org.mockito.ArgumentMatchers.isA) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Tracer(io.opentracing.Tracer) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Mockito.never(org.mockito.Mockito.never) ResourceLimitExceededException(org.eclipse.hono.client.ResourceLimitExceededException) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ArgumentCaptor(org.mockito.ArgumentCaptor) ProtonDelivery(io.vertx.proton.ProtonDelivery) Message(org.apache.qpid.proton.message.Message) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) JsonObject(io.vertx.core.json.JsonObject) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) Handler(io.vertx.core.Handler) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected)

Example 37 with TIMEOUT

use of org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT in project hono by eclipse.

the class KafkaBasedCommandSenderTest method testSendCommandAndReceiveResponseTimesOut.

/**
 * Verifies that
 * {@link org.eclipse.hono.application.client.CommandSender#sendCommand(String, String, String, String, Buffer, String, Map, Duration, io.opentracing.SpanContext)}
 * fails as the timeout is reached.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testSendCommandAndReceiveResponseTimesOut(final VertxTestContext ctx) {
    final Context context = vertx.getOrCreateContext();
    commandSender.setKafkaConsumerSupplier(() -> mockConsumer);
    context.runOnContext(v -> {
        commandSender.sendCommand(tenantId, deviceId, "testCommand", "text/plain", Buffer.buffer("data"), null, null, Duration.ofMillis(5), null).onComplete(ctx.failing(error -> {
            ctx.verify(() -> {
                // VERIFY that the error is caused due to time out.
                assertThat(error).isInstanceOf(SendMessageTimeoutException.class);
                verify(span).finish();
            });
            ctx.completeNow();
        }));
    });
}
Also used : KafkaMessageContext(org.eclipse.hono.application.client.kafka.KafkaMessageContext) Context(io.vertx.core.Context) VertxTestContext(io.vertx.junit5.VertxTestContext) HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) MessagingKafkaConsumerConfigProperties(org.eclipse.hono.client.kafka.consumer.MessagingKafkaConsumerConfigProperties) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) MessagingKafkaProducerConfigProperties(org.eclipse.hono.client.kafka.producer.MessagingKafkaProducerConfigProperties) KafkaMessageContext(org.eclipse.hono.application.client.kafka.KafkaMessageContext) LoggerFactory(org.slf4j.LoggerFactory) OffsetResetStrategy(org.apache.kafka.clients.consumer.OffsetResetStrategy) Context(io.vertx.core.Context) Timeout(io.vertx.junit5.Timeout) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Duration(java.time.Duration) Map(java.util.Map) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) TimestampType(org.apache.kafka.common.record.TimestampType) TopicPartition(org.apache.kafka.common.TopicPartition) KafkaMockConsumer(org.eclipse.hono.kafka.test.KafkaMockConsumer) CachingKafkaProducerFactory(org.eclipse.hono.client.kafka.producer.CachingKafkaProducerFactory) UUID(java.util.UUID) RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Test(org.junit.jupiter.api.Test) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) Header(org.apache.kafka.common.header.Header) ConsumerRecord(org.apache.kafka.clients.consumer.ConsumerRecord) Span(io.opentracing.Span) Callback(org.apache.kafka.clients.producer.Callback) VertxTestContext(io.vertx.junit5.VertxTestContext) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) BufferSerializer(io.vertx.kafka.client.serialization.BufferSerializer) HashMap(java.util.HashMap) RecordHeader(org.apache.kafka.common.header.internals.RecordHeader) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) ArrayList(java.util.ArrayList) RecordHeaders(org.apache.kafka.common.header.internals.RecordHeaders) KafkaClientUnitTestHelper(org.eclipse.hono.kafka.test.KafkaClientUnitTestHelper) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) NoopTracerFactory(io.opentracing.noop.NoopTracerFactory) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) AfterEach(org.junit.jupiter.api.AfterEach) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) NoopSpan(io.opentracing.noop.NoopSpan) MockProducer(org.apache.kafka.clients.producer.MockProducer) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) Test(org.junit.jupiter.api.Test)

Example 38 with TIMEOUT

use of org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT in project hono by eclipse.

the class CommandAndControlAmqpIT 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 = 10)
@AssumeMessagingSystem(type = MessagingType.kafka)
public void testSendCommandViaKafkaFailsForMalformedMessage(final AmqpCommandEndpointConfiguration 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 setupDone = setup.checkpoint();
    final Checkpoint ttdReceivedPrecondition = setup.checkpoint();
    final Future<MessageConsumer> kafkaAsyncErrorResponseConsumer = helper.createDeliveryFailureCommandResponseConsumer(ctx, tenantId, HttpURLConnection.HTTP_BAD_REQUEST, response -> {
        ctx.verify(() -> {
            DownstreamMessageAssertions.assertMessageContainsTimeToLive(response, TTL_COMMAND_RESPONSE);
        });
        expectedCommandResponses.countDown();
    }, null);
    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) {
            ttdReceivedPrecondition.flag();
        }
    })).compose(con -> subscribeToCommands(endpointConfig, tenantId, commandTargetDeviceId).onSuccess(recv -> recv.handler((delivery, msg) -> ctx.failNow(new IllegalStateException("should not have received command"))))).compose(ok -> helper.createGenericKafkaSender().onSuccess(kafkaSenderRef::set).mapEmpty()).compose(v -> kafkaAsyncErrorResponseConsumer).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 String commandTopic = new HonoTopic(HonoTopic.Type.COMMAND, tenantId).toString();
    log.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 -> {
    }));
    log.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)) {
        log.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 IllegalStateException("did not receive command response"));
        }
    });
}
Also used : GenericKafkaSender(org.eclipse.hono.tests.GenericKafkaSender) 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) 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 39 with TIMEOUT

use of org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT 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 40 with TIMEOUT

use of org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT in project hono by eclipse.

the class CommandAndControlAmqpIT method testSendCommandFailsForCommandNotAcknowledgedByDevice.

/**
 * Verifies that the adapter forwards the <em>released</em> disposition back to the
 * application if the device hasn't sent a disposition update for the delivery of
 * the command message sent to the device.
 * <p>
 * If Kafka is used, this means a corresponding error command response is published.
 *
 * @param ctx The vert.x test context.
 * @throws InterruptedException if not all commands and responses are exchanged in time.
 */
@Test
@Timeout(timeUnit = TimeUnit.SECONDS, value = 10)
public void testSendCommandFailsForCommandNotAcknowledgedByDevice(final VertxTestContext ctx) throws InterruptedException {
    final AmqpCommandEndpointConfiguration endpointConfig = new AmqpCommandEndpointConfiguration(SubscriberRole.DEVICE);
    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
    final AtomicInteger receivedMessagesCounter = new AtomicInteger(0);
    final int totalNoOfCommandsToSend = 2;
    // command handler won't send a disposition update
    connectAndSubscribe(ctx, commandTargetDeviceId, endpointConfig, (cmdReceiver, cmdResponseSender) -> createNotSendingDeliveryUpdateCommandConsumer(ctx, cmdReceiver, receivedMessagesCounter), totalNoOfCommandsToSend);
    if (ctx.failed()) {
        return;
    }
    final String replyId = "reply-id";
    final CountDownLatch commandsFailed = new CountDownLatch(totalNoOfCommandsToSend);
    final AtomicInteger commandsSent = new AtomicInteger(0);
    final AtomicLong lastReceivedTimestamp = new AtomicLong();
    final long start = System.currentTimeMillis();
    final long commandTimeout = IntegrationTestSupport.getSendCommandTimeout();
    final Handler<Void> failureNotificationReceivedHandler = v -> {
        lastReceivedTimestamp.set(System.currentTimeMillis());
        commandsFailed.countDown();
    };
    final VertxTestContext setup = new VertxTestContext();
    final Future<MessageConsumer> kafkaAsyncErrorResponseConsumer = IntegrationTestSupport.isUsingKafkaMessaging() ? helper.createDeliveryFailureCommandResponseConsumer(ctx, tenantId, HttpURLConnection.HTTP_UNAVAILABLE, response -> failureNotificationReceivedHandler.handle(null), null) : Future.succeededFuture(null);
    kafkaAsyncErrorResponseConsumer.onComplete(setup.succeedingThenComplete());
    assertWithMessage("setup of command response consumer finished within %s seconds", IntegrationTestSupport.getTestSetupTimeout()).that(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    while (commandsSent.get() < totalNoOfCommandsToSend) {
        final CountDownLatch commandSent = new CountDownLatch(1);
        context.runOnContext(go -> {
            final String correlationId = String.valueOf(commandsSent.getAndIncrement());
            final Buffer msg = Buffer.buffer("value: " + commandsSent.get());
            helper.applicationClient.sendAsyncCommand(tenantId, commandTargetDeviceId, "setValue", "text/plain", msg, correlationId, replyId, null).onComplete(sendAttempt -> {
                if (IntegrationTestSupport.isUsingAmqpMessaging()) {
                    if (sendAttempt.succeeded()) {
                        log.debug("sending command {} succeeded unexpectedly", commandsSent.get());
                    } else {
                        if (sendAttempt.cause() instanceof ServerErrorException && ((ServerErrorException) sendAttempt.cause()).getErrorCode() == HttpURLConnection.HTTP_UNAVAILABLE && !(sendAttempt.cause() instanceof SendMessageTimeoutException)) {
                            log.debug("sending command {} failed as expected: {}", commandsSent.get(), sendAttempt.cause().toString());
                            failureNotificationReceivedHandler.handle(null);
                        } else {
                            log.debug("sending command {} failed with an unexpected error", commandsSent.get(), sendAttempt.cause());
                        }
                    }
                } else if (sendAttempt.failed()) {
                    log.debug("sending command {} via Kafka failed unexpectedly", commandsSent.get(), sendAttempt.cause());
                }
                commandSent.countDown();
            });
        });
        commandSent.await();
    }
    final long timeToWait = 300 + (totalNoOfCommandsToSend * commandTimeout);
    if (!commandsFailed.await(timeToWait, TimeUnit.MILLISECONDS)) {
        log.info("Timeout of {} milliseconds reached, stop waiting for commands", timeToWait);
    }
    assertThat(receivedMessagesCounter.get()).isEqualTo(totalNoOfCommandsToSend);
    final long commandsCompleted = totalNoOfCommandsToSend - commandsFailed.getCount();
    log.info("commands sent: {}, commands failed: {} after {} milliseconds", commandsSent.get(), commandsCompleted, lastReceivedTimestamp.get() - start);
    Optional.ofNullable(kafkaAsyncErrorResponseConsumer.result()).map(MessageConsumer::close).orElseGet(Future::succeededFuture).onComplete(ar -> {
        if (commandsCompleted == commandsSent.get()) {
            ctx.completeNow();
        } else {
            ctx.failNow(new IllegalStateException("did not complete all commands sent"));
        }
    });
}
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) Buffer(io.vertx.core.buffer.Buffer) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) VertxTestContext(io.vertx.junit5.VertxTestContext) CountDownLatch(java.util.concurrent.CountDownLatch) Checkpoint(io.vertx.junit5.Checkpoint) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ServerErrorException(org.eclipse.hono.client.ServerErrorException) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Timeout(io.vertx.junit5.Timeout)

Aggregations

Timeout (io.vertx.junit5.Timeout)75 VertxTestContext (io.vertx.junit5.VertxTestContext)70 Test (org.junit.jupiter.api.Test)69 TimeUnit (java.util.concurrent.TimeUnit)64 Truth.assertThat (com.google.common.truth.Truth.assertThat)62 Future (io.vertx.core.Future)53 HttpURLConnection (java.net.HttpURLConnection)50 Handler (io.vertx.core.Handler)47 IntegrationTestSupport (org.eclipse.hono.tests.IntegrationTestSupport)47 BeforeEach (org.junit.jupiter.api.BeforeEach)45 Buffer (io.vertx.core.buffer.Buffer)44 Promise (io.vertx.core.Promise)43 Vertx (io.vertx.core.Vertx)38 JsonObject (io.vertx.core.json.JsonObject)37 VertxExtension (io.vertx.junit5.VertxExtension)37 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)37 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)36 MethodSource (org.junit.jupiter.params.provider.MethodSource)34 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)33 Tenant (org.eclipse.hono.service.management.tenant.Tenant)33