Search in sources :

Example 1 with PersistentDispatcherSingleActiveConsumer

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();
}
Also used : ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) Test(org.testng.annotations.Test)

Example 2 with PersistentDispatcherSingleActiveConsumer

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));
}
Also used : CommandActiveConsumerChange(org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Test(org.testng.annotations.Test)

Example 3 with PersistentDispatcherSingleActiveConsumer

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);
}
Also used : MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) TopicName(org.apache.pulsar.common.naming.TopicName) CompletableFuture(java.util.concurrent.CompletableFuture) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 4 with PersistentDispatcherSingleActiveConsumer

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());
}
Also used : CommandActiveConsumerChange(org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) Test(org.testng.annotations.Test)

Aggregations

PersistentDispatcherSingleActiveConsumer (org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer)4 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)4 Test (org.testng.annotations.Test)4 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)2 PersistentSubscription (org.apache.pulsar.broker.service.persistent.PersistentSubscription)2 CommandActiveConsumerChange (org.apache.pulsar.common.api.proto.PulsarApi.CommandActiveConsumerChange)2 HashSet (java.util.HashSet)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ManagedCursor (org.apache.bookkeeper.mledger.ManagedCursor)1 MessageIdImpl (org.apache.pulsar.client.impl.MessageIdImpl)1 TopicName (org.apache.pulsar.common.naming.TopicName)1