use of io.vertx.proton.ProtonReceiver 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.ProtonReceiver in project hono by eclipse.
the class TenantClientImplTest method setUp.
/**
* Sets up the fixture.
*/
@SuppressWarnings("unchecked")
@Before
public void setUp() {
vertx = mock(Vertx.class);
context = HonoClientUnitTestHelper.mockContext(vertx);
final ProtonReceiver receiver = HonoClientUnitTestHelper.mockProtonReceiver();
sender = HonoClientUnitTestHelper.mockProtonSender();
cache = mock(ExpiringValueCache.class);
final RequestResponseClientConfigProperties config = new RequestResponseClientConfigProperties();
client = new TenantClientImpl(context, config, sender, receiver);
}
use of io.vertx.proton.ProtonReceiver in project vertx-proton by vert-x3.
the class ProtonReceiverImplTest method testFlowWithExistingDrainOutstandingThrowsISE.
@Test
public void testFlowWithExistingDrainOutstandingThrowsISE() {
ProtonConnectionImpl conn = new ProtonConnectionImpl(null, null);
ProtonReceiver receiver = conn.createReceiver("address");
AtomicBoolean drain1complete = new AtomicBoolean();
receiver.setPrefetch(0);
receiver.flow(1);
receiver.drain(0, h -> {
drain1complete.set(true);
});
try {
receiver.flow(1);
fail("should have thrown due to outstanding drain operation");
} catch (IllegalStateException ise) {
// Expected
assertFalse("drain should not have been completed", drain1complete.get());
}
}
use of io.vertx.proton.ProtonReceiver in project vertx-proton by vert-x3.
the class ProtonReceiverImplTest method testDrainWithExistingDrainOutstandingThrowsISE.
@Test
public void testDrainWithExistingDrainOutstandingThrowsISE() {
ProtonConnectionImpl conn = new ProtonConnectionImpl(null, null);
ProtonReceiver receiver = conn.createReceiver("address");
AtomicBoolean drain1complete = new AtomicBoolean();
receiver.setPrefetch(0);
receiver.flow(1);
receiver.drain(0, h -> {
drain1complete.set(true);
});
try {
receiver.drain(0, h2 -> {
});
fail("should have thrown due to outstanding drain operation");
} catch (IllegalStateException ise) {
// Expected
assertFalse("first drain should not have been completed", drain1complete.get());
}
}
use of io.vertx.proton.ProtonReceiver in project hono by eclipse.
the class AbstractHonoClient method createReceiver.
/**
* Creates a receiver link.
* <p>
* The receiver will be created with its <em>autoAccept</em> property set to {@code true}.
*
* @param ctx The vert.x context to use for establishing the link.
* @param clientConfig The configuration properties to use.
* @param con The connection to create the link for.
* @param sourceAddress The address to receive messages from.
* @param qos The quality of service to use for the link.
* @param messageHandler The handler to invoke with every message received.
* @param closeHook The handler to invoke when the link is closed by the peer (may be {@code null}).
* @return A future for the created link. The future will be completed once the link is open.
* The future will fail with a {@link ServiceInvocationException} if the link cannot be opened.
* @throws NullPointerException if any of the arguments other than close hook is {@code null}.
*/
protected static final Future<ProtonReceiver> createReceiver(final Context ctx, final ClientConfigProperties clientConfig, final ProtonConnection con, final String sourceAddress, final ProtonQoS qos, final ProtonMessageHandler messageHandler, final Handler<String> closeHook) {
Objects.requireNonNull(ctx);
Objects.requireNonNull(clientConfig);
Objects.requireNonNull(con);
Objects.requireNonNull(sourceAddress);
Objects.requireNonNull(qos);
Objects.requireNonNull(messageHandler);
final Future<ProtonReceiver> result = Future.future();
ctx.runOnContext(go -> {
final ProtonReceiver receiver = con.createReceiver(sourceAddress);
receiver.attachments().set(KEY_LINK_ESTABLISHED, Boolean.class, Boolean.FALSE);
receiver.setAutoAccept(true);
receiver.setQoS(qos);
receiver.setPrefetch(clientConfig.getInitialCredits());
receiver.handler((delivery, message) -> {
messageHandler.handle(delivery, message);
if (LOG.isTraceEnabled()) {
int remainingCredits = receiver.getCredit() - receiver.getQueued();
LOG.trace("handling message [remotely settled: {}, queued messages: {}, remaining credit: {}]", delivery.remotelySettled(), receiver.getQueued(), remainingCredits);
}
});
receiver.openHandler(recvOpen -> {
if (recvOpen.succeeded()) {
LOG.debug("receiver open [source: {}]", sourceAddress);
receiver.attachments().set(KEY_LINK_ESTABLISHED, Boolean.class, Boolean.TRUE);
result.complete(recvOpen.result());
} else {
final ErrorCondition error = receiver.getRemoteCondition();
if (error == null) {
LOG.debug("opening receiver [{}] failed", sourceAddress, recvOpen.cause());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot open receiver", recvOpen.cause()));
} else {
LOG.debug("opening receiver [{}] failed: {} - {}", sourceAddress, error.getCondition(), error.getDescription());
result.fail(StatusCodeMapper.from(error));
}
}
});
receiver.detachHandler(remoteDetached -> onRemoteDetach(receiver, con.getRemoteContainer(), false, closeHook));
receiver.closeHandler(remoteClosed -> onRemoteDetach(receiver, con.getRemoteContainer(), true, closeHook));
receiver.open();
});
return result;
}
Aggregations