Search in sources :

Example 96 with ManagedCursor

use of org.apache.bookkeeper.mledger.ManagedCursor in project pulsar by yahoo.

the class PersistentTopicTest method testAtomicReplicationRemoval.

/**
     * {@link PersistentReplicator.removeReplicator} doesn't remove replicator in atomic way and does in multiple step:
     * 1. disconnect replicator producer
     * <p>
     * 2. close cursor
     * <p>
     * 3. remove from replicator-list.
     * <p>
     * 
     * If we try to startReplicationProducer before step-c finish then it should not avoid restarting repl-producer.
     * 
     * @throws Exception
     */
@Test
public void testAtomicReplicationRemoval() throws Exception {
    final String globalTopicName = "persistent://prop/global/ns-abc/successTopic";
    String localCluster = "local";
    String remoteCluster = "remote";
    final ManagedLedger ledgerMock = mock(ManagedLedger.class);
    doNothing().when(ledgerMock).asyncDeleteCursor(anyObject(), anyObject(), anyObject());
    doReturn(new ArrayList<Object>()).when(ledgerMock).getCursors();
    PersistentTopic topic = new PersistentTopic(globalTopicName, ledgerMock, brokerService);
    String remoteReplicatorName = topic.replicatorPrefix + "." + remoteCluster;
    ConcurrentOpenHashMap<String, PersistentReplicator> replicatorMap = topic.getReplicators();
    final URL brokerUrl = new URL("http://" + pulsar.getAdvertisedAddress() + ":" + pulsar.getConfiguration().getBrokerServicePort());
    PulsarClient client = PulsarClient.create(brokerUrl.toString());
    ManagedCursor cursor = mock(ManagedCursorImpl.class);
    doReturn(remoteCluster).when(cursor).getName();
    brokerService.getReplicationClients().put(remoteCluster, client);
    PersistentReplicator replicator = spy(new PersistentReplicator(topic, cursor, localCluster, remoteCluster, brokerService));
    replicatorMap.put(remoteReplicatorName, replicator);
    // step-1 remove replicator : it will disconnect the producer but it will wait for callback to be completed
    Method removeMethod = PersistentTopic.class.getDeclaredMethod("removeReplicator", String.class);
    removeMethod.setAccessible(true);
    removeMethod.invoke(topic, remoteReplicatorName);
    // step-2 now, policies doesn't have removed replication cluster so, it should not invoke "startProducer" of the
    // replicator
    when(pulsar.getConfigurationCache().policiesCache().get(AdminResource.path("policies", DestinationName.get(globalTopicName).getNamespace()))).thenReturn(Optional.of(new Policies()));
    // try to start replicator again
    topic.startReplProducers();
    // verify: replicator.startProducer is not invoked
    verify(replicator, Mockito.times(0)).startProducer();
    // step-3 : complete the callback to remove replicator from the list
    ArgumentCaptor<DeleteCursorCallback> captor = ArgumentCaptor.forClass(DeleteCursorCallback.class);
    Mockito.verify(ledgerMock).asyncDeleteCursor(anyObject(), captor.capture(), anyObject());
    DeleteCursorCallback callback = captor.getValue();
    callback.deleteCursorComplete(null);
}
Also used : PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) Policies(com.yahoo.pulsar.common.policies.data.Policies) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) Matchers.anyString(org.mockito.Matchers.anyString) AfterMethod(org.testng.annotations.AfterMethod) Method(java.lang.reflect.Method) BeforeMethod(org.testng.annotations.BeforeMethod) URL(java.net.URL) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyObject(org.mockito.Matchers.anyObject) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback) PulsarClient(com.yahoo.pulsar.client.api.PulsarClient) Test(org.testng.annotations.Test)

Example 97 with ManagedCursor

use of org.apache.bookkeeper.mledger.ManagedCursor in project pulsar by yahoo.

the class PersistentTopicTest method testClosingReplicationProducerTwice.

@Test
public void testClosingReplicationProducerTwice() throws Exception {
    final String globalTopicName = "persistent://prop/global/ns/testClosingReplicationProducerTwice";
    String localCluster = "local";
    String remoteCluster = "remote";
    final ManagedLedger ledgerMock = mock(ManagedLedger.class);
    doNothing().when(ledgerMock).asyncDeleteCursor(anyObject(), anyObject(), anyObject());
    doReturn(new ArrayList<Object>()).when(ledgerMock).getCursors();
    PersistentTopic topic = new PersistentTopic(globalTopicName, ledgerMock, brokerService);
    String remoteReplicatorName = topic.replicatorPrefix + "." + localCluster;
    final URL brokerUrl = new URL("http://" + pulsar.getAdvertisedAddress() + ":" + pulsar.getConfiguration().getBrokerServicePort());
    PulsarClient client = spy(PulsarClient.create(brokerUrl.toString()));
    PulsarClientImpl clientImpl = (PulsarClientImpl) client;
    Field conf = PersistentReplicator.class.getDeclaredField("producerConfiguration");
    conf.setAccessible(true);
    ManagedCursor cursor = mock(ManagedCursorImpl.class);
    doReturn(remoteCluster).when(cursor).getName();
    brokerService.getReplicationClients().put(remoteCluster, client);
    PersistentReplicator replicator = new PersistentReplicator(topic, cursor, localCluster, remoteCluster, brokerService);
    doReturn(new CompletableFuture<Producer>()).when(clientImpl).createProducerAsync(globalTopicName, (ProducerConfiguration) conf.get(replicator), remoteReplicatorName);
    replicator.startProducer();
    verify(clientImpl).createProducerAsync(globalTopicName, (ProducerConfiguration) conf.get(replicator), remoteReplicatorName);
    replicator.disconnect(false);
    replicator.disconnect(false);
    replicator.startProducer();
    verify(clientImpl, Mockito.times(2)).createProducerAsync(globalTopicName, (ProducerConfiguration) conf.get(replicator), remoteReplicatorName);
}
Also used : PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) Matchers.anyString(org.mockito.Matchers.anyString) URL(java.net.URL) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) Field(java.lang.reflect.Field) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyObject(org.mockito.Matchers.anyObject) PulsarClient(com.yahoo.pulsar.client.api.PulsarClient) PulsarClientImpl(com.yahoo.pulsar.client.impl.PulsarClientImpl) Test(org.testng.annotations.Test)

Example 98 with ManagedCursor

use of org.apache.bookkeeper.mledger.ManagedCursor in project pulsar by yahoo.

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(com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) PersistentDispatcherSingleActiveConsumer(com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) Test(org.testng.annotations.Test)

Example 99 with ManagedCursor

use of org.apache.bookkeeper.mledger.ManagedCursor in project pulsar by yahoo.

the class PersistentTopic method subscribe.

@Override
public CompletableFuture<Consumer> subscribe(final ServerCnx cnx, String subscriptionName, long consumerId, SubType subType, int priorityLevel, String consumerName) {
    final CompletableFuture<Consumer> future = new CompletableFuture<>();
    if (hasBatchMessagePublished && !cnx.isBatchMessageCompatibleVersion()) {
        if (log.isDebugEnabled()) {
            log.debug("[{}] Consumer doesn't support batch-message {}", topic, subscriptionName);
        }
        future.completeExceptionally(new UnsupportedVersionException("Consumer doesn't support batch-message"));
        return future;
    }
    if (subscriptionName.startsWith(replicatorPrefix)) {
        log.warn("[{}] Failed to create subscription for {}", topic, subscriptionName);
        future.completeExceptionally(new NamingException("Subscription with reserved subscription name attempted"));
        return future;
    }
    lock.readLock().lock();
    try {
        if (isFenced) {
            log.warn("[{}] Attempting to subscribe to a fenced topic", topic);
            future.completeExceptionally(new TopicFencedException("Topic is temporarily unavailable"));
            return future;
        }
        USAGE_COUNT_UPDATER.incrementAndGet(this);
        if (log.isDebugEnabled()) {
            log.debug("[{}] [{}] [{}] Added consumer -- count: {}", topic, subscriptionName, consumerName, USAGE_COUNT_UPDATER.get(this));
        }
    } finally {
        lock.readLock().unlock();
    }
    ledger.asyncOpenCursor(Codec.encode(subscriptionName), new OpenCursorCallback() {

        @Override
        public void openCursorComplete(ManagedCursor cursor, Object ctx) {
            if (log.isDebugEnabled()) {
                log.debug("[{}][{}] Opened cursor for {} {}", topic, subscriptionName, consumerId, consumerName);
            }
            try {
                PersistentSubscription subscription = subscriptions.computeIfAbsent(subscriptionName, name -> new PersistentSubscription(PersistentTopic.this, cursor));
                Consumer consumer = new Consumer(subscription, subType, consumerId, priorityLevel, consumerName, brokerService.pulsar().getConfiguration().getMaxUnackedMessagesPerConsumer(), cnx, cnx.getRole());
                subscription.addConsumer(consumer);
                if (!cnx.isActive()) {
                    consumer.close();
                    if (log.isDebugEnabled()) {
                        log.debug("[{}] [{}] [{}] Subscribe failed -- count: {}", topic, subscriptionName, consumer.consumerName(), USAGE_COUNT_UPDATER.get(PersistentTopic.this));
                    }
                    future.completeExceptionally(new BrokerServiceException("Connection was closed while the opening the cursor "));
                } else {
                    log.info("[{}][{}] Created new subscription for {}", topic, subscriptionName, consumerId);
                    future.complete(consumer);
                }
            } catch (BrokerServiceException e) {
                if (e instanceof ConsumerBusyException) {
                    log.warn("[{}][{}] Consumer {} {} already connected", topic, subscriptionName, consumerId, consumerName);
                } else if (e instanceof SubscriptionBusyException) {
                    log.warn("[{}][{}] {}", topic, subscriptionName, e.getMessage());
                }
                USAGE_COUNT_UPDATER.decrementAndGet(PersistentTopic.this);
                future.completeExceptionally(e);
            }
        }

        @Override
        public void openCursorFailed(ManagedLedgerException exception, Object ctx) {
            log.warn("[{}] Failed to create subscription for {}", topic, subscriptionName);
            USAGE_COUNT_UPDATER.decrementAndGet(PersistentTopic.this);
            future.completeExceptionally(new PersistenceException(exception));
        }
    }, null);
    return future;
}
Also used : ReplicationMetrics(com.yahoo.pulsar.broker.stats.ReplicationMetrics) SubType(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType) PersistentSubscriptionStats(com.yahoo.pulsar.common.policies.data.PersistentSubscriptionStats) LedgerInfo(com.yahoo.pulsar.common.policies.data.PersistentTopicInternalStats.LedgerInfo) NamingException(com.yahoo.pulsar.broker.service.BrokerServiceException.NamingException) ConsumerStats(com.yahoo.pulsar.common.policies.data.ConsumerStats) CloseCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.CloseCallback) PersistentTopicInternalStats(com.yahoo.pulsar.common.policies.data.PersistentTopicInternalStats) LoggerFactory(org.slf4j.LoggerFactory) ObjectObjectHashMap(com.carrotsearch.hppc.ObjectObjectHashMap) NamespaceBundleStats(com.yahoo.pulsar.common.policies.data.loadbalancer.NamespaceBundleStats) Policies(com.yahoo.pulsar.common.policies.data.Policies) BacklogQuota(com.yahoo.pulsar.common.policies.data.BacklogQuota) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) OpenCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenCursorCallback) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) ReplicatorStats(com.yahoo.pulsar.common.policies.data.ReplicatorStats) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback) FutureUtil(com.yahoo.pulsar.client.util.FutureUtil) Objects(com.google.common.base.Objects) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) CursorStats(com.yahoo.pulsar.common.policies.data.PersistentTopicInternalStats.CursorStats) Set(java.util.Set) Position(org.apache.bookkeeper.mledger.Position) Instant(java.time.Instant) IndividualDeletedEntries(org.apache.bookkeeper.mledger.ManagedCursor.IndividualDeletedEntries) TopicFencedException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicFencedException) Lists(com.beust.jcommander.internal.Lists) ZoneId(java.time.ZoneId) Sets(com.google.common.collect.Sets) AddEntryCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback) BrokerService(com.yahoo.pulsar.broker.service.BrokerService) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Topic(com.yahoo.pulsar.broker.service.Topic) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) Consumer(com.yahoo.pulsar.broker.service.Consumer) List(java.util.List) ManagedLedgerFencedException(org.apache.bookkeeper.mledger.ManagedLedgerException.ManagedLedgerFencedException) AdminResource(com.yahoo.pulsar.broker.admin.AdminResource) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) StatsOutputStream(com.yahoo.pulsar.utils.StatsOutputStream) Entry(org.apache.bookkeeper.mledger.Entry) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) UnsupportedVersionException(com.yahoo.pulsar.broker.service.BrokerServiceException.UnsupportedVersionException) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) MessageImpl(com.yahoo.pulsar.client.impl.MessageImpl) PersistentTopicStats(com.yahoo.pulsar.common.policies.data.PersistentTopicStats) ServerCnx(com.yahoo.pulsar.broker.service.ServerCnx) ByteBuf(io.netty.buffer.ByteBuf) FastThreadLocal(io.netty.util.concurrent.FastThreadLocal) ConcurrentOpenHashSet(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashSet) ConsumerBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ConcurrentOpenHashMap(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashMap) Codec(com.yahoo.pulsar.common.util.Codec) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) ClusterReplicationMetrics(com.yahoo.pulsar.broker.stats.ClusterReplicationMetrics) Logger(org.slf4j.Logger) KeeperException(org.apache.zookeeper.KeeperException) BrokerServiceException(com.yahoo.pulsar.broker.service.BrokerServiceException) PublisherStats(com.yahoo.pulsar.common.policies.data.PublisherStats) Producer(com.yahoo.pulsar.broker.service.Producer) ServerMetadataException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServerMetadataException) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) NamespaceStats(com.yahoo.pulsar.broker.stats.NamespaceStats) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) DateTimeFormatter(java.time.format.DateTimeFormatter) Collections(java.util.Collections) TopicFencedException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicFencedException) BrokerServiceException(com.yahoo.pulsar.broker.service.BrokerServiceException) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) CompletableFuture(java.util.concurrent.CompletableFuture) OpenCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenCursorCallback) ConsumerBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Consumer(com.yahoo.pulsar.broker.service.Consumer) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) NamingException(com.yahoo.pulsar.broker.service.BrokerServiceException.NamingException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) UnsupportedVersionException(com.yahoo.pulsar.broker.service.BrokerServiceException.UnsupportedVersionException)

Example 100 with ManagedCursor

use of org.apache.bookkeeper.mledger.ManagedCursor in project pulsar by yahoo.

the class ReplicatorTest method testCloseReplicatorStartProducer.

/**
     * It verifies that PersistentReplicator considers CursorAlreadyClosedException as non-retriable-read exception and
     * it should closed the producer as cursor is already closed because replicator is already deleted.
     * 
     * @throws Exception
     */
@Test(timeOut = 5000)
public void testCloseReplicatorStartProducer() throws Exception {
    DestinationName dest = DestinationName.get("persistent://pulsar/global/ns1/closeCursor");
    // Producer on r1
    MessageProducer producer1 = new MessageProducer(url1, dest);
    // Consumer on r1
    MessageConsumer consumer1 = new MessageConsumer(url1, dest);
    // Consumer on r2
    MessageConsumer consumer2 = new MessageConsumer(url2, dest);
    // Replicator for r1 -> r2
    PersistentTopic topic = (PersistentTopic) pulsar1.getBrokerService().getTopicReference(dest.toString());
    PersistentReplicator replicator = topic.getPersistentReplicator("r2");
    // close the cursor
    Field cursorField = PersistentReplicator.class.getDeclaredField("cursor");
    cursorField.setAccessible(true);
    ManagedCursor cursor = (ManagedCursor) cursorField.get(replicator);
    cursor.close();
    // try to read entries
    CountDownLatch latch = new CountDownLatch(1);
    producer1.produce(10);
    cursor.asyncReadEntriesOrWait(10, new ReadEntriesCallback() {

        @Override
        public void readEntriesComplete(List<Entry> entries, Object ctx) {
            latch.countDown();
            fail("it should have been failed");
        }

        @Override
        public void readEntriesFailed(ManagedLedgerException exception, Object ctx) {
            latch.countDown();
            assertTrue(exception instanceof CursorAlreadyClosedException);
        }
    }, null);
    // replicator-readException: cursorAlreadyClosed
    replicator.readEntriesFailed(new CursorAlreadyClosedException("Cursor already closed exception"), null);
    // wait replicator producer to be closed
    Thread.sleep(1000);
    // Replicator producer must be closed
    Field producerField = PersistentReplicator.class.getDeclaredField("producer");
    producerField.setAccessible(true);
    ProducerImpl replicatorProducer = (ProducerImpl) producerField.get(replicator);
    assertEquals(replicatorProducer, null);
    producer1.close();
    consumer1.close();
    consumer2.close();
}
Also used : ReadEntriesCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntriesCallback) PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) CountDownLatch(java.util.concurrent.CountDownLatch) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) Field(java.lang.reflect.Field) ProducerImpl(com.yahoo.pulsar.client.impl.ProducerImpl) Entry(org.apache.bookkeeper.mledger.Entry) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) CursorAlreadyClosedException(org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException) Test(org.testng.annotations.Test)

Aggregations

ManagedCursor (org.apache.bookkeeper.mledger.ManagedCursor)135 Test (org.testng.annotations.Test)126 ManagedLedger (org.apache.bookkeeper.mledger.ManagedLedger)102 ManagedLedgerConfig (org.apache.bookkeeper.mledger.ManagedLedgerConfig)66 Position (org.apache.bookkeeper.mledger.Position)59 Entry (org.apache.bookkeeper.mledger.Entry)57 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)52 CountDownLatch (java.util.concurrent.CountDownLatch)32 ManagedLedgerFactory (org.apache.bookkeeper.mledger.ManagedLedgerFactory)28 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)17 CyclicBarrier (java.util.concurrent.CyclicBarrier)15 AddEntryCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback)12 ManagedLedgerFactoryConfig (org.apache.bookkeeper.mledger.ManagedLedgerFactoryConfig)12 List (java.util.List)10 BKException (org.apache.bookkeeper.client.BKException)10 AsyncCallbacks (org.apache.bookkeeper.mledger.AsyncCallbacks)10 Future (java.util.concurrent.Future)9 TimeUnit (java.util.concurrent.TimeUnit)9 AtomicReference (java.util.concurrent.atomic.AtomicReference)9 MarkDeleteCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.MarkDeleteCallback)9