use of org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback in project incubator-pulsar by apache.
the class ServerCnxTest method testCreateProducerMultipleTimeouts.
@Test(timeOut = 30000, enabled = false)
public void testCreateProducerMultipleTimeouts() throws Exception {
resetChannel();
setChannelConnected();
// Delay the topic creation in a deterministic way
CountDownLatch topicCreationDelayLatch = new CountDownLatch(1);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
topicCreationDelayLatch.await();
((OpenLedgerCallback) invocationOnMock.getArguments()[2]).openLedgerComplete(ledgerMock, null);
return null;
}
}).when(mlFactoryMock).asyncOpen(matches(".*success.*"), any(ManagedLedgerConfig.class), any(OpenLedgerCallback.class), anyObject());
// In a create producer timeout from client side we expect to see this sequence of commands :
// 1. create producer
// 2. close producer (when the timeout is triggered, which may be before the producer was created on the broker
// 3. create producer (triggered by reconnection logic)
// These operations need to be serialized, to allow the last create producer to finally succeed
// (There can be more create/close pairs in the sequence, depending on the client timeout
String producerName = "my-producer";
ByteBuf createProducer1 = Commands.newProducer(successTopicName, 1, /* producer id */
1, /* request id */
producerName, Collections.emptyMap());
channel.writeInbound(createProducer1);
ByteBuf closeProducer1 = Commands.newCloseProducer(1, /* producer id */
2);
channel.writeInbound(closeProducer1);
ByteBuf createProducer2 = Commands.newProducer(successTopicName, 1, /* producer id */
3, /* request id */
producerName, Collections.emptyMap());
channel.writeInbound(createProducer2);
ByteBuf createProducer3 = Commands.newProducer(successTopicName, 1, /* producer id */
4, /* request id */
producerName, Collections.emptyMap());
channel.writeInbound(createProducer3);
ByteBuf createProducer4 = Commands.newProducer(successTopicName, 1, /* producer id */
5, /* request id */
producerName, Collections.emptyMap());
channel.writeInbound(createProducer4);
// Close succeeds
Object response = getResponse();
assertEquals(response.getClass(), CommandSuccess.class);
assertEquals(((CommandSuccess) response).getRequestId(), 2);
// Now allow topic creation to complete
topicCreationDelayLatch.countDown();
// 1st producer it's not acked
// 2nd producer fails
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 3);
// 3rd producer fails
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 4);
// 4nd producer fails
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 5);
Thread.sleep(100);
// We should not receive response for 1st producer, since it was cancelled by the close
assertTrue(channel.outboundMessages().isEmpty());
assertTrue(channel.isActive());
channel.finish();
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback in project incubator-pulsar by apache.
the class ServerCnxTest method setupMLAsyncCallbackMocks.
private void setupMLAsyncCallbackMocks() {
doReturn(new ArrayList<Object>()).when(ledgerMock).getCursors();
// call openLedgerComplete with ledgerMock on ML factory asyncOpen
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Thread.sleep(300);
((OpenLedgerCallback) invocationOnMock.getArguments()[2]).openLedgerComplete(ledgerMock, null);
return null;
}
}).when(mlFactoryMock).asyncOpen(matches(".*success.*"), any(ManagedLedgerConfig.class), any(OpenLedgerCallback.class), anyObject());
// call openLedgerFailed on ML factory asyncOpen
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Thread.sleep(300);
new Thread(() -> {
((OpenLedgerCallback) invocationOnMock.getArguments()[2]).openLedgerFailed(new ManagedLedgerException("Managed ledger failure"), null);
}).start();
return null;
}
}).when(mlFactoryMock).asyncOpen(matches(".*fail.*"), any(ManagedLedgerConfig.class), any(OpenLedgerCallback.class), anyObject());
// call addComplete on ledger asyncAddEntry
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
((AddEntryCallback) invocationOnMock.getArguments()[1]).addComplete(new PositionImpl(-1, -1), invocationOnMock.getArguments()[2]);
return null;
}
}).when(ledgerMock).asyncAddEntry(any(ByteBuf.class), any(AddEntryCallback.class), anyObject());
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Thread.sleep(300);
((OpenCursorCallback) invocationOnMock.getArguments()[2]).openCursorComplete(cursorMock, null);
return null;
}
}).when(ledgerMock).asyncOpenCursor(matches(".*success.*"), any(InitialPosition.class), any(OpenCursorCallback.class), anyObject());
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Thread.sleep(300);
((OpenCursorCallback) invocationOnMock.getArguments()[2]).openCursorFailed(new ManagedLedgerException("Managed ledger failure"), null);
return null;
}
}).when(ledgerMock).asyncOpenCursor(matches(".*fail.*"), any(InitialPosition.class), any(OpenCursorCallback.class), anyObject());
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
((DeleteCursorCallback) invocationOnMock.getArguments()[1]).deleteCursorComplete(null);
return null;
}
}).when(ledgerMock).asyncDeleteCursor(matches(".*success.*"), any(DeleteCursorCallback.class), anyObject());
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
((DeleteCursorCallback) invocationOnMock.getArguments()[1]).deleteCursorFailed(new ManagedLedgerException("Managed ledger failure"), null);
return null;
}
}).when(ledgerMock).asyncDeleteCursor(matches(".*fail.*"), any(DeleteCursorCallback.class), anyObject());
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
((CloseCallback) invocationOnMock.getArguments()[0]).closeComplete(null);
return null;
}
}).when(cursorMock).asyncClose(any(CloseCallback.class), anyObject());
doReturn(successSubName).when(cursorMock).getName();
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback in project incubator-pulsar by apache.
the class ServerCnxTest method testCreateProducerTimeout.
@Test(timeOut = 30000)
public void testCreateProducerTimeout() throws Exception {
resetChannel();
setChannelConnected();
// Delay the topic creation in a deterministic way
CompletableFuture<Runnable> openTopicFuture = new CompletableFuture<>();
doAnswer(invocationOnMock -> {
openTopicFuture.complete(() -> {
((OpenLedgerCallback) invocationOnMock.getArguments()[2]).openLedgerComplete(ledgerMock, null);
});
return null;
}).when(mlFactoryMock).asyncOpen(matches(".*success.*"), any(ManagedLedgerConfig.class), any(OpenLedgerCallback.class), anyObject());
// In a create producer timeout from client side we expect to see this sequence of commands :
// 1. create producer
// 2. close producer (when the timeout is triggered, which may be before the producer was created on the broker
// 3. create producer (triggered by reconnection logic)
// These operations need to be serialized, to allow the last create producer to finally succeed
// (There can be more create/close pairs in the sequence, depending on the client timeout
String producerName = "my-producer";
ByteBuf createProducer1 = Commands.newProducer(successTopicName, 1, /* producer id */
1, /* request id */
producerName, Collections.emptyMap());
channel.writeInbound(createProducer1);
ByteBuf closeProducer = Commands.newCloseProducer(1, /* producer id */
2);
channel.writeInbound(closeProducer);
ByteBuf createProducer2 = Commands.newProducer(successTopicName, 1, /* producer id */
3, /* request id */
producerName, Collections.emptyMap());
channel.writeInbound(createProducer2);
// Complete the topic opening
openTopicFuture.get().run();
// Close succeeds
Object response = getResponse();
assertEquals(response.getClass(), CommandSuccess.class);
assertEquals(((CommandSuccess) response).getRequestId(), 2);
// 2nd producer fails to create
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 3);
// We should not receive response for 1st producer, since it was cancelled by the close
assertTrue(channel.outboundMessages().isEmpty());
assertTrue(channel.isActive());
channel.finish();
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback in project incubator-pulsar by apache.
the class ServerCnxTest method testSubscribeTimeout.
@Test(timeOut = 30000)
public void testSubscribeTimeout() throws Exception {
resetChannel();
setChannelConnected();
// Delay the topic creation in a deterministic way
CompletableFuture<Runnable> openTopicTask = new CompletableFuture<>();
doAnswer(invocationOnMock -> {
openTopicTask.complete(() -> {
((OpenLedgerCallback) invocationOnMock.getArguments()[2]).openLedgerComplete(ledgerMock, null);
});
return null;
}).when(mlFactoryMock).asyncOpen(matches(".*success.*"), any(ManagedLedgerConfig.class), any(OpenLedgerCallback.class), anyObject());
// In a subscribe timeout from client side we expect to see this sequence of commands :
// 1. Subscribe
// 2. close consumer (when the timeout is triggered, which may be before the consumer was created on the broker)
// 3. Subscribe (triggered by reconnection logic)
// These operations need to be serialized, to allow the last subscribe operation to finally succeed
// (There can be more subscribe/close pairs in the sequence, depending on the client timeout
ByteBuf subscribe1 = //
Commands.newSubscribe(//
successTopicName, successSubName, 1, /* consumer id */
1, /* request id */
SubType.Exclusive, 0, "test");
channel.writeInbound(subscribe1);
ByteBuf closeConsumer = Commands.newCloseConsumer(1, /* consumer id */
2);
channel.writeInbound(closeConsumer);
ByteBuf subscribe2 = //
Commands.newSubscribe(//
successTopicName, successSubName, 1, /* consumer id */
3, /* request id */
SubType.Exclusive, 0, "test");
channel.writeInbound(subscribe2);
ByteBuf subscribe3 = //
Commands.newSubscribe(//
successTopicName, successSubName, 1, /* consumer id */
4, /* request id */
SubType.Exclusive, 0, "test");
channel.writeInbound(subscribe3);
ByteBuf subscribe4 = //
Commands.newSubscribe(//
successTopicName, successSubName, 1, /* consumer id */
5, /* request id */
SubType.Exclusive, 0, "test");
channel.writeInbound(subscribe4);
openTopicTask.get().run();
Object response;
synchronized (this) {
// Close succeeds
response = getResponse();
assertEquals(response.getClass(), CommandSuccess.class);
assertEquals(((CommandSuccess) response).getRequestId(), 2);
// All other subscribe should fail
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 3);
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 4);
response = getResponse();
assertEquals(response.getClass(), CommandError.class);
assertEquals(((CommandError) response).getRequestId(), 5);
// We should not receive response for 1st producer, since it was cancelled by the close
assertTrue(channel.outboundMessages().isEmpty());
assertTrue(channel.isActive());
}
channel.finish();
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback in project incubator-pulsar by apache.
the class PersistentTopicTest method testCreateTopic.
@Test
public void testCreateTopic() throws Exception {
final ManagedLedger ledgerMock = mock(ManagedLedger.class);
doReturn(new ArrayList<Object>()).when(ledgerMock).getCursors();
final String topicName = "persistent://prop/use/ns-abc/topic1";
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
((OpenLedgerCallback) invocationOnMock.getArguments()[2]).openLedgerComplete(ledgerMock, null);
return null;
}
}).when(mlFactoryMock).asyncOpen(anyString(), any(ManagedLedgerConfig.class), any(OpenLedgerCallback.class), anyObject());
CompletableFuture<Void> future = brokerService.getTopic(topicName).thenAccept(topic -> {
assertTrue(topic.toString().contains(topicName));
}).exceptionally((t) -> {
fail("should not fail");
return null;
});
// wait for completion
try {
future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
fail("Should not fail or time out");
}
}
Aggregations