use of org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer in project incubator-pulsar by apache.
the class PersistentTopicTest method testDispatcherSingleConsumerReadFailed.
@Test
public void testDispatcherSingleConsumerReadFailed() throws Exception {
PersistentTopic topic = spy(new PersistentTopic(successTopicName, ledgerMock, brokerService));
ManagedCursor cursor = mock(ManagedCursor.class);
when(cursor.getName()).thenReturn("cursor");
PersistentDispatcherSingleActiveConsumer dispatcher = new PersistentDispatcherSingleActiveConsumer(cursor, SubType.Exclusive, 1, topic);
Consumer consumer = mock(Consumer.class);
dispatcher.readEntriesFailed(new ManagedLedgerException.InvalidCursorPositionException("failed"), consumer);
verify(topic, atLeast(1)).getBrokerService();
}
use of org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer in project incubator-pulsar by apache.
the class PersistentDispatcherFailoverConsumerTest method testAddRemoveConsumer.
@Test
public void testAddRemoveConsumer() throws Exception {
log.info("--- Starting PersistentDispatcherFailoverConsumerTest::testAddConsumer ---");
PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
PersistentSubscription sub = new PersistentSubscription(topic, "sub-1", cursorMock);
int partitionIndex = 0;
PersistentDispatcherSingleActiveConsumer pdfc = new PersistentDispatcherSingleActiveConsumer(cursorMock, SubType.Failover, partitionIndex, topic);
// 1. Verify no consumers connected
assertFalse(pdfc.isConsumerConnected());
// 2. Add consumer
Consumer consumer1 = spy(new Consumer(sub, SubType.Exclusive, topic.getName(), 1, /* consumer id */
0, "Cons1", /* consumer name */
50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
InitialPosition.Latest));
pdfc.addConsumer(consumer1);
List<Consumer> consumers = pdfc.getConsumers();
assertTrue(consumers.get(0).consumerName() == consumer1.consumerName());
assertEquals(1, consumers.size());
CommandActiveConsumerChange change = consumerChanges.take();
verifyActiveConsumerChange(change, 1, true);
verify(consumer1, times(1)).notifyActiveConsumerChange(same(consumer1));
// 3. Add again, duplicate allowed
pdfc.addConsumer(consumer1);
consumers = pdfc.getConsumers();
assertTrue(consumers.get(0).consumerName() == consumer1.consumerName());
assertEquals(2, consumers.size());
// 4. Verify active consumer
assertTrue(pdfc.getActiveConsumer().consumerName() == consumer1.consumerName());
// get the notified with who is the leader
change = consumerChanges.take();
verifyActiveConsumerChange(change, 1, true);
verify(consumer1, times(2)).notifyActiveConsumerChange(same(consumer1));
// 5. Add another consumer which does not change active consumer
Consumer consumer2 = spy(new Consumer(sub, SubType.Exclusive, topic.getName(), 2, /* consumer id */
0, "Cons2", /* consumer name */
50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
InitialPosition.Latest));
pdfc.addConsumer(consumer2);
consumers = pdfc.getConsumers();
assertTrue(pdfc.getActiveConsumer().consumerName() == consumer1.consumerName());
assertEquals(3, consumers.size());
// get notified with who is the leader
change = consumerChanges.take();
verifyActiveConsumerChange(change, 2, false);
verify(consumer1, times(2)).notifyActiveConsumerChange(same(consumer1));
verify(consumer2, times(1)).notifyActiveConsumerChange(same(consumer1));
// 6. Add a consumer which changes active consumer
Consumer consumer0 = spy(new Consumer(sub, SubType.Exclusive, topic.getName(), 0, /* consumer id */
0, "Cons0", /* consumer name */
50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
InitialPosition.Latest));
pdfc.addConsumer(consumer0);
consumers = pdfc.getConsumers();
assertTrue(pdfc.getActiveConsumer().consumerName() == consumer0.consumerName());
assertEquals(4, consumers.size());
// all consumers will receive notifications
change = consumerChanges.take();
verifyActiveConsumerChange(change, 0, true);
change = consumerChanges.take();
verifyActiveConsumerChange(change, 1, false);
change = consumerChanges.take();
verifyActiveConsumerChange(change, 1, false);
change = consumerChanges.take();
verifyActiveConsumerChange(change, 2, false);
verify(consumer0, times(1)).notifyActiveConsumerChange(same(consumer0));
verify(consumer1, times(2)).notifyActiveConsumerChange(same(consumer1));
verify(consumer1, times(2)).notifyActiveConsumerChange(same(consumer0));
verify(consumer2, times(1)).notifyActiveConsumerChange(same(consumer1));
verify(consumer2, times(1)).notifyActiveConsumerChange(same(consumer0));
// 7. Remove last consumer
pdfc.removeConsumer(consumer2);
consumers = pdfc.getConsumers();
assertTrue(pdfc.getActiveConsumer().consumerName() == consumer0.consumerName());
assertEquals(3, consumers.size());
// not consumer group changes
assertNull(consumerChanges.poll());
// 8. Verify if we cannot unsubscribe when more than one consumer is connected
assertFalse(pdfc.canUnsubscribe(consumer0));
// 9. Remove active consumer
pdfc.removeConsumer(consumer0);
consumers = pdfc.getConsumers();
assertTrue(pdfc.getActiveConsumer().consumerName() == consumer1.consumerName());
assertEquals(2, consumers.size());
// the remaining consumers will receive notifications
change = consumerChanges.take();
verifyActiveConsumerChange(change, 1, true);
change = consumerChanges.take();
verifyActiveConsumerChange(change, 1, true);
// 10. Attempt to remove already removed consumer
String cause = "";
try {
pdfc.removeConsumer(consumer0);
} catch (Exception e) {
cause = e.getMessage();
}
assertEquals(cause, "Consumer was not connected");
// 11. Remove active consumer
pdfc.removeConsumer(consumer1);
consumers = pdfc.getConsumers();
assertTrue(pdfc.getActiveConsumer().consumerName() == consumer1.consumerName());
assertEquals(1, consumers.size());
// not consumer group changes
assertNull(consumerChanges.poll());
// 11. With only one consumer, unsubscribe is allowed
assertTrue(pdfc.canUnsubscribe(consumer1));
}
use of org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer in project incubator-pulsar by apache.
the class PersistentFailoverE2ETest method testSimpleConsumerEventsWithPartition.
@Test
public void testSimpleConsumerEventsWithPartition() throws Exception {
int numPartitions = 4;
final String topicName = "persistent://prop/use/ns-abc/failover-topic2";
final TopicName destName = TopicName.get(topicName);
final String subName = "sub1";
final int numMsgs = 100;
Set<String> uniqueMessages = new HashSet<>();
admin.persistentTopics().createPartitionedTopic(topicName, numPartitions);
ConsumerBuilder<byte[]> consumerBuilder = pulsarClient.newConsumer().topic(topicName).subscriptionName(subName).subscriptionType(SubscriptionType.Failover);
// 1. two consumers on the same subscription
ActiveInactiveListenerEvent listener1 = new ActiveInactiveListenerEvent();
ActiveInactiveListenerEvent listener2 = new ActiveInactiveListenerEvent();
Consumer<byte[]> consumer1 = consumerBuilder.clone().consumerName("1").consumerEventListener(listener1).subscribe();
Consumer<byte[]> consumer2 = consumerBuilder.clone().consumerName("2").consumerEventListener(listener2).subscribe();
PersistentTopic topicRef;
topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(0).toString());
PersistentDispatcherSingleActiveConsumer disp0 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(1).toString());
PersistentDispatcherSingleActiveConsumer disp1 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(2).toString());
PersistentDispatcherSingleActiveConsumer disp2 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
topicRef = (PersistentTopic) pulsar.getBrokerService().getTopicReference(destName.getPartition(3).toString());
PersistentDispatcherSingleActiveConsumer disp3 = (PersistentDispatcherSingleActiveConsumer) topicRef.getSubscription(subName).getDispatcher();
List<CompletableFuture<MessageId>> futures = Lists.newArrayListWithCapacity(numMsgs);
Producer<byte[]> producer = pulsarClient.newProducer().topic(topicName).messageRoutingMode(MessageRoutingMode.RoundRobinPartition).create();
for (int i = 0; i < numMsgs; i++) {
String message = "my-message-" + i;
futures.add(producer.sendAsync(message.getBytes()));
}
FutureUtil.waitForAll(futures).get();
futures.clear();
// equal distribution between both consumers
int totalMessages = 0;
Message<byte[]> msg = null;
Set<Integer> receivedPtns = Sets.newHashSet();
while (true) {
msg = consumer1.receive(1, TimeUnit.SECONDS);
if (msg == null) {
break;
}
totalMessages++;
consumer1.acknowledge(msg);
MessageIdImpl msgId = (MessageIdImpl) msg.getMessageId();
receivedPtns.add(msgId.getPartitionIndex());
}
assertTrue(Sets.difference(listener1.activePtns, receivedPtns).isEmpty());
assertTrue(Sets.difference(listener2.inactivePtns, receivedPtns).isEmpty());
Assert.assertEquals(totalMessages, numMsgs / 2);
receivedPtns = Sets.newHashSet();
while (true) {
msg = consumer2.receive(1, TimeUnit.SECONDS);
if (msg == null) {
break;
}
totalMessages++;
consumer2.acknowledge(msg);
MessageIdImpl msgId = (MessageIdImpl) msg.getMessageId();
receivedPtns.add(msgId.getPartitionIndex());
}
assertTrue(Sets.difference(listener1.inactivePtns, receivedPtns).isEmpty());
assertTrue(Sets.difference(listener2.activePtns, receivedPtns).isEmpty());
Assert.assertEquals(totalMessages, numMsgs);
Assert.assertEquals(disp0.getActiveConsumer().consumerName(), "1");
Assert.assertEquals(disp1.getActiveConsumer().consumerName(), "2");
Assert.assertEquals(disp2.getActiveConsumer().consumerName(), "1");
Assert.assertEquals(disp3.getActiveConsumer().consumerName(), "2");
totalMessages = 0;
for (int i = 0; i < numMsgs; i++) {
String message = "my-message-" + i;
futures.add(producer.sendAsync(message.getBytes()));
}
FutureUtil.waitForAll(futures).get();
futures.clear();
// add a consumer
for (int i = 0; i < 20; i++) {
msg = consumer1.receive(1, TimeUnit.SECONDS);
Assert.assertNotNull(msg);
uniqueMessages.add(new String(msg.getData()));
consumer1.acknowledge(msg);
}
Consumer<byte[]> consumer3 = consumerBuilder.clone().consumerName("3").subscribe();
Thread.sleep(CONSUMER_ADD_OR_REMOVE_WAIT_TIME);
int consumer1Messages = 0;
while (true) {
msg = consumer1.receive(1, TimeUnit.SECONDS);
if (msg == null) {
Assert.assertEquals(consumer1Messages, 55);
break;
}
consumer1Messages++;
uniqueMessages.add(new String(msg.getData()));
consumer1.acknowledge(msg);
}
int consumer2Messages = 0;
while (true) {
msg = consumer2.receive(1, TimeUnit.SECONDS);
if (msg == null) {
Assert.assertEquals(consumer2Messages, 50);
break;
}
consumer2Messages++;
uniqueMessages.add(new String(msg.getData()));
consumer2.acknowledge(msg);
}
int consumer3Messages = 0;
while (true) {
msg = consumer3.receive(1, TimeUnit.SECONDS);
if (msg == null) {
Assert.assertEquals(consumer3Messages, 15, 10);
break;
}
consumer3Messages++;
uniqueMessages.add(new String(msg.getData()));
consumer3.acknowledge(msg);
}
Assert.assertEquals(uniqueMessages.size(), numMsgs);
Assert.assertEquals(disp0.getActiveConsumer().consumerName(), "1");
Assert.assertEquals(disp1.getActiveConsumer().consumerName(), "2");
Assert.assertEquals(disp2.getActiveConsumer().consumerName(), "3");
Assert.assertEquals(disp3.getActiveConsumer().consumerName(), "1");
uniqueMessages.clear();
for (int i = 0; i < numMsgs; i++) {
String message = "my-message-" + i;
futures.add(producer.sendAsync(message.getBytes()));
}
FutureUtil.waitForAll(futures).get();
futures.clear();
// remove a consumer
for (int i = 0; i < 10; i++) {
msg = consumer1.receive(1, TimeUnit.SECONDS);
Assert.assertNotNull(msg);
uniqueMessages.add(new String(msg.getData()));
consumer1.acknowledge(msg);
}
consumer1.close();
Thread.sleep(CONSUMER_ADD_OR_REMOVE_WAIT_TIME);
consumer2Messages = 0;
while (true) {
msg = consumer2.receive(1, TimeUnit.SECONDS);
if (msg == null) {
Assert.assertEquals(consumer2Messages, 70, 5);
break;
}
consumer2Messages++;
uniqueMessages.add(new String(msg.getData()));
consumer2.acknowledge(msg);
}
consumer3Messages = 0;
while (true) {
msg = consumer3.receive(1, TimeUnit.SECONDS);
if (msg == null) {
Assert.assertEquals(consumer3Messages, 70, 5);
break;
}
consumer3Messages++;
uniqueMessages.add(new String(msg.getData()));
consumer3.acknowledge(msg);
}
Assert.assertEquals(uniqueMessages.size(), numMsgs);
Assert.assertEquals(disp0.getActiveConsumer().consumerName(), "2");
Assert.assertEquals(disp1.getActiveConsumer().consumerName(), "3");
Assert.assertEquals(disp2.getActiveConsumer().consumerName(), "2");
Assert.assertEquals(disp3.getActiveConsumer().consumerName(), "3");
producer.close();
consumer2.close();
consumer3.unsubscribe();
admin.persistentTopics().deletePartitionedTopic(topicName);
}
use of org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer in project incubator-pulsar by apache.
the class PersistentDispatcherFailoverConsumerTest method testConsumerGroupChangesWithOldNewConsumers.
@Test
public void testConsumerGroupChangesWithOldNewConsumers() throws Exception {
PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
PersistentSubscription sub = new PersistentSubscription(topic, "sub-1", cursorMock);
int partitionIndex = 0;
PersistentDispatcherSingleActiveConsumer pdfc = new PersistentDispatcherSingleActiveConsumer(cursorMock, SubType.Failover, partitionIndex, topic);
// 1. Verify no consumers connected
assertFalse(pdfc.isConsumerConnected());
// 2. Add old consumer
Consumer consumer1 = new Consumer(sub, SubType.Exclusive, topic.getName(), 1, /* consumer id */
0, "Cons1", /* consumer name */
50000, serverCnxWithOldVersion, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest);
pdfc.addConsumer(consumer1);
List<Consumer> consumers = pdfc.getConsumers();
assertTrue(consumers.get(0).consumerName() == consumer1.consumerName());
assertEquals(1, consumers.size());
assertNull(consumerChanges.poll());
verify(channelCtx, times(0)).write(any());
// 3. Add new consumer
Consumer consumer2 = new Consumer(sub, SubType.Exclusive, topic.getName(), 2, /* consumer id */
0, "Cons2", /* consumer name */
50000, serverCnx, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest);
pdfc.addConsumer(consumer2);
consumers = pdfc.getConsumers();
assertTrue(consumers.get(0).consumerName() == consumer1.consumerName());
assertEquals(2, consumers.size());
CommandActiveConsumerChange change = consumerChanges.take();
verifyActiveConsumerChange(change, 2, false);
verify(channelCtx, times(1)).writeAndFlush(any(), any());
}
Aggregations