Search in sources :

Example 6 with PersistentSubscription

use of org.apache.pulsar.broker.service.persistent.PersistentSubscription in project incubator-pulsar by apache.

the class PersistentTopicTest method testConcurrentTopicAndSubscriptionDelete.

// @Test
public void testConcurrentTopicAndSubscriptionDelete() throws Exception {
    // create topic
    final PersistentTopic topic = (PersistentTopic) brokerService.getTopic(successTopicName).get();
    CommandSubscribe cmd = CommandSubscribe.newBuilder().setConsumerId(1).setTopic(successTopicName).setSubscription(successSubName).setRequestId(1).setSubType(SubType.Exclusive).build();
    Future<Consumer> f1 = topic.subscribe(serverCnx, cmd.getSubscription(), cmd.getConsumerId(), cmd.getSubType(), 0, cmd.getConsumerName(), cmd.getDurable(), null, Collections.emptyMap(), cmd.getReadCompacted(), InitialPosition.Latest);
    f1.get();
    final CyclicBarrier barrier = new CyclicBarrier(2);
    final CountDownLatch counter = new CountDownLatch(2);
    final AtomicBoolean gotException = new AtomicBoolean(false);
    Thread deleter = new Thread() {

        @Override
        public void run() {
            try {
                barrier.await();
                // assertTrue(topic.unsubscribe(successSubName).isDone());
                Thread.sleep(5, 0);
                log.info("deleter outcome is {}", topic.delete().get());
            } catch (Exception e) {
                e.printStackTrace();
                gotException.set(true);
            } finally {
                counter.countDown();
            }
        }
    };
    Thread unsubscriber = new Thread() {

        @Override
        public void run() {
            try {
                barrier.await();
                // do subscription delete
                ConcurrentOpenHashMap<String, PersistentSubscription> subscriptions = topic.getSubscriptions();
                PersistentSubscription ps = subscriptions.get(successSubName);
                // Thread.sleep(5,0);
                log.info("unsubscriber outcome is {}", ps.doUnsubscribe(ps.getConsumers().get(0)).get());
            // assertFalse(ps.delete().isCompletedExceptionally());
            } catch (Exception e) {
                e.printStackTrace();
                gotException.set(true);
            } finally {
                counter.countDown();
            }
        }
    };
    deleter.start();
    unsubscriber.start();
    counter.await();
    assertEquals(gotException.get(), false);
}
Also used : CommandSubscribe(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyString(org.mockito.Matchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) TimeoutException(java.util.concurrent.TimeoutException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) ExecutionException(java.util.concurrent.ExecutionException) CyclicBarrier(java.util.concurrent.CyclicBarrier)

Example 7 with PersistentSubscription

use of org.apache.pulsar.broker.service.persistent.PersistentSubscription in project incubator-pulsar by apache.

the class PersistentTopicTest method testMaxConsumersShared.

public void testMaxConsumersShared() throws Exception {
    PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
    PersistentSubscription sub = new PersistentSubscription(topic, "sub-1", cursorMock);
    PersistentSubscription sub2 = new PersistentSubscription(topic, "sub-2", cursorMock);
    // for count consumers on topic
    ConcurrentOpenHashMap<String, PersistentSubscription> subscriptions = new ConcurrentOpenHashMap<>(16, 1);
    subscriptions.put("sub-1", sub);
    subscriptions.put("sub-2", sub2);
    Field field = topic.getClass().getDeclaredField("subscriptions");
    field.setAccessible(true);
    field.set(topic, subscriptions);
    // 1. add consumer1
    Consumer consumer = new Consumer(sub, SubType.Shared, topic.getName(), 1, /* consumer id */
    0, "Cons1", /* consumer name */
    50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
    InitialPosition.Latest);
    sub.addConsumer(consumer);
    assertEquals(sub.getConsumers().size(), 1);
    // 2. add consumer2
    Consumer consumer2 = new Consumer(sub, SubType.Shared, topic.getName(), 2, /* consumer id */
    0, "Cons2", /* consumer name */
    50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
    InitialPosition.Latest);
    sub.addConsumer(consumer2);
    assertEquals(sub.getConsumers().size(), 2);
    // 3. add consumer3 but reach maxConsumersPerSubscription
    try {
        Consumer consumer3 = new Consumer(sub, SubType.Shared, topic.getName(), 3, /* consumer id */
        0, "Cons3", /* consumer name */
        50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
        InitialPosition.Latest);
        sub.addConsumer(consumer3);
        fail("should have failed");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.ConsumerBusyException);
    }
    // check number of consumers on topic
    assertEquals(topic.getNumberOfConsumers(), 2);
    // 4. add consumer4 to sub2
    Consumer consumer4 = new Consumer(sub2, SubType.Shared, topic.getName(), 4, /* consumer id */
    0, "Cons4", /* consumer name */
    50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
    InitialPosition.Latest);
    sub2.addConsumer(consumer4);
    assertEquals(sub2.getConsumers().size(), 1);
    // check number of consumers on topic
    assertEquals(topic.getNumberOfConsumers(), 3);
    // 5. add consumer5 to sub2 but reach maxConsumersPerTopic
    try {
        Consumer consumer5 = new Consumer(sub2, SubType.Shared, topic.getName(), 5, /* consumer id */
        0, "Cons5", /* consumer name */
        50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
        InitialPosition.Latest);
        sub2.addConsumer(consumer5);
        fail("should have failed");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.ConsumerBusyException);
    }
}
Also used : Field(java.lang.reflect.Field) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyString(org.mockito.Matchers.anyString) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription)

Example 8 with PersistentSubscription

use of org.apache.pulsar.broker.service.persistent.PersistentSubscription in project incubator-pulsar by apache.

the class PersistentTopicTest method testMaxConsumersFailover.

public void testMaxConsumersFailover() throws Exception {
    PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
    PersistentSubscription sub = new PersistentSubscription(topic, "sub-1", cursorMock);
    PersistentSubscription sub2 = new PersistentSubscription(topic, "sub-2", cursorMock);
    // for count consumers on topic
    ConcurrentOpenHashMap<String, PersistentSubscription> subscriptions = new ConcurrentOpenHashMap<>(16, 1);
    subscriptions.put("sub-1", sub);
    subscriptions.put("sub-2", sub2);
    Field field = topic.getClass().getDeclaredField("subscriptions");
    field.setAccessible(true);
    field.set(topic, subscriptions);
    // 1. add consumer1
    Consumer consumer = new Consumer(sub, SubType.Failover, topic.getName(), 1, /* consumer id */
    0, "Cons1", /* consumer name */
    50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
    InitialPosition.Latest);
    sub.addConsumer(consumer);
    assertEquals(sub.getConsumers().size(), 1);
    // 2. add consumer2
    Consumer consumer2 = new Consumer(sub, SubType.Failover, topic.getName(), 2, /* consumer id */
    0, "Cons2", /* consumer name */
    50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
    InitialPosition.Latest);
    sub.addConsumer(consumer2);
    assertEquals(sub.getConsumers().size(), 2);
    // 3. add consumer3 but reach maxConsumersPerSubscription
    try {
        Consumer consumer3 = new Consumer(sub, SubType.Failover, topic.getName(), 3, /* consumer id */
        0, "Cons3", /* consumer name */
        50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
        InitialPosition.Latest);
        sub.addConsumer(consumer3);
        fail("should have failed");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.ConsumerBusyException);
    }
    // check number of consumers on topic
    assertEquals(topic.getNumberOfConsumers(), 2);
    // 4. add consumer4 to sub2
    Consumer consumer4 = new Consumer(sub2, SubType.Failover, topic.getName(), 4, /* consumer id */
    0, "Cons4", /* consumer name */
    50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
    InitialPosition.Latest);
    sub2.addConsumer(consumer4);
    assertEquals(sub2.getConsumers().size(), 1);
    // check number of consumers on topic
    assertEquals(topic.getNumberOfConsumers(), 3);
    // 5. add consumer5 to sub2 but reach maxConsumersPerTopic
    try {
        Consumer consumer5 = new Consumer(sub2, SubType.Failover, topic.getName(), 5, /* consumer id */
        0, "Cons5", /* consumer name */
        50000, serverCnx, "myrole-1", Collections.emptyMap(), false, /* read compacted */
        InitialPosition.Latest);
        sub2.addConsumer(consumer5);
        fail("should have failed");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.ConsumerBusyException);
    }
}
Also used : Field(java.lang.reflect.Field) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyString(org.mockito.Matchers.anyString) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription)

Example 9 with PersistentSubscription

use of org.apache.pulsar.broker.service.persistent.PersistentSubscription in project incubator-pulsar by apache.

the class PersistentTopicTest method testUbsubscribeRaceConditions.

@Test
public void testUbsubscribeRaceConditions() throws Exception {
    PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
    PersistentSubscription sub = new PersistentSubscription(topic, "sub-1", cursorMock);
    Consumer consumer1 = 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);
    sub.addConsumer(consumer1);
    doAnswer(new Answer<Object>() {

        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            ((DeleteCursorCallback) invocationOnMock.getArguments()[1]).deleteCursorComplete(null);
            Thread.sleep(1000);
            return null;
        }
    }).when(ledgerMock).asyncDeleteCursor(matches(".*success.*"), any(DeleteCursorCallback.class), anyObject());
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.submit(() -> {
        sub.doUnsubscribe(consumer1);
        return null;
    }).get();
    try {
        Thread.sleep(10);
        /* delay to ensure that the ubsubscribe gets executed first */
        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);
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.SubscriptionFencedException);
    }
}
Also used : PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) ExecutorService(java.util.concurrent.ExecutorService) Matchers.anyObject(org.mockito.Matchers.anyObject) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Test(org.testng.annotations.Test)

Example 10 with PersistentSubscription

use of org.apache.pulsar.broker.service.persistent.PersistentSubscription 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)

Aggregations

PersistentSubscription (org.apache.pulsar.broker.service.persistent.PersistentSubscription)34 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)34 Test (org.testng.annotations.Test)20 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)13 ExecutionException (java.util.concurrent.ExecutionException)9 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)9 PersistentDispatcherSingleActiveConsumer (org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer)9 PulsarAdminException (org.apache.pulsar.client.admin.PulsarAdminException)9 IOException (java.io.IOException)7 WebApplicationException (javax.ws.rs.WebApplicationException)7 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)7 NotAllowedException (org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException)7 SubscriptionBusyException (org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)7 TopicBusyException (org.apache.pulsar.broker.service.BrokerServiceException.TopicBusyException)7 RestException (org.apache.pulsar.broker.web.RestException)7 NotFoundException (org.apache.pulsar.client.admin.PulsarAdminException.NotFoundException)7 PreconditionFailedException (org.apache.pulsar.client.admin.PulsarAdminException.PreconditionFailedException)7 PartitionedTopicMetadata (org.apache.pulsar.common.partition.PartitionedTopicMetadata)7 KeeperException (org.apache.zookeeper.KeeperException)7 CountDownLatch (java.util.concurrent.CountDownLatch)6