Java Code Examples for org.apache.qpid.proton.message.Message#setReplyTo()

The following examples show how to use org.apache.qpid.proton.message.Message#setReplyTo() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ProtonRequestClient.java    From enmasse with Apache License 2.0 6 votes vote down vote up
public Message request(Message message, long timeout, TimeUnit timeUnit) {
    Map<String, Object> properties = new HashMap<>();
    if (message.getApplicationProperties() != null) {
        properties.putAll(message.getApplicationProperties().getValue());
    }
    message.setApplicationProperties(new ApplicationProperties(properties));

    if (message.getReplyTo() == null) {
        message.setReplyTo(replyTo);
    }
    context.runOnContext(h -> sender.send(message));
    try {
        return replies.poll(timeout, timeUnit);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}
 
Example 2
Source File: CredentialsMessageFilterTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies that a message that does not contain a message-id nor correlation-id
 * does not pass the filter.
 */
@Test
public void testVerifyFailsForMissingCorrelationId() {

    // GIVEN a message with an unsupported subject
    final Message msg = ProtonHelper.message();
    msg.setReplyTo("reply");
    msg.setBody(new AmqpValue(BILLIE_HASHED_PASSWORD));
    msg.setContentType("application/json");

    // WHEN receiving the message via a link with any tenant
    final boolean filterResult = CredentialsMessageFilter.verify(target, msg);

    // THEN message validation fails
    assertFalse(filterResult);
}
 
Example 3
Source File: AsyncCommandClientImpl.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
@Override
public Future<Void> sendAsyncCommand(final String deviceId, final String command, final String contentType, final Buffer data,
        final String correlationId, final String replyId, final Map<String, Object> properties, final SpanContext context) {
    Objects.requireNonNull(command);
    Objects.requireNonNull(correlationId);
    Objects.requireNonNull(replyId);

    final Message message = ProtonHelper.message();
    message.setCorrelationId(correlationId);
    MessageHelper.setCreationTime(message);
    MessageHelper.setPayload(message, contentType, data);
    message.setSubject(command);
    message.setAddress(getTargetAddress(tenantId, deviceId));
    final String replyToAddress = String.format("%s/%s/%s", CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, tenantId, replyId);
    message.setReplyTo(replyToAddress);

    return sendAndWaitForOutcome(message, context).compose(ignore -> Future.succeededFuture());
}
 
Example 4
Source File: CommandTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies that a command can be created from a valid message having device-id as part of the reply-to address.
 * Verifies that the reply-to address contains the device-id and the reply-id is prefixed with flag 0.
 */
@Test
public void testForReplyToWithDeviceId() {
    final String replyToId = "the-reply-to-id";
    final String correlationId = "the-correlation-id";
    final Message message = ProtonHelper.message("input data");
    message.setAddress(String.format("%s/%s/%s",
            CommandConstants.COMMAND_ENDPOINT, Constants.DEFAULT_TENANT, "4711"));
    message.setSubject("doThis");
    message.setCorrelationId(correlationId);
    message.setReplyTo(String.format("%s/%s/%s/%s",
            CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, "4711", replyToId));
    final String replyToOptionsBitFlag = Command.encodeReplyToOptions(true);
    final Command cmd = Command.from(message, Constants.DEFAULT_TENANT, "4711");
    assertTrue(cmd.isValid());
    assertThat(cmd.getReplyToId()).isEqualTo(String.format("4711/%s", replyToId));
    assertThat(cmd.getCommandMessage()).isNotNull();
    assertThat(cmd.getCommandMessage().getReplyTo()).isNotNull();
    assertThat(cmd.getCommandMessage().getReplyTo()).isEqualTo(String.format("%s/%s/%s/%s%s",
            CommandConstants.COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, "4711", replyToOptionsBitFlag, replyToId));
}
 
Example 5
Source File: CommandTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies that a command can be created from a valid message.
 * Verifies that the replyToId are build up of all segments behind the tenant.
 */
@Test
public void testFromMessageSucceeds() {
    final String replyToId = "the-reply-to-id";
    final String correlationId = "the-correlation-id";
    final Message message = ProtonHelper.message("input data");
    message.setAddress(String.format("%s/%s/%s",
            CommandConstants.COMMAND_ENDPOINT, Constants.DEFAULT_TENANT, "4711"));
    message.setSubject("doThis");
    message.setCorrelationId(correlationId);
    message.setReplyTo(String.format("%s/%s/%s/%s",
            CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, "4711", replyToId));
    final boolean replyToContainedDeviceId = true;
    final String replyToOptionsBitFlag = Command.encodeReplyToOptions(replyToContainedDeviceId);
    final Command cmd = Command.from(message, Constants.DEFAULT_TENANT, "4711");
    assertTrue(cmd.isValid());
    assertThat(cmd.getName()).isEqualTo("doThis");
    assertThat(cmd.getDeviceId()).isEqualTo("4711");
    assertThat(cmd.getOriginalDeviceId()).isEqualTo("4711");
    assertThat(cmd.getReplyToId()).isEqualTo(String.format("4711/%s", replyToId));
    assertThat(cmd.getReplyToEndpoint()).isEqualTo(CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT);
    assertThat(cmd.getCorrelationId()).isEqualTo(correlationId);
    assertFalse(cmd.isOneWay());
    assertThat(cmd.getCommandMessage().getReplyTo()).isEqualTo(String.format("%s/%s/%s/%s%s",
            CommandConstants.COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, "4711", replyToOptionsBitFlag, replyToId));
}
 
Example 6
Source File: CommandTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies that a command can be created from a valid message having no device-id as part of the reply-to address.
 * Verifies that the reply-to address contains the device-id and the reply-id is prefixed with flag 1.
 */
@Test
public void testForReplyToWithoutDeviceId() {
    final String replyToId = "the-reply-to-id";
    final String correlationId = "the-correlation-id";
    final Message message = ProtonHelper.message("input data");
    message.setAddress(String.format("%s/%s/%s",
            CommandConstants.COMMAND_ENDPOINT, Constants.DEFAULT_TENANT, "4711"));
    message.setSubject("doThis");
    message.setCorrelationId(correlationId);
    message.setReplyTo(String.format("%s/%s/%s",
            CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, replyToId));
    final boolean replyToContainedDeviceId = false;
    final String replyToOptionsBitFlag = Command.encodeReplyToOptions(replyToContainedDeviceId);
    final Command cmd = Command.from(message, Constants.DEFAULT_TENANT, "4711");
    assertTrue(cmd.isValid());
    assertThat(cmd.getReplyToId()).isEqualTo(replyToId);
    assertThat(cmd.getCommandMessage()).isNotNull();
    assertThat(cmd.getCommandMessage().getReplyTo()).isNotNull();
    assertThat(cmd.getCommandMessage().getReplyTo()).isEqualTo(String.format("%s/%s/%s/%s%s",
            CommandConstants.COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, "4711", replyToOptionsBitFlag, replyToId));
}
 
Example 7
Source File: CommandTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that a command can be created from a valid message, containing a message address with device id
 * differing from the one given in the command constructor.
 * Verifies that the replyToId are build up of all segments behind the tenant.
 */
@Test
public void testFromMessageSucceedsWithDifferingDeviceId() {
    final String gatewayId = "gw-1";
    final String targetDeviceId = "4711";
    final String replyToId = "the-reply-to-id";
    final String correlationId = "the-correlation-id";
    final Message message = ProtonHelper.message("input data");
    message.setAddress(String.format("%s/%s/%s",
            CommandConstants.COMMAND_ENDPOINT, Constants.DEFAULT_TENANT, targetDeviceId));
    message.setSubject("doThis");
    message.setCorrelationId(correlationId);
    message.setReplyTo(String.format("%s/%s/%s/%s",
            CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, targetDeviceId, replyToId));
    final boolean replyToContainedDeviceId = true;
    final String replyToOptionsBitFlag = Command.encodeReplyToOptions(replyToContainedDeviceId);
    final Command cmd = Command.from(message, Constants.DEFAULT_TENANT, gatewayId);
    assertTrue(cmd.isValid());
    assertThat(cmd.getName()).isEqualTo("doThis");
    assertThat(cmd.getDeviceId()).isEqualTo(gatewayId);
    assertThat(cmd.getOriginalDeviceId()).isEqualTo(targetDeviceId);
    assertThat(cmd.getReplyToId()).isEqualTo(String.format("%s/%s", targetDeviceId, replyToId));
    assertThat(cmd.getReplyToEndpoint()).isEqualTo(CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT);
    assertThat(cmd.getCorrelationId()).isEqualTo(correlationId);
    assertFalse(cmd.isOneWay());
    assertThat(cmd.getCommandMessage().getReplyTo()).isEqualTo(String.format("%s/%s/%s/%s%s",
            CommandConstants.COMMAND_RESPONSE_ENDPOINT, Constants.DEFAULT_TENANT, "4711", replyToOptionsBitFlag, replyToId));
}
 
Example 8
Source File: RequestResponseEndpointTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the endpoint processes request messages for operations the client
 * is authorized to invoke.
 */
@SuppressWarnings("unchecked")
@Test
public void testHandleMessageProcessesAuthorizedRequests() {

    final Message msg = ProtonHelper.message();
    msg.setSubject("get");
    msg.setReplyTo(REPLY_RESOURCE.toString());
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    final AuthorizationService authService = mock(AuthorizationService.class);
    when(authService.isAuthorized(any(HonoUser.class), any(ResourceIdentifier.class), anyString())).thenReturn(Future.succeededFuture(Boolean.TRUE));

    final RequestResponseEndpoint<ServiceConfigProperties> endpoint = getEndpoint(true);
    endpoint.setAuthorizationService(authService);
    endpoint.onLinkAttach(connection, sender, REPLY_RESOURCE);

    // WHEN a request for an operation is received that the client is authorized to invoke
    endpoint.handleRequestMessage(connection, receiver, resource, delivery, msg);

    // THEN then the message gets processed
    final ArgumentCaptor<DeliveryState> deliveryState = ArgumentCaptor.forClass(DeliveryState.class);
    verify(delivery).disposition(deliveryState.capture(), eq(Boolean.TRUE));
    assertThat(deliveryState.getValue()).isInstanceOf(Accepted.class);
    verify(receiver, never()).close();
    verify(authService).isAuthorized(Constants.PRINCIPAL_ANONYMOUS, resource, "get");
    // and forwarded to the service instance
    final ArgumentCaptor<Handler<AsyncResult<io.vertx.core.eventbus.Message<Object>>>> replyHandler = ArgumentCaptor.forClass(Handler.class);
    verify(eventBus).request(eq(EVENT_BUS_ADDRESS), any(JsonObject.class), any(DeliveryOptions.class), replyHandler.capture());

    // WHEN the service implementation sends the response
    final EventBusMessage response = EventBusMessage.forStatusCode(HttpURLConnection.HTTP_ACCEPTED);
    final io.vertx.core.eventbus.Message<Object> reply = mock(io.vertx.core.eventbus.Message.class);
    when(reply.body()).thenReturn(response.toJson());
    replyHandler.getValue().handle(Future.succeededFuture(reply));

    // THEN the response is sent to the client
    verify(sender).send(any(Message.class));
    verify(receiver).flow(1);
}
 
Example 9
Source File: RequestResponseEndpointTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the endpoint returns a response with status code 400
 * for a request that contains malformed payload. 
 */
@SuppressWarnings("unchecked")
@Test
public void testHandleMessageSendsResponseForMalformedPayload() {

    final Message msg = ProtonHelper.message();
    msg.setSubject("get");
    msg.setReplyTo(REPLY_RESOURCE.toString());
    msg.setCorrelationId(UUID.randomUUID().toString());
    msg.setBody(new Data(new Binary(new byte[] { 0x01, 0x02, 0x03 })));

    final ProtonDelivery delivery = mock(ProtonDelivery.class);

    final RequestResponseEndpoint<ServiceConfigProperties> endpoint = getEndpoint(true);
    endpoint.onLinkAttach(connection, sender, REPLY_RESOURCE);

    // WHEN a request for an operation is received that the client is authorized to invoke
    endpoint.handleRequestMessage(connection, receiver, resource, delivery, msg);

    // THEN then the message is accepted
    verify(delivery).disposition(argThat(d -> d instanceof Accepted), eq(Boolean.TRUE));

    // and not forwarded to the service instance
    verify(eventBus, never()).request(eq(EVENT_BUS_ADDRESS), any(JsonObject.class), any(DeliveryOptions.class), any(Handler.class));

    // and a response with the expected status is sent to the client
    verify(sender).send(argThat(m -> hasStatusCode(m, HttpURLConnection.HTTP_BAD_REQUEST)));
    verify(receiver).flow(1);
}
 
Example 10
Source File: RequestResponseEndpointTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
private void testHandleMessageSendsResponseWithStatusCode(final Throwable error, final int expectedStatus) {

    final Message msg = ProtonHelper.message();
    msg.setSubject("get");
    msg.setReplyTo(REPLY_RESOURCE.toString());
    msg.setCorrelationId(UUID.randomUUID().toString());
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    final AuthorizationService authService = mock(AuthorizationService.class);
    when(authService.isAuthorized(any(HonoUser.class), any(ResourceIdentifier.class), anyString())).thenReturn(Future.succeededFuture(Boolean.TRUE));

    final RequestResponseEndpoint<ServiceConfigProperties> endpoint = getEndpoint(true);
    endpoint.setAuthorizationService(authService);
    endpoint.onLinkAttach(connection, sender, REPLY_RESOURCE);

    // WHEN a request for an operation is received that the client is authorized to invoke
    endpoint.handleRequestMessage(connection, receiver, resource, delivery, msg);

    // THEN then the message is accepted
    verify(delivery).disposition(argThat(d -> d instanceof Accepted), eq(Boolean.TRUE));
    // and forwarded to the service instance
    final ArgumentCaptor<Handler<AsyncResult<io.vertx.core.eventbus.Message<Object>>>> replyHandler = ArgumentCaptor.forClass(Handler.class);
    verify(eventBus).request(eq(EVENT_BUS_ADDRESS), any(JsonObject.class), any(DeliveryOptions.class), replyHandler.capture());

    // WHEN the service invocation times out
    replyHandler.getValue().handle(Future.failedFuture(error));

    // THEN a response with status 500 is sent to the client
    verify(sender).send(argThat(m -> hasStatusCode(m, expectedStatus)));
    verify(receiver).flow(1);
}
 
Example 11
Source File: RequestResponseEndpointTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the endpoint rejects request messages for operations the client
 * is not authorized to invoke.
 */
@SuppressWarnings("unchecked")
@Test
public void testHandleMessageSendsResponseForUnauthorizedRequests() {

    final Message msg = ProtonHelper.message();
    msg.setSubject("unauthorized");
    msg.setReplyTo(REPLY_RESOURCE.toString());
    msg.setCorrelationId(UUID.randomUUID().toString());
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    final AuthorizationService authService = mock(AuthorizationService.class);
    when(authService.isAuthorized(any(HonoUser.class), any(ResourceIdentifier.class), anyString())).thenReturn(Future.succeededFuture(Boolean.FALSE));
    final RequestResponseEndpoint<ServiceConfigProperties> endpoint = getEndpoint(true);
    endpoint.setAuthorizationService(authService);
    endpoint.onLinkAttach(connection, sender, REPLY_RESOURCE);

    // WHEN a request for an operation is received that the client is not authorized to invoke
    endpoint.handleRequestMessage(connection, receiver, resource, delivery, msg);

    // THEN the message is accepted
    final ArgumentCaptor<DeliveryState> deliveryState = ArgumentCaptor.forClass(DeliveryState.class);
    verify(delivery).disposition(deliveryState.capture(), eq(Boolean.TRUE));
    assertThat(deliveryState.getValue()).isInstanceOf(Accepted.class);
    verify(receiver, never()).close();
    verify(authService).isAuthorized(Constants.PRINCIPAL_ANONYMOUS, resource, "unauthorized");
    // but not forwarded to the service instance
    verify(eventBus, never()).request(anyString(), any(), any(DeliveryOptions.class), any(Handler.class));
    // and a response is sent to the client with status 403
    verify(sender).send(argThat(m -> hasStatusCode(m, HttpURLConnection.HTTP_FORBIDDEN)));
}
 
Example 12
Source File: DelegatedCommandSenderImpl.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private static Message createDelegatedCommandMessage(final Message originalMessage, final String replyToAddress) {
    Objects.requireNonNull(originalMessage);
    // copy original message
    final Message msg = MessageHelper.getShallowCopy(originalMessage);
    msg.setReplyTo(replyToAddress);
    return msg;
}
 
Example 13
Source File: CredentialsMessageFilterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private static Message givenAValidMessageWithoutBody(final CredentialsConstants.CredentialsAction action) {
    final Message msg = ProtonHelper.message();
    msg.setMessageId("msg");
    msg.setReplyTo("reply");
    msg.setSubject(action.toString());
    return msg;
}
 
Example 14
Source File: RegistrationMessageFilterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private static Message givenAMessageHavingProperties(final String deviceId, final String action) {
    final Message msg = ProtonHelper.message();
    msg.setMessageId("msg-id");
    msg.setReplyTo("reply");
    msg.setSubject(action);
    if (deviceId != null) {
        MessageHelper.addDeviceId(msg, deviceId);
    }
    return msg;
}
 
Example 15
Source File: TenantMessageFilterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private Message givenAMessageHavingProperties(final TenantConstants.TenantAction action) {
    final Message msg = ProtonHelper.message();
    msg.setMessageId("msg");
    msg.setReplyTo("reply");
    msg.setSubject(action.toString());
    return msg;
}
 
Example 16
Source File: TenantMessageFilterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the filter detects a missing subject.
 */
@Test
public void testVerifyDetectsMissingSubject() {

    // GIVEN a request message without a subject
    final Message msg = ProtonHelper.message();
    msg.setMessageId("msg");
    msg.setReplyTo("reply");
    // WHEN receiving the message via a link with any tenant
    final ResourceIdentifier linkTarget = getResourceIdentifier(DEFAULT_TENANT);

    // THEN message validation fails
    assertFalse(TenantMessageFilter.verify(linkTarget, msg));
}
 
Example 17
Source File: AmqpMessageTest.java    From smallrye-reactive-messaging with Apache License 2.0 4 votes vote down vote up
@Test
public void testMessageAttributes() {
    Map<String, Object> props = new LinkedHashMap<>();
    props.put("hello", "world");
    props.put("some", "content");
    Message message = message();
    message.setTtl(1);
    message.setDurable(true);
    message.setReplyTo("reply");
    ApplicationProperties apps = new ApplicationProperties(props);
    message.setApplicationProperties(apps);
    message.setContentType("text/plain");
    message.setCorrelationId("1234");
    message.setDeliveryCount(2);
    message.setExpiryTime(10000);
    message.setFooter(new Footer(props));
    message.setGroupId("some-group");
    message.setAddress("address");
    message.setCreationTime(System.currentTimeMillis());
    message.setSubject("subject");
    message.setUserId("username".getBytes());
    message.setPriority((short) 2);
    message.setBody(new AmqpValue("hello"));
    message.setMessageId("4321");

    AmqpMessage<?> msg = new AmqpMessage<>(new AmqpMessageImpl(message), null, null);
    assertThat(msg.getAddress()).isEqualTo("address");
    assertThat(msg.getApplicationProperties()).contains(entry("hello", "world"), entry("some", "content"));
    assertThat(msg.getContentType()).isEqualTo("text/plain");
    assertThat(msg.getCreationTime()).isNotZero();
    assertThat(msg.getDeliveryCount()).isEqualTo(2);
    assertThat(msg.getExpiryTime()).isEqualTo(10000);
    assertThat(msg.getGroupId()).isEqualTo("some-group");
    assertThat(msg.getTtl()).isEqualTo(1);
    assertThat(msg.getSubject()).isEqualTo("subject");
    assertThat(msg.getPriority()).isEqualTo((short) 2);
    assertThat(((AmqpValue) msg.getBody()).getValue()).isEqualTo("hello");
    assertThat(msg.getCorrelationId()).isEqualTo("1234");
    assertThat(msg.getMessageId()).isEqualTo("4321");
    assertThat(msg.getHeader()).isNotNull();
    assertThat(msg.isDurable()).isTrue();
    assertThat(msg.getError().name()).isEqualTo("OK");
    assertThat(msg.getGroupSequence()).isZero();

}
 
Example 18
Source File: CommandAndControlAmqpIT.java    From hono with Eclipse Public License 2.0 4 votes vote down vote up
/**
 * Verifies that the adapter rejects malformed command messages sent by applications.
 *
 * @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)
public void testSendCommandFailsForMalformedMessage(
        final AmqpCommandEndpointConfiguration endpointConfig,
        final VertxTestContext ctx) throws InterruptedException {

    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway()
            ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5)
            : deviceId;

    final AtomicReference<MessageSender> sender = new AtomicReference<>();
    final String targetAddress = endpointConfig.getSenderLinkTargetAddress(tenantId);

    final VertxTestContext setup = new VertxTestContext();
    final Checkpoint preconditions = setup.checkpoint(2);

    connectToAdapter(tenantId, tenant, deviceId, password, () -> createEventConsumer(tenantId, msg -> {
        // expect empty notification with TTD -1
        ctx.verify(() -> assertThat(msg.getContentType()).isEqualTo(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION));
        final TimeUntilDisconnectNotification notification = TimeUntilDisconnectNotification.fromMessage(msg).orElse(null);
        log.debug("received notification [{}]", notification);
        ctx.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.applicationClientFactory.createGenericMessageSender(targetAddress))
    .map(s -> {
        log.debug("created generic sender for sending commands [target address: {}]", targetAddress);
        sender.set(s);
        preconditions.flag();
        return s;
    })
    .onComplete(setup.completing());

    assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
    }

    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");
    sender.get().sendAndWaitForOutcome(messageWithoutSubject).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");
    sender.get().sendAndWaitForOutcome(messageWithoutId).onComplete(ctx.failing(t -> {
        ctx.verify(() -> assertThat(t).isInstanceOf(ClientErrorException.class));
        expectedFailures.flag();
    }));
}
 
Example 19
Source File: CommandAndControlMqttIT.java    From hono with Eclipse Public License 2.0 4 votes vote down vote up
/**
 * Verifies that the adapter rejects malformed command messages sent by applications.
 *
 * @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)
public void testSendCommandFailsForMalformedMessage(
        final MqttCommandEndpointConfiguration endpointConfig,
        final VertxTestContext ctx) throws InterruptedException {

    final VertxTestContext setup = new VertxTestContext();
    final Checkpoint ready = setup.checkpoint(3);

    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway()
            ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5)
            : deviceId;

    helper.registry
            .addDeviceForTenant(tenantId, tenant, deviceId, password)
            .compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password))
            .compose(ok -> createConsumer(tenantId, msg -> {
                // expect empty notification with TTD -1
                setup.verify(() -> assertThat(msg.getContentType()).isEqualTo(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION));
                final TimeUntilDisconnectNotification notification = TimeUntilDisconnectNotification
                        .fromMessage(msg).orElse(null);
                LOGGER.info("received notification [{}]", notification);
                if (notification.getTtd() == -1) {
                    ready.flag();
                }
            }))
            .compose(conAck -> subscribeToCommands(commandTargetDeviceId, msg -> {
                setup.failNow(new IllegalStateException("should not have received command"));
            }, endpointConfig, MqttQoS.AT_MOST_ONCE))
            .onComplete(ctx.succeeding(ok -> ready.flag()));

    final AtomicReference<MessageSender> sender = new AtomicReference<>();
    final String linkTargetAddress = endpointConfig.getSenderLinkTargetAddress(tenantId);

    helper.applicationClientFactory.createGenericMessageSender(linkTargetAddress)
    .map(s -> {
        LOGGER.debug("created generic sender for sending commands [target address: {}]", linkTargetAddress);
        sender.set(s);
        ready.flag();
        return s;
    });

    assertThat(setup.awaitCompletion(15, TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
    }

    final Checkpoint failedAttempts = ctx.checkpoint(2);
    final String messageAddress = endpointConfig.getCommandMessageAddress(tenantId, commandTargetDeviceId);

    LOGGER.debug("sending command message lacking subject");
    final Message messageWithoutSubject = ProtonHelper.message("input data");
    messageWithoutSubject.setAddress(messageAddress);
    messageWithoutSubject.setMessageId("message-id");
    messageWithoutSubject.setReplyTo("reply/to/address");
    sender.get().sendAndWaitForOutcome(messageWithoutSubject).onComplete(ctx.failing(t -> {
        ctx.verify(() -> assertThat(t).isInstanceOf(ClientErrorException.class));
        failedAttempts.flag();
    }));

    LOGGER.debug("sending command message lacking message ID and correlation ID");
    final Message messageWithoutId = ProtonHelper.message("input data");
    messageWithoutId.setAddress(messageAddress);
    messageWithoutId.setSubject("setValue");
    messageWithoutId.setReplyTo("reply/to/address");
    sender.get().sendAndWaitForOutcome(messageWithoutId).onComplete(ctx.failing(t -> {
        ctx.verify(() -> assertThat(t).isInstanceOf(ClientErrorException.class));
        failedAttempts.flag();
    }));
}
 
Example 20
Source File: AbstractRequestResponseClient.java    From hono with Eclipse Public License 2.0 3 votes vote down vote up
/**
 * Creates an AMQP message for a subject and address.
 * <p>
 * The message can be extended by arbitrary application properties passed in.
 *
 * @param subject The subject system property of the message.
 * @param address The address of the message, put in the <em>to</em> property.
 * @param appProperties The map containing arbitrary application properties.
 *                      Maybe null if no application properties are needed.
 * @return The Proton message constructed from the provided parameters.
 * @throws NullPointerException if the subject is {@code null}.
 * @throws IllegalArgumentException if the application properties contain not AMQP 1.0 compatible values
 *                  (see {@link AbstractHonoClient#setApplicationProperties(Message, Map)}
 */
private Message createMessage(final String subject, final String address,
        final Map<String, Object> appProperties) {

    Objects.requireNonNull(subject);
    final Message msg = ProtonHelper.message();
    final String messageId = createMessageId();
    AbstractHonoClient.setApplicationProperties(msg, appProperties);
    msg.setAddress(address);
    msg.setReplyTo(replyToAddress);
    msg.setMessageId(messageId);
    msg.setSubject(subject);
    return msg;
}