use of org.reactivestreams.Subscriber in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testSubscriberErrorOnLinkCLose.
@Test(timeout = 20000)
public void testSubscriberErrorOnLinkCLose(TestContext context) throws Exception {
server.close();
final Async clientLinkOpenAsync = context.async();
final Async serverLinkOpenAsync = context.async();
final Async serverLinkCloseAsync = context.async();
final Async clientLinkCloseAsync = context.async();
ProtonServer protonServer = null;
try {
protonServer = createServer((serverConnection) -> {
serverConnection.openHandler(result -> {
serverConnection.open();
});
serverConnection.sessionOpenHandler(session -> session.open());
serverConnection.senderOpenHandler(serverSender -> {
serverSender.closeHandler(res -> {
serverLinkCloseAsync.complete();
});
LOG.trace("Server sender opened");
serverSender.open();
serverLinkOpenAsync.complete();
serverSender.close();
});
});
// ===== 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) {
clientLinkCloseAsync.complete();
}
@Override
public void onComplete() {
context.fail("onComplete called");
}
});
});
serverLinkOpenAsync.awaitSuccess();
clientLinkOpenAsync.awaitSuccess();
clientLinkCloseAsync.awaitSuccess();
serverLinkCloseAsync.awaitSuccess();
} finally {
if (protonServer != null) {
protonServer.close();
}
}
}
use of org.reactivestreams.Subscriber in project vertx-proton by vert-x3.
the class ProtonPublisherIntTest method testAutoAccept.
@Test(timeout = 20000)
public void testAutoAccept(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<>());
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 Message, which auto-accepts after onNext
ProtonPublisher<Message> publisher = ProtonStreams.createConsumer(connection, "myAddress");
publisher.subscribe(new Subscriber<Message>() {
Subscription sub = null;
@Override
public void onSubscribe(Subscription s) {
sub = s;
LOG.trace("Flowing initial credit");
sub.request(messageCount);
}
@Override
public void onNext(Message m) {
int count = counter.incrementAndGet();
validateMessage(context, count, String.valueOf(count), m);
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();
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 org.reactivestreams.Subscriber in project vertx-proton by vert-x3.
the class MessageSubscriberWhiteboxVerificationTckTest method createServer.
private TestServer createServer() throws Exception {
return new TestServer(vertx, (connection) -> {
connection.openHandler(res -> {
LOG.trace("Client connected: " + connection.getRemoteContainer());
connection.open();
}).closeHandler(c -> {
LOG.trace("Client closing amqp connection: " + connection.getRemoteContainer());
connection.close();
connection.disconnect();
}).disconnectHandler(c -> {
LOG.trace("Client socket disconnected: " + connection.getRemoteContainer());
connection.disconnect();
}).sessionOpenHandler(session -> session.open());
connection.receiverOpenHandler(receiver -> {
if (!server.getDetachLink()) {
LOG.trace("Receiving from client to: " + receiver.getRemoteTarget().getAddress());
// This is rather naive, for example use only, proper
receiver.setTarget(receiver.getRemoteTarget());
// servers should ensure that they advertise their own
// Target settings that actually reflect what is in place.
// The request may have also been for a dynamic address.
receiver.handler((delivery, msg) -> {
String address = msg.getAddress();
if (address == null) {
address = receiver.getRemoteTarget().getAddress();
}
Section body = msg.getBody();
String content = "unknown";
if (body instanceof AmqpValue) {
content = (String) ((AmqpValue) body).getValue();
}
LOG.trace("message to:" + address + ", body: " + content);
});
receiver.closeHandler(s -> {
s.result().close();
});
}
receiver.open();
if (server.getDetachLink()) {
receiver.setCondition(new ErrorCondition(Symbol.getSymbol("Failed Subscriber Requested"), ""));
receiver.close();
}
});
});
}
use of org.reactivestreams.Subscriber in project vertx-proton by vert-x3.
the class MessageSubscriberWhiteboxVerificationTckTest method createSubscriber.
@Override
public Subscriber<Message> createSubscriber(WhiteboxSubscriberProbe<Message> probe) {
int actualPort = server.actualPort();
ProtonClient client = ProtonClient.create(vertx);
AtomicReference<Subscriber<Message>> ref = new AtomicReference<>();
CountDownLatch latch = new CountDownLatch(1);
client.connect("localhost", actualPort, result -> {
if (result.succeeded()) {
ProtonConnection conn = result.result();
conn.open();
// Modified stream impl, overriding methods to add test probe instrumentation
ProtonSubscriberImpl subscriber = new ProtonSubscriberImpl("myAddress", (ProtonConnectionImpl) conn);
ProtonSubscriber<Message> stream = new ProtonSubscriberWrapperImpl(subscriber) {
@Override
public void onSubscribe(final Subscription s) {
super.onSubscribe(s);
probe.registerOnSubscribe(new SubscriberPuppet() {
@Override
public void triggerRequest(long n) {
s.request(n);
}
@Override
public void signalCancel() {
s.cancel();
}
});
}
@Override
public void onNext(Message value) {
probe.registerOnNext(value);
super.onNext(value);
}
@Override
public void onError(Throwable t) {
probe.registerOnError(t);
super.onError(t);
}
@Override
public void onComplete() {
probe.registerOnComplete();
super.onComplete();
}
};
ref.set(stream);
} else {
LOG.error("Connection failed");
}
latch.countDown();
});
try {
LOG.trace("Awaiting connection");
boolean res = latch.await(2, TimeUnit.SECONDS);
LOG.trace("Client connected: " + res);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while creating subscriber", e);
}
return ref.get();
}
use of org.reactivestreams.Subscriber in project vertx-proton by vert-x3.
the class TrackerSubscriberWhiteboxVerificationTckTest method createSubscriber.
@Override
public Subscriber<Tracker> createSubscriber(WhiteboxSubscriberProbe<Tracker> probe) {
int actualPort = server.actualPort();
ProtonClient client = ProtonClient.create(vertx);
AtomicReference<Subscriber<Tracker>> ref = new AtomicReference<>();
CountDownLatch latch = new CountDownLatch(1);
client.connect("localhost", actualPort, result -> {
if (result.succeeded()) {
ProtonConnection conn = result.result();
conn.open();
// Modified stream impl, overriding methods to add test probe instrumentation
ProtonSubscriber<Tracker> stream = new ProtonSubscriberImpl("myAddress", (ProtonConnectionImpl) conn) {
@Override
public void onSubscribe(final Subscription s) {
super.onSubscribe(s);
probe.registerOnSubscribe(new SubscriberPuppet() {
@Override
public void triggerRequest(long n) {
s.request(n);
}
@Override
public void signalCancel() {
s.cancel();
}
});
}
@Override
public void onNext(Tracker value) {
probe.registerOnNext(value);
super.onNext(value);
}
@Override
public void onError(Throwable t) {
probe.registerOnError(t);
super.onError(t);
}
@Override
public void onComplete() {
probe.registerOnComplete();
super.onComplete();
}
};
ref.set(stream);
} else {
LOG.error("Connection failed");
}
latch.countDown();
});
try {
LOG.trace("Awaiting connection");
boolean res = latch.await(2, TimeUnit.SECONDS);
LOG.trace("Client connected: " + res);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while creating subscriber", e);
}
return ref.get();
}
Aggregations