use of io.vertx.proton.ProtonDelivery in project hono by eclipse.
the class EventSenderImpl method sendMessage.
@Override
protected Future<ProtonDelivery> sendMessage(final Message message) {
Objects.requireNonNull(message);
final Future<ProtonDelivery> result = Future.future();
final String messageId = String.format("%s-%d", getClass().getSimpleName(), MESSAGE_COUNTER.getAndIncrement());
message.setMessageId(messageId);
sender.send(message, deliveryUpdated -> {
if (deliveryUpdated.remotelySettled()) {
if (Accepted.class.isInstance(deliveryUpdated.getRemoteState())) {
LOG.trace("event [message ID: {}] accepted by peer", messageId);
result.complete(deliveryUpdated);
} else if (Rejected.class.isInstance(deliveryUpdated.getRemoteState())) {
Rejected rejected = (Rejected) deliveryUpdated.getRemoteState();
if (rejected.getError() == null) {
LOG.debug("event [message ID: {}] rejected by peer", messageId);
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
} else {
LOG.debug("event [message ID: {}] rejected by peer: {}, {}", messageId, rejected.getError().getCondition(), rejected.getError().getDescription());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, rejected.getError().getDescription()));
}
} else {
LOG.debug("event [message ID: {}] not accepted by peer: {}", messageId, deliveryUpdated.getRemoteState());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
}
} else {
LOG.warn("peer did not settle event, failing delivery [new remote state: {}]", deliveryUpdated.getRemoteState());
result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
}
});
LOG.trace("sent event [ID: {}], remaining credit: {}, queued messages: {}", messageId, sender.getCredit(), sender.getQueued());
return result;
}
use of io.vertx.proton.ProtonDelivery in project hono by eclipse.
the class TelemetrySenderImpl method sendMessage.
@Override
protected Future<ProtonDelivery> sendMessage(final Message message) {
Objects.requireNonNull(message);
final String messageId = String.format("%s-%d", getClass().getSimpleName(), MESSAGE_COUNTER.getAndIncrement());
message.setMessageId(messageId);
final ProtonDelivery result = sender.send(message, deliveryUpdated -> {
if (deliveryUpdated.remotelySettled()) {
if (Accepted.class.isInstance(deliveryUpdated.getRemoteState())) {
LOG.trace("message [message ID: {}] accepted by peer", messageId);
} else if (Rejected.class.isInstance(deliveryUpdated.getRemoteState())) {
Rejected remoteState = (Rejected) deliveryUpdated.getRemoteState();
if (remoteState.getError() == null) {
LOG.debug("message [message ID: {}] rejected by peer", messageId);
} else {
LOG.debug("message [message ID: {}] rejected by peer: {}, {}", messageId, remoteState.getError().getCondition(), remoteState.getError().getDescription());
}
} else {
LOG.debug("message [message ID: {}] not accepted by peer: {}", messageId, deliveryUpdated.getRemoteState());
}
} else {
LOG.warn("peer did not settle telemetry message [message ID: {}, remote state: {}]", messageId, deliveryUpdated.getRemoteState());
}
});
LOG.trace("sent telemetry message [ID: {}], remaining credit: {}, queued messages: {}", messageId, sender.getCredit(), sender.getQueued());
return Future.succeededFuture(result);
}
use of io.vertx.proton.ProtonDelivery in project hono by eclipse.
the class EventConsumerImplTest method testCreateRegistersBiConsumerAsMessageHandler.
/**
* Verifies that the message delivery for a received event is forwarded to the
* registered event consumer.
*
* @param ctx The test context.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testCreateRegistersBiConsumerAsMessageHandler(final TestContext ctx) {
// GIVEN an event consumer that releases all messages
final Async consumerCreation = ctx.async();
final BiConsumer<ProtonDelivery, Message> eventConsumer = (delivery, message) -> {
ProtonHelper.released(delivery, true);
};
final RecordImpl attachments = new RecordImpl();
final Source source = mock(Source.class);
when(source.toString()).thenReturn("event/tenant");
final ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.getSource()).thenReturn(source);
when(receiver.attachments()).thenReturn(attachments);
when(receiver.getRemoteQoS()).thenReturn(ProtonQoS.AT_LEAST_ONCE);
when(receiver.open()).then(answer -> {
consumerCreation.complete();
return receiver;
});
final ProtonConnection con = mock(ProtonConnection.class);
when(con.createReceiver(anyString())).thenReturn(receiver);
when(receiver.openHandler(any(Handler.class))).thenAnswer(invocation -> {
final Handler handler = invocation.getArgument(0);
handler.handle(Future.succeededFuture(receiver));
return receiver;
});
final ArgumentCaptor<ProtonMessageHandler> messageHandler = ArgumentCaptor.forClass(ProtonMessageHandler.class);
EventConsumerImpl.create(vertx.getOrCreateContext(), new ClientConfigProperties(), con, "tenant", eventConsumer, open -> {
}, remoteDetach -> {
});
consumerCreation.await();
verify(receiver).handler(messageHandler.capture());
// WHEN an event is received
final ProtonDelivery delivery = mock(ProtonDelivery.class);
final Message msg = mock(Message.class);
messageHandler.getValue().handle(delivery, msg);
// THEN the message is released and settled
verify(delivery).disposition(any(Released.class), eq(Boolean.TRUE));
}
use of io.vertx.proton.ProtonDelivery in project hono by eclipse.
the class EventSenderImplTest method testSendMessageFailsOnLackOfCredit.
/**
* Verifies that the sender fails if no credit is available.
*
* @param ctx The vert.x test context.
*/
@SuppressWarnings("unchecked")
@Test
public void testSendMessageFailsOnLackOfCredit(final TestContext ctx) {
// GIVEN a sender that has no credit
when(sender.sendQueueFull()).thenReturn(Boolean.TRUE);
MessageSender messageSender = new EventSenderImpl(config, sender, "tenant", "telemetry/tenant", context);
// WHEN trying to send a message
final Future<ProtonDelivery> result = messageSender.send("device", "some payload", "application/text", "token");
// THEN the message is not sent
assertFalse(result.succeeded());
verify(sender, never()).send(any(Message.class), any(Handler.class));
}
use of io.vertx.proton.ProtonDelivery in project hono by eclipse.
the class RegistrationClientImplTest method testAssertRegistrationAddsResponseToCacheOnCacheMiss.
/**
* Verifies that on a cache miss the adapter retrieves registration information
* from the Device Registration service and puts it to the cache.
*
* @param ctx The vert.x test context.
*/
@SuppressWarnings("unchecked")
@Test
public void testAssertRegistrationAddsResponseToCacheOnCacheMiss(final TestContext ctx) {
// GIVEN an adapter with an empty cache
client.setResponseCache(cache);
// WHEN getting registration information
final Async assertion = ctx.async();
client.assertRegistration("device").setHandler(ctx.asyncAssertSuccess(result -> assertion.complete()));
final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(sender).send(messageCaptor.capture(), any(Handler.class));
final JsonObject registrationAssertion = newRegistrationAssertionResult();
final Message response = ProtonHelper.message(registrationAssertion.encode());
MessageHelper.addProperty(response, MessageHelper.APP_PROPERTY_STATUS, HttpURLConnection.HTTP_OK);
MessageHelper.addCacheDirective(response, CacheDirective.maxAgeDirective(60));
response.setCorrelationId(messageCaptor.getValue().getMessageId());
final ProtonDelivery delivery = mock(ProtonDelivery.class);
client.handleResponse(delivery, response);
// THEN the registration information has been added to the cache
verify(cache).put(eq(TriTuple.of("assert", "device", null)), any(RegistrationResult.class), any(Duration.class));
}
Aggregations