use of org.apache.pulsar.broker.service.persistent.PersistentTopic in project incubator-pulsar by apache.
the class PersistentTopicE2ETest method testGracefulClose.
@Test(enabled = false)
public // TODO: enable this after java client supports graceful close
void testGracefulClose() throws Exception {
final String topicName = "persistent://prop/use/ns-abc/topic4";
final String subName = "sub4";
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
assertNotNull(topicRef);
ExecutorService executor = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(1);
executor.submit(() -> {
for (int i = 0; i < 10; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
}
latch.countDown();
return null;
});
producer.close();
// 1. verify there are no pending publish acks once the producer close
// is completed on client
assertEquals(topicRef.getProducers().values().iterator().next().getPendingPublishAcks(), 0);
// safety latch in case of failure,
// wait for the spawned thread to complete
latch.await();
Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscribe();
PersistentSubscription subRef = topicRef.getSubscription(subName);
assertNotNull(subRef);
Message<byte[]> msg = null;
for (int i = 0; i < 10; i++) {
msg = consumer.receive();
}
// message acks
try {
consumer.close();
fail("should have failed");
} catch (IllegalStateException e) {
// Expected - messages not acked
}
consumer.acknowledgeCumulative(msg);
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
// 3. verify consumer close succeeds once all messages are ack'ed
consumer.close();
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
assertTrue(subRef.getDispatcher().isConsumerConnected());
executor.shutdown();
}
use of org.apache.pulsar.broker.service.persistent.PersistentTopic in project incubator-pulsar by apache.
the class PersistentTopicE2ETest method testActiveSubscriptionWithCache.
/**
* Validation: 1. validates active-cursor after active subscription 2. validate active-cursor with subscription 3.
* unconsumed messages should be present into cache 4. cache and active-cursor should be empty once subscription is
* closed
*
* @throws Exception
*/
@Test
public void testActiveSubscriptionWithCache() throws Exception {
final String topicName = "persistent://prop/use/ns-abc/topic2";
final String subName = "sub2";
Message<byte[]> msg;
int recvQueueSize = 4;
// (1) Create subscription
Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).receiverQueueSize(recvQueueSize).subscribe();
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
// (2) Produce Messages
for (int i = 0; i < recvQueueSize / 2; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
msg = consumer.receive();
consumer.acknowledge(msg);
}
PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
// (3) Get Entry cache
ManagedLedgerImpl ledger = (ManagedLedgerImpl) topicRef.getManagedLedger();
Field cacheField = ManagedLedgerImpl.class.getDeclaredField("entryCache");
cacheField.setAccessible(true);
EntryCacheImpl entryCache = (EntryCacheImpl) cacheField.get(ledger);
/**
*********** Validation on non-empty active-cursor *************
*/
// (4) Get ActiveCursor : which is list of active subscription
Iterable<ManagedCursor> activeCursors = ledger.getActiveCursors();
ManagedCursor curosr = activeCursors.iterator().next();
// (4.1) Validate: active Cursor must be non-empty
assertNotNull(curosr);
// (4.2) Validate: validate cursor name
assertEquals(subName, curosr.getName());
// (4.3) Validate: entryCache should have cached messages
assertTrue(entryCache.getSize() != 0);
/**
*********** Validation on empty active-cursor *************
*/
// (5) Close consumer: which (1)removes activeConsumer and (2)clears the entry-cache
consumer.close();
Thread.sleep(1000);
// (5.1) Validate: active-consumer must be empty
assertFalse(ledger.getActiveCursors().iterator().hasNext());
// (5.2) Validate: Entry-cache must be cleared
assertTrue(entryCache.getSize() == 0);
}
use of org.apache.pulsar.broker.service.persistent.PersistentTopic in project incubator-pulsar by apache.
the class PersistentTopicE2ETest method testSimpleCloseTopic.
@Test
public void testSimpleCloseTopic() throws Exception {
final String topicName = "persistent://prop/use/ns-abc/topic5";
final String subName = "sub5";
Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscribe();
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
assertNotNull(topicRef);
PersistentSubscription subRef = topicRef.getSubscription(subName);
assertNotNull(subRef);
Message<byte[]> msg;
for (int i = 0; i < 10; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
msg = consumer.receive();
consumer.acknowledge(msg);
}
producer.close();
consumer.close();
topicRef.close().get();
assertNull(pulsar.getBrokerService().getTopicReference(topicName));
}
use of org.apache.pulsar.broker.service.persistent.PersistentTopic in project incubator-pulsar by apache.
the class PersistentTopicE2ETest method testSimpleConsumerEvents.
@Test
public void testSimpleConsumerEvents() throws Exception {
final String topicName = "persistent://prop/use/ns-abc/topic1";
final String subName = "sub1";
final int numMsgs = 10;
// 1. client connect
Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscribe();
PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
PersistentSubscription subRef = topicRef.getSubscription(subName);
assertNotNull(topicRef);
assertNotNull(subRef);
assertTrue(subRef.getDispatcher().isConsumerConnected());
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
assertEquals(getAvailablePermits(subRef), 1000);
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
for (int i = 0; i < numMsgs * 2; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
}
assertTrue(subRef.getDispatcher().isConsumerConnected());
rolloverPerIntervalStats();
assertEquals(subRef.getNumberOfEntriesInBacklog(), numMsgs * 2);
// 2. messages pushed before client receive
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
assertEquals(getAvailablePermits(subRef), 1000 - numMsgs * 2);
Message<byte[]> msg = null;
for (int i = 0; i < numMsgs; i++) {
msg = consumer.receive();
// 3. in-order message delivery
assertEquals(new String(msg.getData()), "my-message-" + i);
consumer.acknowledge(msg);
}
rolloverPerIntervalStats();
// 4. messages deleted on individual acks
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
assertEquals(subRef.getNumberOfEntriesInBacklog(), numMsgs);
for (int i = 0; i < numMsgs; i++) {
msg = consumer.receive();
if (i == numMsgs - 1) {
consumer.acknowledgeCumulative(msg);
}
}
rolloverPerIntervalStats();
// 5. messages deleted on cumulative acks
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
assertEquals(subRef.getNumberOfEntriesInBacklog(), 0);
// 6. consumer unsubscribe
consumer.unsubscribe();
// 6. consumer graceful close
consumer.close();
// 7. consumer unsubscribe
try {
consumer.unsubscribe();
fail("Should have failed");
} catch (PulsarClientException.AlreadyClosedException e) {
// ok
}
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
subRef = topicRef.getSubscription(subName);
assertNull(subRef);
producer.close();
Thread.sleep(ASYNC_EVENT_COMPLETION_WAIT);
}
use of org.apache.pulsar.broker.service.persistent.PersistentTopic in project incubator-pulsar by apache.
the class PersistentTopicE2ETest method testMessageExpiry.
@Test
public void testMessageExpiry() throws Exception {
int messageTTLSecs = 1;
String namespaceName = "prop/use/expiry-check";
admin.namespaces().createNamespace(namespaceName);
admin.namespaces().setNamespaceMessageTTL(namespaceName, messageTTLSecs);
final String topicName = "persistent://prop/use/expiry-check/topic1";
final String subName = "sub1";
final int numMsgs = 10;
Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscribe();
PersistentTopic topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(topicName);
PersistentSubscription subRef = topicRef.getSubscription(subName);
consumer.close();
assertFalse(subRef.getDispatcher().isConsumerConnected());
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).create();
for (int i = 0; i < numMsgs; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
}
rolloverPerIntervalStats();
assertEquals(subRef.getNumberOfEntriesInBacklog(), numMsgs);
Thread.sleep(TimeUnit.SECONDS.toMillis(messageTTLSecs));
runMessageExpiryCheck();
// 1. check all messages expired for this unconnected subscription
assertEquals(subRef.getNumberOfEntriesInBacklog(), 0);
// clean-up
producer.close();
consumer.close();
admin.persistentTopics().deleteSubscription(topicName, subName);
admin.persistentTopics().delete(topicName);
admin.namespaces().deleteNamespace(namespaceName);
}
Aggregations