Search in sources :

Example 36 with PersistentTopic

use of com.yahoo.pulsar.broker.service.persistent.PersistentTopic in project pulsar by yahoo.

the class BrokerService method createPersistentTopic.

private CompletableFuture<Topic> createPersistentTopic(final String topic) throws RuntimeException {
    checkTopicNsOwnership(topic);
    final long topicCreateTimeMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
    DestinationName destinationName = DestinationName.get(topic);
    if (!pulsar.getNamespaceService().isServiceUnitActive(destinationName)) {
        // namespace is being unloaded
        String msg = String.format("Namespace is being unloaded, cannot add topic %s", topic);
        log.warn(msg);
        throw new RuntimeException(new ServiceUnitNotReadyException(msg));
    }
    final CompletableFuture<Topic> topicFuture = new CompletableFuture<>();
    getManagedLedgerConfig(destinationName).thenAccept(config -> {
        managedLedgerFactory.asyncOpen(destinationName.getPersistenceNamingEncoding(), config, new OpenLedgerCallback() {

            @Override
            public void openLedgerComplete(ManagedLedger ledger, Object ctx) {
                PersistentTopic persistentTopic = new PersistentTopic(topic, ledger, BrokerService.this);
                CompletableFuture<Void> replicationFuture = persistentTopic.checkReplication();
                replicationFuture.thenRun(() -> {
                    log.info("Created topic {}", topic);
                    long topicLoadLatencyMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - topicCreateTimeMs;
                    pulsarStats.recordTopicLoadTimeValue(topic, topicLoadLatencyMs);
                    addTopicToStatsMaps(destinationName, persistentTopic);
                    topicFuture.complete(persistentTopic);
                });
                replicationFuture.exceptionally((ex) -> {
                    log.warn("Replication check failed. Removing topic from topics list {}, {}", topic, ex);
                    persistentTopic.stopReplProducers().whenComplete((v, exception) -> {
                        topics.remove(topic, topicFuture);
                        topicFuture.completeExceptionally(ex);
                    });
                    return null;
                });
            }

            @Override
            public void openLedgerFailed(ManagedLedgerException exception, Object ctx) {
                log.warn("Failed to create topic {}", topic, exception);
                topics.remove(topic, topicFuture);
                topicFuture.completeExceptionally(new PersistenceException(exception));
            }
        }, null);
    }).exceptionally((exception) -> {
        log.warn("[{}] Failed to get topic configuration: {}", topic, exception.getMessage(), exception);
        topics.remove(topic, topicFuture);
        topicFuture.completeExceptionally(exception);
        return null;
    });
    return topicFuture;
}
Also used : DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) LoggerFactory(org.slf4j.LoggerFactory) NamespaceBundleStats(com.yahoo.pulsar.common.policies.data.loadbalancer.NamespaceBundleStats) Stat(org.apache.zookeeper.data.Stat) Policies(com.yahoo.pulsar.common.policies.data.Policies) EpollMode(io.netty.channel.epoll.EpollMode) PersistencePolicies(com.yahoo.pulsar.common.policies.data.PersistencePolicies) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) PersistentOfflineTopicStats(com.yahoo.pulsar.common.policies.data.PersistentOfflineTopicStats) ClusterData(com.yahoo.pulsar.common.policies.data.ClusterData) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) ManagedLedgerConfig(org.apache.bookkeeper.mledger.ManagedLedgerConfig) Map(java.util.Map) ZooKeeperCacheListener(com.yahoo.pulsar.zookeeper.ZooKeeperCacheListener) PulsarService(com.yahoo.pulsar.broker.PulsarService) FieldParser(com.yahoo.pulsar.common.util.FieldParser) PulsarClientImpl(com.yahoo.pulsar.client.impl.PulsarClientImpl) FutureUtil(com.yahoo.pulsar.client.util.FutureUtil) URI(java.net.URI) PulsarClient(com.yahoo.pulsar.client.api.PulsarClient) SystemUtils(org.apache.commons.lang.SystemUtils) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) DigestType(org.apache.bookkeeper.client.BookKeeper.DigestType) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) Set(java.util.Set) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) PooledByteBufAllocator(io.netty.buffer.PooledByteBufAllocator) InetSocketAddress(java.net.InetSocketAddress) Executors(java.util.concurrent.Executors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) ObjectMapperFactory(com.yahoo.pulsar.common.util.ObjectMapperFactory) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Metrics(com.yahoo.pulsar.broker.stats.Metrics) List(java.util.List) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) AdminResource(com.yahoo.pulsar.broker.admin.AdminResource) ClientConfiguration(com.yahoo.pulsar.client.api.ClientConfiguration) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) Optional(java.util.Optional) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) ManagedLedgerFactory(org.apache.bookkeeper.mledger.ManagedLedgerFactory) ChannelOption(io.netty.channel.ChannelOption) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) SafeRun.safeRun(org.apache.bookkeeper.mledger.util.SafeRun.safeRun) PersistentTopicStats(com.yahoo.pulsar.common.policies.data.PersistentTopicStats) EpollChannelOption(io.netty.channel.epoll.EpollChannelOption) Lists(com.google.common.collect.Lists) FieldContext(com.yahoo.pulsar.common.configuration.FieldContext) ByteBuf(io.netty.buffer.ByteBuf) EpollServerSocketChannel(io.netty.channel.epoll.EpollServerSocketChannel) RetentionPolicies(com.yahoo.pulsar.common.policies.data.RetentionPolicies) ConcurrentOpenHashSet(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashSet) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) EpollEventLoopGroup(io.netty.channel.epoll.EpollEventLoopGroup) ConcurrentOpenHashMap(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashMap) AdaptiveRecvByteBufAllocator(io.netty.channel.AdaptiveRecvByteBufAllocator) NamespaceBundle(com.yahoo.pulsar.common.naming.NamespaceBundle) NamespaceBundleFactory(com.yahoo.pulsar.common.naming.NamespaceBundleFactory) PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) ClusterReplicationMetrics(com.yahoo.pulsar.broker.stats.ClusterReplicationMetrics) Logger(org.slf4j.Logger) ZooKeeperDataCache(com.yahoo.pulsar.zookeeper.ZooKeeperDataCache) EventLoopGroup(io.netty.channel.EventLoopGroup) KeeperException(org.apache.zookeeper.KeeperException) Semaphore(java.util.concurrent.Semaphore) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) ServerMetadataException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServerMetadataException) IOException(java.io.IOException) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) Field(java.lang.reflect.Field) ServiceUnitNotReadyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) OpenLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback) ServiceConfiguration(com.yahoo.pulsar.broker.ServiceConfiguration) PulsarWebResource(com.yahoo.pulsar.broker.web.PulsarWebResource) Closeable(java.io.Closeable) CollectionUtils.isEmpty(org.apache.commons.collections.CollectionUtils.isEmpty) AuthorizationManager(com.yahoo.pulsar.broker.authorization.AuthorizationManager) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) AuthenticationService(com.yahoo.pulsar.broker.authentication.AuthenticationService) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) ServiceUnitNotReadyException(com.yahoo.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) PersistenceException(com.yahoo.pulsar.broker.service.BrokerServiceException.PersistenceException) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) OpenLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback)

Example 37 with PersistentTopic

use of com.yahoo.pulsar.broker.service.persistent.PersistentTopic in project pulsar by yahoo.

the class BrokerService method getTopicStats.

public Map<String, PersistentTopicStats> getTopicStats() {
    HashMap<String, PersistentTopicStats> stats = new HashMap<>();
    topics.forEach((name, topicFuture) -> {
        PersistentTopic currentTopic = (PersistentTopic) topicFuture.getNow(null);
        if (currentTopic != null) {
            stats.put(name, currentTopic.getStats());
        }
    });
    return stats;
}
Also used : HashMap(java.util.HashMap) ConcurrentOpenHashMap(com.yahoo.pulsar.common.util.collections.ConcurrentOpenHashMap) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) PersistentTopicStats(com.yahoo.pulsar.common.policies.data.PersistentTopicStats)

Example 38 with PersistentTopic

use of com.yahoo.pulsar.broker.service.persistent.PersistentTopic 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 39 with PersistentTopic

use of com.yahoo.pulsar.broker.service.persistent.PersistentTopic 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 40 with PersistentTopic

use of com.yahoo.pulsar.broker.service.persistent.PersistentTopic in project pulsar by yahoo.

the class PersistentTopicTest method testDeleteTopicRaceConditions.

@Test
public void testDeleteTopicRaceConditions() throws Exception {
    PersistentTopic topic = (PersistentTopic) brokerService.getTopic(successTopicName).get();
    // override ledger deletion callback to slow down deletion
    doAnswer(new Answer<Object>() {

        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            Thread.sleep(1000);
            ((DeleteLedgerCallback) invocationOnMock.getArguments()[0]).deleteLedgerComplete(null);
            return null;
        }
    }).when(ledgerMock).asyncDelete(any(DeleteLedgerCallback.class), anyObject());
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.submit(() -> {
        topic.delete();
        return null;
    }).get();
    try {
        String role = "appid1";
        Thread.sleep(10);
        /* delay to ensure that the delete gets executed first */
        Producer producer = new Producer(topic, serverCnx, 1, /* producer id */
        "prod-name", role);
        topic.addProducer(producer);
        fail("Should have failed");
    } catch (BrokerServiceException e) {
        assertTrue(e instanceof BrokerServiceException.TopicFencedException);
    }
    CommandSubscribe cmd = CommandSubscribe.newBuilder().setConsumerId(1).setTopic(successTopicName).setSubscription(successSubName).setRequestId(1).setSubType(SubType.Exclusive).build();
    Future<Consumer> f = topic.subscribe(serverCnx, cmd.getSubscription(), cmd.getConsumerId(), cmd.getSubType(), 0, cmd.getConsumerName());
    try {
        f.get();
        fail("should have failed");
    } catch (ExecutionException ee) {
        assertTrue(ee.getCause() instanceof BrokerServiceException.TopicFencedException);
    // Expected
    }
}
Also used : Matchers.anyString(org.mockito.Matchers.anyString) CommandSubscribe(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSubscribe) DeleteLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.DeleteLedgerCallback) 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) ExecutionException(java.util.concurrent.ExecutionException) Test(org.testng.annotations.Test)

Aggregations

PersistentTopic (com.yahoo.pulsar.broker.service.persistent.PersistentTopic)92 Test (org.testng.annotations.Test)67 Producer (com.yahoo.pulsar.client.api.Producer)35 Consumer (com.yahoo.pulsar.client.api.Consumer)33 Message (com.yahoo.pulsar.client.api.Message)31 PersistentSubscription (com.yahoo.pulsar.broker.service.persistent.PersistentSubscription)29 DestinationName (com.yahoo.pulsar.common.naming.DestinationName)24 ConsumerConfiguration (com.yahoo.pulsar.client.api.ConsumerConfiguration)23 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)21 CompletableFuture (java.util.concurrent.CompletableFuture)17 KeeperException (org.apache.zookeeper.KeeperException)15 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)14 PersistentReplicator (com.yahoo.pulsar.broker.service.persistent.PersistentReplicator)13 IOException (java.io.IOException)13 SubscriptionBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)12 PersistentDispatcherSingleActiveConsumer (com.yahoo.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer)12 RestException (com.yahoo.pulsar.broker.web.RestException)12 PreconditionFailedException (com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException)12 ProducerConfiguration (com.yahoo.pulsar.client.api.ProducerConfiguration)12 CountDownLatch (java.util.concurrent.CountDownLatch)12