io.vertx.proton.ProtonDelivery Java Examples
The following examples show how to use
io.vertx.proton.ProtonDelivery.
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: TelemetrySenderImplTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the sender does not wait for the peer to settle and * accept a message before succeeding. */ @Test public void testSendMessageDoesNotWaitForAcceptedOutcome() { // GIVEN a sender that has credit when(sender.sendQueueFull()).thenReturn(Boolean.FALSE); final DownstreamSender messageSender = new TelemetrySenderImpl(connection, sender, "tenant", "telemetry/tenant"); final AtomicReference<Handler<ProtonDelivery>> handlerRef = new AtomicReference<>(); doAnswer(invocation -> { handlerRef.set(invocation.getArgument(1)); return mock(ProtonDelivery.class); }).when(sender).send(any(Message.class), VertxMockSupport.anyHandler()); // WHEN trying to send a message final Future<ProtonDelivery> result = messageSender.send("device", "some payload", "application/text"); // which gets rejected by the peer final ProtonDelivery rejected = mock(ProtonDelivery.class); when(rejected.remotelySettled()).thenReturn(Boolean.TRUE); when(rejected.getRemoteState()).thenReturn(new Rejected()); handlerRef.get().handle(rejected); // THEN the resulting future is succeeded nevertheless assertTrue(result.succeeded()); // and the message has been sent verify(sender).send(any(Message.class), eq(handlerRef.get())); }
Example #2
Source File: MappingAndDelegatingCommandHandlerTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies the behaviour of the <em>mapAndDelegateIncomingCommandMessage</em> method in a scenario where * the command shall get handled by another adapter instance and where sending the command message to * the adapter instance fails. */ @Test public void testMapWithCommandHandlerOnAnotherInstanceWithMessageSendingFailed() { final String deviceId = "4711"; // GIVEN a deviceId commandHandler registered for another adapter instance (not the local one) final String otherAdapterInstance = "otherAdapterInstance"; when(commandTargetMapper.getTargetGatewayAndAdapterInstance(anyString(), anyString(), any())) .thenReturn(Future.succeededFuture(createTargetAdapterInstanceJson(deviceId, otherAdapterInstance))); // AND an error when sending the command message to another adapter instance (no credit) when(sender.sendQueueFull()).thenReturn(Boolean.TRUE); // register local command handler - that shall not get used final AtomicReference<CommandContext> localHandlerCmdContextRef = new AtomicReference<>(); adapterInstanceCommandHandler.putDeviceSpecificCommandHandler(Constants.DEFAULT_TENANT, deviceId, null, localHandlerCmdContextRef::set); // WHEN mapping and delegating the command message final Message message = getValidCommandMessage(deviceId); final ProtonDelivery delivery = mock(ProtonDelivery.class); mappingAndDelegatingCommandHandler.mapAndDelegateIncomingCommandMessage(Constants.DEFAULT_TENANT, delivery, message); // THEN the delivery gets RELEASED verify(delivery).disposition(any(Released.class), eq(true)); assertThat(localHandlerCmdContextRef.get()).isNull(); }
Example #3
Source File: AbstractRequestResponseClientTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the adapter puts the response from the service to the cache * using the max age indicated by a response's <em>max-age</em> cache directive. * * @param ctx The vert.x test context. */ @Test public void testCreateAndSendRequestAddsResponseToCacheWithMaxAge(final VertxTestContext ctx) { // GIVEN an adapter with an empty cache client.setResponseCache(cache); // WHEN sending a request client.createAndSendRequest("get", (Buffer) null, ctx.succeeding(result -> { assertEquals(200, result.getStatus()); // THEN the response has been put to the cache verify(cache).put(eq("cacheKey"), any(SimpleRequestResponseResult.class), eq(Duration.ofSeconds(35))); ctx.completeNow(); }), "cacheKey"); final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sender).send(messageCaptor.capture(), VertxMockSupport.anyHandler()); final Message response = ProtonHelper.message("result"); MessageHelper.addProperty(response, MessageHelper.APP_PROPERTY_STATUS, HttpURLConnection.HTTP_OK); MessageHelper.addCacheDirective(response, CacheDirective.maxAgeDirective(35)); response.setCorrelationId(messageCaptor.getValue().getMessageId()); final ProtonDelivery delivery = mock(ProtonDelivery.class); client.handleResponse(delivery, response); }
Example #4
Source File: VertxBasedHttpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that a POST request to the command reply URI for that the delivery to the associated link is being remotely settled * results in a {@link HttpURLConnection#HTTP_ACCEPTED}. * @param ctx The vert.x test context. */ @Test public void testPostCmdResponseForExistingCommandResponseLinkResultsInAccepted(final VertxTestContext ctx) { final ProtonDelivery remotelySettledDelivery = mock(ProtonDelivery.class); when(remotelySettledDelivery.remotelySettled()).thenReturn(Boolean.TRUE); mockSuccessfulAuthentication("DEFAULT_TENANT", "device_1"); when(commandResponseSender.sendCommandResponse(any(CommandResponse.class), (SpanContext) any())).thenReturn( Future.succeededFuture(remotelySettledDelivery)); httpClient.post(getCommandResponsePath(CMD_REQ_ID)) .addQueryParam(Constants.HEADER_COMMAND_RESPONSE_STATUS, "200") .putHeader(HttpHeaders.CONTENT_TYPE.toString(), HttpUtils.CONTENT_TYPE_JSON) .basicAuthentication("testuser@DEFAULT_TENANT", "password123") .putHeader(HttpHeaders.ORIGIN.toString(), "hono.eclipse.org") .expect(ResponsePredicate.SC_ACCEPTED) .sendJsonObject(new JsonObject(), ctx.completing()); }
Example #5
Source File: ApplicationClientFactoryImpl.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * {@inheritDoc} */ @Override public Future<MessageConsumer> createAsyncCommandResponseConsumer( final String tenantId, final String replyId, final BiConsumer<ProtonDelivery, Message> consumer, final Handler<Void> closeHandler) { return connection.executeOnContext(result -> { consumerFactory.createClient( () -> AsyncCommandResponseConsumerImpl.create( connection, tenantId, replyId, consumer, closeHook -> closeHandler.handle(null)), result); }); }
Example #6
Source File: AbstractAmqpAdapterClientDownstreamSenderTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Sets up fixture. */ @BeforeEach public void setUp() { sender = HonoClientUnitTestHelper.mockProtonSender(); protonDelivery = mock(ProtonDelivery.class); when(protonDelivery.remotelySettled()).thenReturn(true); final Accepted deliveryState = new Accepted(); when(protonDelivery.getRemoteState()).thenReturn(deliveryState); when(sender.send(any(Message.class), VertxMockSupport.anyHandler())).thenReturn(protonDelivery); final Span span = mock(Span.class); when(span.context()).thenReturn(mock(SpanContext.class)); spanBuilder = HonoClientUnitTestHelper.mockSpanBuilder(span); final Tracer tracer = mock(Tracer.class); when(tracer.buildSpan(anyString())).thenReturn(spanBuilder); connection = HonoClientUnitTestHelper.mockHonoConnection(mock(Vertx.class)); when(connection.getTracer()).thenReturn(tracer); when(connection.createSender(any(), any(), any())).thenReturn(Future.succeededFuture(sender)); }
Example #7
Source File: GenericMessageSenderImpl.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Sends an AMQP 1.0 message to the peer this client is configured for * and waits for the outcome of the transfer. * * @param message The message to send. * @return A future indicating the outcome of transferring the message. * <p> * The future will succeed with the updated delivery from the peer if * the message has been settled with the <em>accepted</em> outcome. * <p> * The future will be failed with a {@link ServerErrorException} if the * message could not be sent, e.g. due to a lack of credit. It will be * failed with a {@link ClientErrorException} if the message has not * been accepted by the peer. * @throws NullPointerException if the message is {@code null}. */ @Override public Future<ProtonDelivery> sendAndWaitForOutcome(final Message message) { return connection.executeOnContext(result -> { if (sender.isOpen() && sender.getCredit() > 0) { sender.send(message, updatedDelivery -> { if (updatedDelivery.getRemoteState() instanceof Accepted) { result.complete(updatedDelivery); } else if (updatedDelivery.getRemoteState() instanceof Released) { result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE)); } else { result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } }); } else { result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE)); } }); }
Example #8
Source File: AbstractRequestResponseClientTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the adapter does not put the response from the service to the cache * if the response contains a <em>no-cache</em> cache directive. * * @param ctx The vert.x test context. */ @Test public void testCreateAndSendRequestDoesNotAddResponseToCache(final VertxTestContext ctx) { // GIVEN an adapter with an empty cache client.setResponseCache(cache); // WHEN sending a request client.createAndSendRequest("get", (Buffer) null, ctx.succeeding(result -> { assertEquals(200, result.getStatus()); // THEN the response is not put to the cache verify(cache, never()).put(eq("cacheKey"), any(SimpleRequestResponseResult.class), any(Duration.class)); ctx.completeNow(); }), "cacheKey"); final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(sender).send(messageCaptor.capture(), VertxMockSupport.anyHandler()); final Message response = ProtonHelper.message("result"); MessageHelper.addProperty(response, MessageHelper.APP_PROPERTY_STATUS, HttpURLConnection.HTTP_OK); MessageHelper.addCacheDirective(response, CacheDirective.noCacheDirective()); response.setCorrelationId(messageCaptor.getValue().getMessageId()); final ProtonDelivery delivery = mock(ProtonDelivery.class); client.handleResponse(delivery, response); }
Example #9
Source File: AbstractProtocolAdapterBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Forwards a response message that has been sent by a device in reply to a * command to the sender of the command. * <p> * This method opens a new link for sending the response, tries to send the * response message and then closes the link again. * * @param tenantId The tenant that the device belongs to. * @param response The response message. * @param context The currently active OpenTracing span. An implementation * should use this as the parent for any span it creates for tracing * the execution of this operation. * @return A future indicating the outcome of the attempt to send * the message. The link will be closed in any case. * @throws NullPointerException if any of the parameters other than context are {@code null}. */ protected final Future<ProtonDelivery> sendCommandResponse( final String tenantId, final CommandResponse response, final SpanContext context) { Objects.requireNonNull(tenantId); Objects.requireNonNull(response); final Future<CommandResponseSender> senderTracker = createCommandResponseSender(tenantId, response.getReplyToId()); return senderTracker .compose(sender -> sender.sendCommandResponse(response, context)) .map(delivery -> { senderTracker.result().close(c -> {}); return delivery; }).recover(t -> { if (senderTracker.succeeded()) { senderTracker.result().close(c -> {}); } return Future.failedFuture(t); }); }
Example #10
Source File: MappingAndDelegatingCommandHandlerTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies the behaviour of the <em>mapAndDelegateIncomingCommandMessage</em> method in a scenario where * the given command message shall get mapped to a local command handler. */ @Test public void testMapWithLocalCommandHandler() { final String deviceId = "4711"; // GIVEN a registered commandHandler for the deviceId final AtomicReference<CommandContext> localHandlerCmdContextRef = new AtomicReference<>(); adapterInstanceCommandHandler.putDeviceSpecificCommandHandler(Constants.DEFAULT_TENANT, deviceId, null, localHandlerCmdContextRef::set); // AND the deviceId commandHandler registered for the local adapter instance when(commandTargetMapper.getTargetGatewayAndAdapterInstance(anyString(), anyString(), any())) .thenReturn(Future.succeededFuture(createTargetAdapterInstanceJson(deviceId, adapterInstanceId))); // WHEN mapping and delegating the command message final Message message = getValidCommandMessage(deviceId); final ProtonDelivery delivery = mock(ProtonDelivery.class); mappingAndDelegatingCommandHandler.mapAndDelegateIncomingCommandMessage(Constants.DEFAULT_TENANT, delivery, message); // THEN the local command handler is invoked with the unchanged command message assertThat(localHandlerCmdContextRef.get()).isNotNull(); assertThat(localHandlerCmdContextRef.get().getCommand()).isNotNull(); assertThat(localHandlerCmdContextRef.get().getCommand().getCommandMessage()).isEqualTo(message); assertThat(localHandlerCmdContextRef.get().getCommand().isValid()).isTrue(); // AND the command message delivery is unchanged (that would be done by the commandHandler) verify(delivery, never()).disposition(any(), anyBoolean()); }
Example #11
Source File: AdapterInstanceCommandHandlerTest.java From hono with Eclipse Public License 2.0 | 6 votes |
@Test void testHandleCommandMessageWithHandlerForGatewayAndSpecificDevice() { final String deviceId = "4711"; final String gatewayId = "gw-1"; 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, deviceId)); message.setSubject("doThis"); message.setCorrelationId(correlationId); final Handler<CommandContext> commandHandler = VertxMockSupport.mockHandler(); adapterInstanceCommandHandler.putDeviceSpecificCommandHandler(Constants.DEFAULT_TENANT, deviceId, gatewayId, commandHandler); adapterInstanceCommandHandler.handleCommandMessage(message, mock(ProtonDelivery.class)); final ArgumentCaptor<CommandContext> commandContextCaptor = ArgumentCaptor.forClass(CommandContext.class); verify(commandHandler).handle(commandContextCaptor.capture()); assertThat(commandContextCaptor.getValue()).isNotNull(); // assert that command is directed at the gateway assertThat(commandContextCaptor.getValue().getCommand().getDeviceId()).isEqualTo(gatewayId); assertThat(commandContextCaptor.getValue().getCommand().getOriginalDeviceId()).isEqualTo(deviceId); }
Example #12
Source File: TelemetrySenderImpl.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * {@inheritDoc} */ @Override public Future<ProtonDelivery> sendAndWaitForOutcome(final Message rawMessage, final SpanContext parent) { Objects.requireNonNull(rawMessage); // we create a child span (instead of a following span) because we depend // on the outcome of the sending operation final Span span = startChildSpan(parent, rawMessage); Tags.MESSAGE_BUS_DESTINATION.set(span, targetAddress); TracingHelper.setDeviceTags(span, tenantId, MessageHelper.getDeviceId(rawMessage)); TracingHelper.injectSpanContext(connection.getTracer(), span.context(), rawMessage); return connection.executeOnContext(result -> { if (sender.sendQueueFull()) { final ServiceInvocationException e = new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "no credit available"); logMessageSendingError("error sending message [ID: {}, address: {}], no credit available", rawMessage.getMessageId(), getMessageAddress(rawMessage)); logError(span, e); span.finish(); result.fail(e); } else { sendMessageAndWaitForOutcome(rawMessage, span).onComplete(result); } }); }
Example #13
Source File: TelemetrySenderImplTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that a timeout occurring while a message is sent doesn't cause the corresponding * OpenTracing span to stay unfinished. */ @Test public void testSendMessageFailsOnTimeout() { // GIVEN a sender that won't receive a delivery update on sending a message // and directly triggers the timeout handler when(sender.send(any(Message.class), VertxMockSupport.anyHandler())).thenReturn(mock(ProtonDelivery.class)); when(vertx.setTimer(anyLong(), VertxMockSupport.anyHandler())).thenAnswer(invocation -> { final Handler<Long> handler = invocation.getArgument(1); final long timerId = 1; handler.handle(timerId); return timerId; }); final DownstreamSender messageSender = new TelemetrySenderImpl(connection, sender, "tenant", "telemetry/tenant"); // WHEN sending a message final Message message = mock(Message.class); final Span span = mock(Span.class); ((TelemetrySenderImpl) messageSender).sendMessage(message, span); // THEN the given Span will nonetheless be finished. verify(span).finish(); }
Example #14
Source File: CommandResponderTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that {@link TraceableCommandResponder} uses the given SpanContext. * * @param ctx The test context to use for running asynchronous tests. */ @Test public void testSendCommandResponseWithTracing(final VertxTestContext ctx) { // GIVEN a TraceableCommandResponder instance final TraceableCommandResponder commandResponder = ((TraceableCommandResponder) createCommandResponder()); // WHEN sending a message using the API... final SpanContext spanContext = mock(SpanContext.class); final Future<ProtonDelivery> deliveryFuture = commandResponder.sendCommandResponse(DEVICE_ID, ADDRESS, CORRELATION_ID, STATUS, PAYLOAD, CONTENT_TYPE, APPLICATION_PROPERTIES, spanContext); // ...AND WHEN the disposition is updated by the peer updateDisposition(); deliveryFuture.onComplete(ctx.succeeding(delivery -> { // THEN the given SpanContext is used ctx.verify(() -> { verify(spanBuilder).addReference(any(), eq(spanContext)); assertMessageConformsAmqpAdapterSpec(); }); ctx.completeNow(); })); }
Example #15
Source File: CommandResponderTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the message created by the client conforms to the expectations of the AMQP adapter. * * @param ctx The test context to use for running asynchronous tests. */ @Test public void testSendCommandResponseCreatesValidMessage(final VertxTestContext ctx) { // GIVEN a CommandResponder instance final CommandResponder commandResponder = createCommandResponder(); // WHEN sending a message using the API... final Future<ProtonDelivery> deliveryFuture = commandResponder.sendCommandResponse(DEVICE_ID, ADDRESS, CORRELATION_ID, STATUS, PAYLOAD, CONTENT_TYPE, APPLICATION_PROPERTIES); // ...AND WHEN the disposition is updated by the peer updateDisposition(); deliveryFuture.onComplete(ctx.succeeding(delivery -> { // THEN the AMQP message conforms to the expectations of the AMQP protocol adapter ctx.verify(this::assertMessageConformsAmqpAdapterSpec); ctx.completeNow(); })); }
Example #16
Source File: TelemetrySenderTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that sending the message waits for the disposition update from the peer. * * @param ctx The test context to use for running asynchronous tests. */ @Test public void testSendAndWaitForOutcomeWaitsForDispositionUpdate(final VertxTestContext ctx) { // GIVEN a TelemetrySender instance final TelemetrySender telemetrySender = createTelemetrySender(); // WHEN sending a message using the API final Future<ProtonDelivery> deliveryFuture = telemetrySender.sendAndWaitForOutcome(DEVICE_ID, PAYLOAD, CONTENT_TYPE, APPLICATION_PROPERTIES); deliveryFuture.onComplete(ctx.completing()); // THEN the future waits for the disposition to be updated by the peer assertThat(deliveryFuture.isComplete()).isFalse(); updateDisposition(); }
Example #17
Source File: TelemetrySenderTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that {@link TraceableTelemetrySender#sendAndWaitForOutcome(String, byte[], String, Map, SpanContext)} * uses the given SpanContext. * * @param ctx The test context to use for running asynchronous tests. */ @Test public void testSendAndWaitForOutcomeWithTracing(final VertxTestContext ctx) { // GIVEN a TraceableTelemetrySender instance final TraceableTelemetrySender telemetrySender = ((TraceableTelemetrySender) createTelemetrySender()); // WHEN sending a message using the API... final SpanContext spanContext = mock(SpanContext.class); final Future<ProtonDelivery> deliveryFuture = telemetrySender.sendAndWaitForOutcome(DEVICE_ID, PAYLOAD, CONTENT_TYPE, APPLICATION_PROPERTIES, spanContext); // ...AND WHEN the disposition is updated by the peer updateDisposition(); deliveryFuture.onComplete(ctx.succeeding(delivery -> { // THEN the given SpanContext is used ctx.verify(() -> { verify(spanBuilder).addReference(any(), eq(spanContext)); assertMessageConformsAmqpAdapterSpec(ADDRESS); }); ctx.completeNow(); })); }
Example #18
Source File: TelemetrySenderTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the message created by {@link TelemetrySender#sendAndWaitForOutcome(String, byte[], String, Map)} * conforms to the expectations of the AMQP adapter. * * @param ctx The test context to use for running asynchronous tests. */ @Test public void testSendAndWaitForOutcomeCreatesValidMessage(final VertxTestContext ctx) { // GIVEN a TelemetrySender instance final TelemetrySender telemetrySender = createTelemetrySender(); // WHEN sending a message using the API... final Future<ProtonDelivery> deliveryFuture = telemetrySender.sendAndWaitForOutcome(DEVICE_ID, PAYLOAD, CONTENT_TYPE, APPLICATION_PROPERTIES); // ...AND WHEN the disposition is updated by the peer updateDisposition(); deliveryFuture.onComplete(ctx.succeeding(delivery -> { // THEN the AMQP message conforms to the expectations of the AMQP protocol adapter ctx.verify(() -> assertMessageConformsAmqpAdapterSpec(ADDRESS)); ctx.completeNow(); })); }
Example #19
Source File: EventSenderTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the message created by the client conforms to the expectations of the AMQP adapter. * * @param ctx The test context to use for running asynchronous tests. */ @Test public void testSendCreatesValidMessage(final VertxTestContext ctx) { // GIVEN a EventSender instance final EventSender eventSender = createEventSender(); // WHEN sending a message using the API... final Future<ProtonDelivery> deliveryFuture = eventSender.send(DEVICE_ID, PAYLOAD, CONTENT_TYPE, APPLICATION_PROPERTIES); // ...AND WHEN the disposition is updated by the peer updateDisposition(); deliveryFuture.onComplete(ctx.succeeding(delivery -> { // THEN the AMQP message conforms to the expectations of the AMQP protocol adapter ctx.verify(() -> assertMessageConformsAmqpAdapterSpec(ADDRESS)); ctx.completeNow(); })); }
Example #20
Source File: TelemetryAndEventCli.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Connects to the AMQP org.eclipse.hono.cli.app.adapter and send a telemetry/event message to the org.eclipse.hono.cli.app.adapter. * * @param messageTracker The future to notify when the message is sent. The future is completed with the delivery * upon success or completed with an exception. */ private void sendMessage(final CompletableFuture<ProtonDelivery> messageTracker) { ctx.runOnContext(go -> { connectToAdapter() .compose(con -> { adapterConnection = con; return createSender(); }) .map(sender -> { final Message message = ProtonHelper.message(messageAddress, payload); sender.send(message, delivery -> { adapterConnection.close(); messageTracker.complete(delivery); }); return sender; }) .otherwise(t -> { messageTracker.completeExceptionally(t); return null; }); }); }
Example #21
Source File: RequestResponseEndpointTest.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the endpoint rejects malformed request messages. */ @Test public void testHandleMessageRejectsMalformedMessage() { final Message msg = ProtonHelper.message(); final ProtonConnection con = mock(ProtonConnection.class); final ProtonDelivery delivery = mock(ProtonDelivery.class); final RequestResponseEndpoint<ServiceConfigProperties> endpoint = getEndpoint(false); // WHEN a malformed message is received endpoint.handleRequestMessage(con, receiver, resource, delivery, msg); // THEN the link is closed and the message is rejected final ArgumentCaptor<DeliveryState> deliveryState = ArgumentCaptor.forClass(DeliveryState.class); verify(delivery).disposition(deliveryState.capture(), eq(Boolean.TRUE)); assertThat(deliveryState.getValue()).isInstanceOf(Rejected.class); verify(receiver, never()).close(); verify(receiver).flow(1); }
Example #22
Source File: AdapterInstanceCommandHandlerTest.java From hono with Eclipse Public License 2.0 | 6 votes |
@Test void testHandleCommandMessageWithHandlerForDevice() { final String deviceId = "4711"; 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, deviceId)); message.setSubject("doThis"); message.setCorrelationId(correlationId); final Handler<CommandContext> commandHandler = VertxMockSupport.mockHandler(); adapterInstanceCommandHandler.putDeviceSpecificCommandHandler(Constants.DEFAULT_TENANT, deviceId, null, commandHandler); adapterInstanceCommandHandler.handleCommandMessage(message, mock(ProtonDelivery.class)); final ArgumentCaptor<CommandContext> commandContextCaptor = ArgumentCaptor.forClass(CommandContext.class); verify(commandHandler).handle(commandContextCaptor.capture()); assertThat(commandContextCaptor.getValue()).isNotNull(); assertThat(commandContextCaptor.getValue().getCommand().getDeviceId()).isEqualTo(deviceId); }
Example #23
Source File: GenericMessageSenderImpl.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * {@inheritDoc} */ @Override public Future<ProtonDelivery> send(final Message message) { return connection.executeOnContext(result -> { if (sender.isOpen() && sender.getCredit() > 0) { result.complete(sender.send(message)); } else { result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE)); } }); }
Example #24
Source File: VertxBasedAmqpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verify that the AMQP adapter forwards command responses downstream. * * @param ctx The vert.x test context. */ @Test public void testUploadCommandResponseSucceeds(final VertxTestContext ctx) { // GIVEN an AMQP adapter final VertxBasedAmqpProtocolAdapter adapter = givenAnAmqpAdapter(); final CommandResponseSender responseSender = givenACommandResponseSenderForAnyTenant(); final ProtonDelivery delivery = mock(ProtonDelivery.class); when(responseSender.sendCommandResponse(any(CommandResponse.class), (SpanContext) any())).thenReturn(Future.succeededFuture(delivery)); // which is enabled for the test tenant final TenantObject tenantObject = givenAConfiguredTenant(TEST_TENANT_ID, true); // WHEN an unauthenticated device publishes a command response final String replyToAddress = String.format("%s/%s/%s", getCommandResponseEndpoint(), TEST_TENANT_ID, Command.getDeviceFacingReplyToId("test-reply-id", TEST_DEVICE)); final Map<String, Object> propertyMap = new HashMap<>(); propertyMap.put(MessageHelper.APP_PROPERTY_STATUS, 200); final ApplicationProperties props = new ApplicationProperties(propertyMap); final Buffer payload = Buffer.buffer("some payload"); final Message message = getFakeMessage(replyToAddress, payload); when(message.getCorrelationId()).thenReturn("correlation-id"); when(message.getApplicationProperties()).thenReturn(props); adapter.onMessageReceived(AmqpContext.fromMessage(delivery, message, null)).onComplete(ctx.succeeding(ok -> { ctx.verify(() -> { // THEN the adapter forwards the command response message downstream verify(responseSender).sendCommandResponse((CommandResponse) any(), (SpanContext) any()); // and reports the forwarded message verify(metrics).reportCommand( eq(Direction.RESPONSE), eq(TEST_TENANT_ID), eq(tenantObject), eq(ProcessingOutcome.FORWARDED), eq(payload.length()), any()); }); ctx.completeNow(); })); }
Example #25
Source File: AbstractVertxBasedHttpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
private DownstreamSender givenAnEventSenderForOutcome(final Future<ProtonDelivery> outcome) { final DownstreamSender sender = mock(DownstreamSender.class); when(sender.sendAndWaitForOutcome(any(Message.class), (SpanContext) any())).thenReturn(outcome); when(downstreamSenderFactory.getOrCreateEventSender(anyString())).thenReturn(Future.succeededFuture(sender)); return sender; }
Example #26
Source File: DelegatedCommandSenderImpl.java From hono with Eclipse Public License 2.0 | 5 votes |
@Override public Future<ProtonDelivery> sendAndWaitForOutcome(final Message rawMessage, final SpanContext parent) { Objects.requireNonNull(rawMessage); final Span span = startSpan(parent, rawMessage); TracingHelper.injectSpanContext(connection.getTracer(), span.context(), rawMessage); return runSendAndWaitForOutcomeOnContext(rawMessage, span); }
Example #27
Source File: VertxBasedAmqpProtocolAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that a request to upload an "unsettled" telemetry message from a device that belongs to a tenant for which the AMQP * adapter is disabled fails and that the device is notified when the message cannot be processed. * * @param ctx The vert.x test context. */ @Test public void testUploadTelemetryMessageFailsForDisabledAdapter(final VertxTestContext ctx) { // GIVEN an adapter configured to use a user-define server. final VertxBasedAmqpProtocolAdapter adapter = givenAnAmqpAdapter(); final DownstreamSender telemetrySender = givenATelemetrySenderForAnyTenant(); // AND given a tenant for which the AMQP Adapter is disabled final TenantObject tenantObject = givenAConfiguredTenant(TEST_TENANT_ID, false); // WHEN a device uploads telemetry data to the adapter (and wants to be notified of failure) final ProtonDelivery delivery = mock(ProtonDelivery.class); when(delivery.remotelySettled()).thenReturn(false); // AT LEAST ONCE final String to = ResourceIdentifier.from(TelemetryConstants.TELEMETRY_ENDPOINT, TEST_TENANT_ID, TEST_DEVICE).toString(); final Buffer payload = Buffer.buffer("some payload"); adapter.onMessageReceived(AmqpContext.fromMessage(delivery, getFakeMessage(to, payload), null)) .onComplete(ctx.failing(t -> { ctx.verify(() -> { // THEN the adapter does not send the message (regardless of the delivery mode). verify(telemetrySender, never()).send(any(Message.class), (SpanContext) any()); verify(telemetrySender, never()).sendAndWaitForOutcome(any(Message.class), (SpanContext) any()); // AND notifies the device by sending back a REJECTED disposition verify(delivery).disposition(any(Rejected.class), eq(true)); // AND has reported the message as unprocessable verify(metrics).reportTelemetry( eq(EndpointType.TELEMETRY), eq(TEST_TENANT_ID), eq(tenantObject), eq(ProcessingOutcome.UNPROCESSABLE), eq(QoS.AT_LEAST_ONCE), eq(payload.length()), any()); }); ctx.completeNow(); })); }
Example #28
Source File: AmqpSourceBridgeEndpoint.java From strimzi-kafka-bridge with Apache License 2.0 | 5 votes |
/** * Process the message received on the related receiver link * * @param receiver Proton receiver instance * @param delivery Proton delivery instance * @param message AMQP message received */ private void processMessage(ProtonReceiver receiver, ProtonDelivery delivery, Message message) { // replace unsupported "/" (in a topic name in Kafka) with "." String kafkaTopic = (receiver.getTarget().getAddress() != null) ? receiver.getTarget().getAddress().replace('/', '.') : null; KafkaProducerRecord<K, V> krecord = this.converter.toKafkaRecord(kafkaTopic, null, message); if (delivery.remotelySettled()) { // message settled (by sender), no feedback need by Apache Kafka, no disposition to be sent this.send(krecord, null); } else { // message unsettled (by sender), feedback needed by Apache Kafka, disposition to be sent accordingly this.send(krecord, writeResult -> { if (writeResult.failed()) { Throwable exception = writeResult.cause(); // record not delivered, send REJECTED disposition to the AMQP sender log.error("Error on delivery to Kafka {}", exception.getMessage()); this.rejectedDelivery(receiver.getName(), delivery, exception); } else { RecordMetadata metadata = writeResult.result(); // record delivered, send ACCEPTED disposition to the AMQP sender log.debug("Delivered to Kafka on topic {} at partition {} [{}]", metadata.getTopic(), metadata.getPartition(), metadata.getOffset()); this.acceptedDelivery(receiver.getName(), delivery); } }); } }
Example #29
Source File: CommandResponseSenderImpl.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * {@inheritDoc} */ @Override public Future<ProtonDelivery> sendCommandResponse(final CommandResponse commandResponse, final SpanContext context) { Objects.requireNonNull(commandResponse); final Message message = commandResponse.toMessage(); Objects.requireNonNull(message); message.setAddress(targetAddress); return sendAndWaitForOutcome(message, context); }
Example #30
Source File: AdapterInstanceCommandHandlerTest.java From hono with Eclipse Public License 2.0 | 5 votes |
@Test void testHandleCommandMessageWithNoHandlerFound() { final Message msg = mock(Message.class); final String deviceId = "4711"; when(msg.getAddress()).thenReturn(String.format("%s/%s/%s", CommandConstants.COMMAND_ENDPOINT, Constants.DEFAULT_TENANT, deviceId)); final ProtonDelivery delivery = mock(ProtonDelivery.class); adapterInstanceCommandHandler.handleCommandMessage(msg, delivery); final ArgumentCaptor<DeliveryState> deliveryStateCaptor = ArgumentCaptor.forClass(DeliveryState.class); verify(delivery).disposition(deliveryStateCaptor.capture(), anyBoolean()); assertThat(deliveryStateCaptor.getValue()).isNotNull(); assertThat(deliveryStateCaptor.getValue()).isInstanceOf(Released.class); }