use of io.vertx.proton.ProtonClient in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testManualAccept.
@Test(timeout = 20000)
public void testManualAccept(TestContext context) throws Exception {
server.close();
final Async receivedMessagesAsync = context.async();
final Async ackedMessagesAsync = context.async();
int messageCount = 5;
List<Integer> accepted = Collections.synchronizedList(new ArrayList<>());
List<Delivery> deliveries = Collections.synchronizedList(new ArrayList<>());
AtomicInteger msgNum = new AtomicInteger(1);
ProtonServer protonServer = null;
try {
protonServer = createServer((serverConnection) -> {
serverConnection.openHandler(result -> {
serverConnection.open();
});
serverConnection.sessionOpenHandler(session -> session.open());
serverConnection.senderOpenHandler(serverSender -> {
LOG.trace("Server sender opened");
serverSender.open();
serverSender.sendQueueDrainHandler(s -> {
for (int i = msgNum.get(); i <= messageCount; i = msgNum.incrementAndGet()) {
int j = i;
serverSender.send(message(String.valueOf(i)), del -> {
LOG.trace("Server received disposition for msg: " + j);
if (del.getRemoteState() instanceof Accepted) {
accepted.add(j);
if (accepted.size() == messageCount) {
ackedMessagesAsync.complete();
}
} else {
context.fail("Expected message to be accepted");
}
});
}
});
});
});
// ===== Client Handling =====
AtomicInteger counter = new AtomicInteger(0);
ProtonClient client = ProtonClient.create(vertx);
client.connect("localhost", protonServer.actualPort(), res -> {
context.assertTrue(res.succeeded());
ProtonConnection connection = res.result();
// Create consumer stream of Delivery, which must be manually accepted
ProtonPublisher<Delivery> publisher = ProtonStreams.createDeliveryConsumer(connection, "myAddress");
publisher.subscribe(new Subscriber<Delivery>() {
Subscription sub = null;
@Override
public void onSubscribe(Subscription s) {
sub = s;
LOG.trace("Flowing initial credit");
sub.request(messageCount);
}
@Override
public void onNext(Delivery d) {
int count = counter.incrementAndGet();
deliveries.add(d);
if (count == messageCount) {
LOG.trace("Got all messages, completing async");
receivedMessagesAsync.complete();
}
}
@Override
public void onError(Throwable t) {
if (!receivedMessagesAsync.isCompleted()) {
context.fail("onError called");
}
}
@Override
public void onComplete() {
context.fail("onComplete called");
}
});
connection.open();
});
receivedMessagesAsync.awaitSuccess();
// Small delay to ensure there is a window for any
// unexpected automatic accept to occur
Thread.sleep(50);
// Verify no messages accepted yet
context.assertTrue(accepted.isEmpty(), "Unexpected accepted count");
// Accept them all
for (Delivery d : deliveries) {
d.accept();
}
ackedMessagesAsync.awaitSuccess();
} finally {
if (protonServer != null) {
protonServer.close();
}
}
// Verify the messages were all accepted
context.assertEquals(accepted.size(), messageCount, "Unexpected accepted count");
for (int i = 1; i <= messageCount; i++) {
// Verify each accepted number, establish correct order etc.
context.assertEquals(accepted.remove(0), i, "Unexpected msgNum");
}
}
use of io.vertx.proton.ProtonClient in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testConfigureSubscriptionDynamic.
@Test(timeout = 20000)
public void testConfigureSubscriptionDynamic(TestContext context) throws Exception {
server.close();
final Async clientLinkOpenAsync = context.async();
final Async serverLinkOpenAsync = context.async();
final Async clientLinkCloseAsync = context.async();
final String dynamicAddress = "testConfigureSubscriptionDynamic:" + UUID.randomUUID();
ProtonServer protonServer = null;
try {
protonServer = createServer((serverConnection) -> {
serverConnection.openHandler(result -> {
serverConnection.open();
});
serverConnection.sessionOpenHandler(session -> session.open());
serverConnection.senderOpenHandler(serverSender -> {
serverSender.closeHandler(res -> {
serverSender.close();
});
// Verify the remote terminus details used were as expected
context.assertNotNull(serverSender.getRemoteSource(), "source should not be null");
org.apache.qpid.proton.amqp.messaging.Source remoteSource = (org.apache.qpid.proton.amqp.messaging.Source) serverSender.getRemoteSource();
context.assertTrue(remoteSource.getDynamic(), "expected dynamic source");
context.assertNull(remoteSource.getAddress(), "expected no source address");
// Set the local terminus details
org.apache.qpid.proton.amqp.messaging.Source source = (org.apache.qpid.proton.amqp.messaging.Source) remoteSource.copy();
source.setAddress(dynamicAddress);
serverSender.setSource(source);
LOG.trace("Server sender opened");
serverSender.open();
serverLinkOpenAsync.complete();
});
});
// ===== Client Handling =====
ProtonClient client = ProtonClient.create(vertx);
client.connect("localhost", protonServer.actualPort(), res -> {
context.assertTrue(res.succeeded());
ProtonConnection connection = res.result();
connection.open();
// Create publisher with dynamic option
ProtonPublisherOptions options = new ProtonPublisherOptions().setDynamic(true);
ProtonPublisher<Delivery> publisher = ProtonStreams.createDeliveryConsumer(connection, null, options);
publisher.subscribe(new Subscriber<Delivery>() {
Subscription sub = null;
@Override
public void onSubscribe(Subscription s) {
// Verify the remote address detail
context.assertEquals(dynamicAddress, publisher.getRemoteAddress(), "unexpected remote address");
// Grab and verify the source details
org.apache.qpid.proton.amqp.messaging.Source remoteSource = (org.apache.qpid.proton.amqp.messaging.Source) publisher.getRemoteSource();
context.assertTrue(remoteSource.getDynamic(), "expected dynamic source");
context.assertEquals(dynamicAddress, remoteSource.getAddress(), "unexpected source address");
clientLinkOpenAsync.complete();
sub = s;
s.request(1);
sub.cancel();
}
@Override
public void onNext(Delivery e) {
}
@Override
public void onError(Throwable t) {
if (!clientLinkCloseAsync.isCompleted()) {
context.fail("onError called");
}
}
@Override
public void onComplete() {
clientLinkCloseAsync.complete();
}
});
});
serverLinkOpenAsync.awaitSuccess();
clientLinkOpenAsync.awaitSuccess();
clientLinkCloseAsync.awaitSuccess();
} finally {
if (protonServer != null) {
protonServer.close();
}
}
}
use of io.vertx.proton.ProtonClient in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testMaxOutstandingCredit2.
@Test(timeout = 20000)
public void testMaxOutstandingCredit2(TestContext context) throws Exception {
server.close();
final int maxOutstandingCredit = 20;
final int totalRequests = 107;
final Async receivedMessagesAsync = context.async();
AtomicInteger receivedCredits = new AtomicInteger();
AtomicInteger maxCredits = new AtomicInteger();
AtomicInteger counter = new AtomicInteger();
ProtonServer protonServer = null;
try {
protonServer = createServer((serverConnection) -> {
serverConnection.openHandler(result -> {
serverConnection.open();
});
serverConnection.sessionOpenHandler(session -> session.open());
serverConnection.senderOpenHandler(serverSender -> {
LOG.trace("Server sender opened");
serverSender.open();
AtomicInteger msgNum = new AtomicInteger();
serverSender.sendQueueDrainHandler(s -> {
int credit = serverSender.getCredit();
LOG.trace("Server credit: " + credit);
int max = maxCredits.get();
if (credit > max) {
maxCredits.compareAndSet(max, credit);
}
while (!serverSender.sendQueueFull()) {
serverSender.send(message(String.valueOf(msgNum.incrementAndGet())));
}
// Simple count, only works because of the thread model and using all credits as received
receivedCredits.addAndGet(credit);
});
});
});
// ===== Client Handling =====
ProtonClient client = ProtonClient.create(vertx);
client.connect("localhost", protonServer.actualPort(), res -> {
context.assertTrue(res.succeeded());
ProtonConnection connection = res.result();
connection.open();
// Create publisher with set maxOutstanding
ProtonPublisherOptions options = new ProtonPublisherOptions().setMaxOutstandingCredit(maxOutstandingCredit);
ProtonPublisher<Delivery> publisher = ProtonStreams.createDeliveryConsumer(connection, "myAddress", options);
publisher.subscribe(new Subscriber<Delivery>() {
Subscription sub = null;
@Override
public void onSubscribe(Subscription s) {
LOG.trace("Flowing initial credit");
sub = s;
sub.request(totalRequests);
}
@Override
public void onNext(Delivery d) {
int count = counter.incrementAndGet();
validateMessage(context, count, String.valueOf(count), d.message());
if (count >= totalRequests) {
receivedMessagesAsync.complete();
}
}
@Override
public void onError(Throwable t) {
if (!receivedMessagesAsync.isCompleted()) {
context.fail("onError called");
}
}
@Override
public void onComplete() {
context.fail("onComplete called");
}
});
});
// Verify the max outstanding was honoured and messages were all received as expected
receivedMessagesAsync.awaitSuccess();
context.assertEquals(maxCredits.get(), maxOutstandingCredit, "Unexpected max credit");
context.assertEquals(receivedCredits.get(), totalRequests, "Unexpected total credits received");
} finally {
if (protonServer != null) {
protonServer.close();
}
}
}
use of io.vertx.proton.ProtonClient in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testAlternativeDispositionStates.
@Test(timeout = 20000)
public void testAlternativeDispositionStates(TestContext context) throws Exception {
server.close();
final Async receivedMessagesAsync = context.async();
final Async ackedMessagesAsync = context.async();
int messageCount = 4;
List<DeliveryState> deliveryStates = Collections.synchronizedList(new ArrayList<>());
List<Delivery> deliveries = Collections.synchronizedList(new ArrayList<>());
AtomicInteger msgNum = new AtomicInteger(1);
ProtonServer protonServer = null;
try {
protonServer = createServer((serverConnection) -> {
serverConnection.openHandler(result -> {
serverConnection.open();
});
serverConnection.sessionOpenHandler(session -> session.open());
serverConnection.senderOpenHandler(serverSender -> {
LOG.trace("Server sender opened");
serverSender.open();
serverSender.sendQueueDrainHandler(s -> {
for (int i = msgNum.get(); i <= messageCount; i = msgNum.incrementAndGet()) {
int j = i;
serverSender.send(message(String.valueOf(i)), del -> {
LOG.trace("Server received disposition for msg: " + j);
DeliveryState state = del.getRemoteState();
context.assertNotNull(state, "Expected message to have a delivery state");
deliveryStates.add(state);
if (deliveryStates.size() == messageCount) {
ackedMessagesAsync.complete();
}
});
}
});
});
});
// ===== Client Handling =====
AtomicInteger counter = new AtomicInteger(0);
ProtonClient client = ProtonClient.create(vertx);
client.connect("localhost", protonServer.actualPort(), res -> {
context.assertTrue(res.succeeded());
ProtonConnection connection = res.result();
// Create consumer stream of Delivery, which must be manually accepted
ProtonPublisher<Delivery> publisher = ProtonStreams.createDeliveryConsumer(connection, "myAddress");
publisher.subscribe(new Subscriber<Delivery>() {
Subscription sub = null;
@Override
public void onSubscribe(Subscription s) {
sub = s;
LOG.trace("Flowing initial credit");
sub.request(messageCount);
}
@Override
public void onNext(Delivery d) {
int count = counter.incrementAndGet();
deliveries.add(d);
if (count == messageCount) {
LOG.trace("Got all messages, completing async");
receivedMessagesAsync.complete();
}
}
@Override
public void onError(Throwable t) {
if (!receivedMessagesAsync.isCompleted()) {
context.fail("onError called");
}
}
@Override
public void onComplete() {
context.fail("onComplete called");
}
});
connection.open();
});
receivedMessagesAsync.awaitSuccess();
// Small delay to ensure there is a window for any
// unexpected automatic accept to occur
Thread.sleep(50);
// Verify no messages acked yet
context.assertTrue(deliveryStates.isEmpty(), "Unexpected acks count");
// Ack them all
deliveries.get(0).disposition(Accepted.getInstance(), true);
deliveries.get(1).disposition(Released.getInstance(), true);
deliveries.get(2).disposition(new Rejected(), true);
deliveries.get(3).disposition(new Modified(), true);
ackedMessagesAsync.awaitSuccess();
} finally {
if (protonServer != null) {
protonServer.close();
}
}
// Verify the messages were all acked as expected
context.assertEquals(deliveryStates.size(), messageCount, "Unexpected state count: " + deliveryStates);
context.assertTrue(deliveryStates.get(0) instanceof Accepted, "Unexpected state: " + deliveryStates.get(0));
context.assertTrue(deliveryStates.get(1) instanceof Released, "Unexpected state: " + deliveryStates.get(1));
context.assertTrue(deliveryStates.get(2) instanceof Rejected, "Unexpected state: " + deliveryStates.get(2));
context.assertTrue(deliveryStates.get(3) instanceof Modified, "Unexpected state: " + deliveryStates.get(3));
}
use of io.vertx.proton.ProtonClient in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testSubscriberErrorOnConnectionEnd.
@Test(timeout = 20000)
public void testSubscriberErrorOnConnectionEnd(TestContext context) throws Exception {
server.close();
final Async clientLinkOpenAsync = context.async();
final Async serverLinkOpenAsync = context.async();
final Async subErroredAsync = context.async();
ProtonServer protonServer = null;
try {
protonServer = createServer((serverConnection) -> {
serverConnection.openHandler(result -> {
serverConnection.open();
});
serverConnection.sessionOpenHandler(session -> session.open());
serverConnection.senderOpenHandler(serverSender -> {
LOG.trace("Server sender opened");
serverSender.open();
serverLinkOpenAsync.complete();
});
});
// ===== Client Handling =====
ProtonClient client = ProtonClient.create(vertx);
client.connect("localhost", protonServer.actualPort(), res -> {
context.assertTrue(res.succeeded());
ProtonConnection connection = res.result();
connection.open();
ProtonPublisher<Delivery> publisher = ProtonStreams.createDeliveryConsumer(connection, "myAddress");
publisher.subscribe(new Subscriber<Delivery>() {
@Override
public void onSubscribe(Subscription s) {
clientLinkOpenAsync.complete();
}
@Override
public void onNext(Delivery e) {
context.fail("onNext called");
}
@Override
public void onError(Throwable t) {
LOG.trace("onError called");
subErroredAsync.complete();
}
@Override
public void onComplete() {
LOG.trace("onComplete called");
context.fail("onComplete called");
}
});
});
serverLinkOpenAsync.awaitSuccess();
clientLinkOpenAsync.awaitSuccess();
context.assertFalse(subErroredAsync.isCompleted());
protonServer.close();
protonServer = null;
subErroredAsync.awaitSuccess();
} finally {
if (protonServer != null) {
protonServer.close();
}
}
}
Aggregations