Search in sources :

Example 11 with DeleteCursorCallback

use of org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback in project incubator-pulsar by apache.

the class PersistentTopic method removeReplicator.

CompletableFuture<Void> removeReplicator(String remoteCluster) {
    log.info("[{}] Removing replicator to {}", topic, remoteCluster);
    final CompletableFuture<Void> future = new CompletableFuture<>();
    String name = PersistentReplicator.getReplicatorName(replicatorPrefix, remoteCluster);
    replicators.get(remoteCluster).disconnect().thenRun(() -> {
        ledger.asyncDeleteCursor(name, new DeleteCursorCallback() {

            @Override
            public void deleteCursorComplete(Object ctx) {
                replicators.remove(remoteCluster);
                future.complete(null);
            }

            @Override
            public void deleteCursorFailed(ManagedLedgerException exception, Object ctx) {
                log.error("[{}] Failed to delete cursor {} {}", topic, name, exception.getMessage(), exception);
                future.completeExceptionally(new PersistenceException(exception));
            }
        }, null);
    }).exceptionally(e -> {
        log.error("[{}] Failed to close replication producer {} {}", topic, name, e.getMessage(), e);
        future.completeExceptionally(e);
        return null;
    });
    return future;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistenceException(org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback)

Example 12 with DeleteCursorCallback

use of org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback in project incubator-pulsar by apache.

the class MessageDeduplication method checkStatus.

/**
 * Check the status of deduplication. If the configuration has changed, it will enable/disable deduplication,
 * returning a future to track the completion of the task
 */
public CompletableFuture<Void> checkStatus() {
    return isDeduplicationEnabled().thenCompose(shouldBeEnabled -> {
        synchronized (this) {
            if (status == Status.Recovering || status == Status.Removing) {
                // If there's already a transition happening, check later for status
                pulsar.getExecutor().schedule(this::checkStatus, 1, TimeUnit.MINUTES);
                return CompletableFuture.completedFuture(null);
            }
            if (status == Status.Enabled && !shouldBeEnabled) {
                // Disabled deduping
                CompletableFuture<Void> future = new CompletableFuture<>();
                status = Status.Removing;
                managedLedger.asyncDeleteCursor(PersistentTopic.DEDUPLICATION_CURSOR_NAME, new DeleteCursorCallback() {

                    @Override
                    public void deleteCursorComplete(Object ctx) {
                        status = Status.Disabled;
                        managedCursor = null;
                        highestSequencedPushed.clear();
                        highestSequencedPersisted.clear();
                        future.complete(null);
                        log.info("[{}] Disabled deduplication", topic.getName());
                    }

                    @Override
                    public void deleteCursorFailed(ManagedLedgerException exception, Object ctx) {
                        log.warn("[{}] Failed to disable deduplication: {}", topic.getName(), exception.getMessage());
                        status = Status.Failed;
                        future.completeExceptionally(exception);
                    }
                }, null);
                return future;
            } else if (status == Status.Disabled && shouldBeEnabled) {
                // Enable deduping
                CompletableFuture<Void> future = new CompletableFuture<>();
                managedLedger.asyncOpenCursor(PersistentTopic.DEDUPLICATION_CURSOR_NAME, new OpenCursorCallback() {

                    @Override
                    public void openCursorComplete(ManagedCursor cursor, Object ctx) {
                        // We don't want to retain cache for this cursor
                        cursor.setInactive();
                        managedCursor = cursor;
                        recoverSequenceIdsMap().thenRun(() -> {
                            status = Status.Enabled;
                            future.complete(null);
                            log.info("[{}] Enabled deduplication", topic.getName());
                        }).exceptionally(ex -> {
                            status = Status.Failed;
                            log.warn("[{}] Failed to enable deduplication: {}", topic.getName(), ex.getMessage());
                            future.completeExceptionally(ex);
                            return null;
                        });
                    }

                    @Override
                    public void openCursorFailed(ManagedLedgerException exception, Object ctx) {
                        log.warn("[{}] Failed to enable deduplication: {}", topic.getName(), exception.getMessage());
                        future.completeExceptionally(exception);
                    }
                }, null);
                return future;
            } else {
                // Nothing to do, we are in the correct state
                return CompletableFuture.completedFuture(null);
            }
        }
    });
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) OpenCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenCursorCallback) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor)

Example 13 with DeleteCursorCallback

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

the class ManagedLedgerImpl method deleteCursor.

@Override
public void deleteCursor(String name) throws InterruptedException, ManagedLedgerException {
    final CountDownLatch counter = new CountDownLatch(1);
    class Result {

        ManagedLedgerException exception = null;
    }
    final Result result = new Result();
    asyncDeleteCursor(name, new DeleteCursorCallback() {

        @Override
        public void deleteCursorComplete(Object ctx) {
            counter.countDown();
        }

        @Override
        public void deleteCursorFailed(ManagedLedgerException exception, Object ctx) {
            result.exception = exception;
            counter.countDown();
        }
    }, null);
    if (!counter.await(AsyncOperationTimeoutSeconds, TimeUnit.SECONDS)) {
        throw new ManagedLedgerException("Timeout during delete-cursors operation");
    }
    if (result.exception != null) {
        log.error("Deleting cursor", result.exception);
        throw result.exception;
    }
}
Also used : ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 14 with DeleteCursorCallback

use of org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback 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 15 with DeleteCursorCallback

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

the class PersistentTopicTest method testUbsubscribeRaceConditions.

@Test
public void testUbsubscribeRaceConditions() throws Exception {
    PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
    PersistentSubscription sub = new PersistentSubscription(topic, cursorMock);
    Consumer consumer1 = new Consumer(sub, SubType.Exclusive, 1, /* consumer id */
    0, "Cons1", /* consumer name */
    50000, serverCnx, "myrole-1");
    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 */
        Consumer consumer2 = new Consumer(sub, SubType.Exclusive, 2, /* consumer id */
        0, "Cons2", /* consumer name */
        50000, serverCnx, "myrole-1");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.SubscriptionFencedException);
    }
}
Also used : PersistentDispatcherSingleActiveConsumer(com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) ExecutorService(java.util.concurrent.ExecutorService) Matchers.anyObject(org.mockito.Matchers.anyObject) DeleteCursorCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback) PersistentSubscription(com.yahoo.pulsar.broker.service.persistent.PersistentSubscription) Test(org.testng.annotations.Test)

Aggregations

DeleteCursorCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteCursorCallback)19 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)15 CompletableFuture (java.util.concurrent.CompletableFuture)9 Matchers.anyObject (org.mockito.Matchers.anyObject)8 ManagedCursor (org.apache.bookkeeper.mledger.ManagedCursor)7 InvocationOnMock (org.mockito.invocation.InvocationOnMock)6 Test (org.testng.annotations.Test)6 OpenCursorCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.OpenCursorCallback)5 ByteBuf (io.netty.buffer.ByteBuf)4 Method (java.lang.reflect.Method)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 AddEntryCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback)4 CloseCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.CloseCallback)4 OpenLedgerCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback)4 ManagedLedger (org.apache.bookkeeper.mledger.ManagedLedger)4 ManagedLedgerConfig (org.apache.bookkeeper.mledger.ManagedLedgerConfig)4 PositionImpl (org.apache.bookkeeper.mledger.impl.PositionImpl)4 PersistentTopic (com.yahoo.pulsar.broker.service.persistent.PersistentTopic)3 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)3 BeforeMethod (org.testng.annotations.BeforeMethod)3