Search in sources :

Example 1 with ServiceUnitNotReadyException

use of org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException in project incubator-pulsar by apache.

the class BrokerService method checkTopicNsOwnership.

void checkTopicNsOwnership(final String topic) throws RuntimeException {
    TopicName topicName = TopicName.get(topic);
    boolean ownedByThisInstance;
    try {
        ownedByThisInstance = pulsar.getNamespaceService().isServiceUnitOwned(topicName);
    } catch (Exception e) {
        log.debug(String.format("Failed to check the ownership of the topic: %s", topicName), e);
        throw new RuntimeException(new ServerMetadataException(e));
    }
    if (!ownedByThisInstance) {
        String msg = String.format("Namespace not served by this instance. Please redo the lookup. " + "Request is denied: namespace=%s", topicName.getNamespace());
        log.warn(msg);
        throw new RuntimeException(new ServiceUnitNotReadyException(msg));
    }
}
Also used : ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) NamingException(org.apache.pulsar.broker.service.BrokerServiceException.NamingException) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) IOException(java.io.IOException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) KeeperException(org.apache.zookeeper.KeeperException) PersistenceException(org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException) TopicName(org.apache.pulsar.common.naming.TopicName)

Example 2 with ServiceUnitNotReadyException

use of org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException in project incubator-pulsar by apache.

the class BrokerService method createPersistentTopic.

private void createPersistentTopic(final String topic, CompletableFuture<Topic> topicFuture) {
    final long topicCreateTimeMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
    TopicName topicName = TopicName.get(topic);
    if (!pulsar.getNamespaceService().isServiceUnitActive(topicName)) {
        // namespace is being unloaded
        String msg = String.format("Namespace is being unloaded, cannot add topic %s", topic);
        log.warn(msg);
        pulsar.getExecutor().submit(() -> topics.remove(topic, topicFuture));
        topicFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
        return;
    }
    getManagedLedgerConfig(topicName).thenAccept(managedLedgerConfig -> {
        // Once we have the configuration, we can proceed with the async open operation
        managedLedgerFactory.asyncOpen(topicName.getPersistenceNamingEncoding(), managedLedgerConfig, new OpenLedgerCallback() {

            @Override
            public void openLedgerComplete(ManagedLedger ledger, Object ctx) {
                try {
                    PersistentTopic persistentTopic = new PersistentTopic(topic, ledger, BrokerService.this);
                    CompletableFuture<Void> replicationFuture = persistentTopic.checkReplication();
                    replicationFuture.thenCompose(v -> {
                        // Also check dedup status
                        return persistentTopic.checkDeduplicationStatus();
                    }).thenRun(() -> {
                        log.info("Created topic {} - dedup is {}", topic, persistentTopic.isDeduplicationEnabled() ? "enabled" : "disabled");
                        long topicLoadLatencyMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - topicCreateTimeMs;
                        pulsarStats.recordTopicLoadTimeValue(topic, topicLoadLatencyMs);
                        addTopicToStatsMaps(topicName, persistentTopic);
                        topicFuture.complete(persistentTopic);
                    }).exceptionally((ex) -> {
                        log.warn("Replication or dedup check failed. Removing topic from topics list {}, {}", topic, ex);
                        persistentTopic.stopReplProducers().whenComplete((v, exception) -> {
                            topics.remove(topic, topicFuture);
                            topicFuture.completeExceptionally(ex);
                        });
                        return null;
                    });
                } catch (NamingException e) {
                    log.warn("Failed to create topic {}-{}", topic, e.getMessage());
                    pulsar.getExecutor().submit(() -> topics.remove(topic, topicFuture));
                    topicFuture.completeExceptionally(e);
                }
            }

            @Override
            public void openLedgerFailed(ManagedLedgerException exception, Object ctx) {
                log.warn("Failed to create topic {}", topic, exception);
                pulsar.getExecutor().submit(() -> topics.remove(topic, topicFuture));
                topicFuture.completeExceptionally(new PersistenceException(exception));
            }
        }, null);
    }).exceptionally((exception) -> {
        log.warn("[{}] Failed to get topic configuration: {}", topic, exception.getMessage(), exception);
        // remove topic from topics-map in different thread to avoid possible deadlock if
        // createPersistentTopic-thread only tries to handle this future-result
        pulsar.getExecutor().submit(() -> topics.remove(topic, topicFuture));
        topicFuture.completeExceptionally(exception);
        return null;
    });
}
Also used : CreateMode(org.apache.zookeeper.CreateMode) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) NamingException(org.apache.pulsar.broker.service.BrokerServiceException.NamingException) PulsarClientImpl(org.apache.pulsar.client.impl.PulsarClientImpl) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) LoadManager(org.apache.pulsar.broker.loadbalance.LoadManager) FieldContext(org.apache.pulsar.common.configuration.FieldContext) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) ZooKeeperDataCache(org.apache.pulsar.zookeeper.ZooKeeperDataCache) PersistentOfflineTopicStats(org.apache.pulsar.common.policies.data.PersistentOfflineTopicStats) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) PersistencePolicies(org.apache.pulsar.common.policies.data.PersistencePolicies) Set(java.util.Set) ZooKeeperCacheListener(org.apache.pulsar.zookeeper.ZooKeeperCacheListener) PooledByteBufAllocator(io.netty.buffer.PooledByteBufAllocator) Executors(java.util.concurrent.Executors) ZkUtils(org.apache.bookkeeper.util.ZkUtils) NamespaceBundleFactory(org.apache.pulsar.common.naming.NamespaceBundleFactory) ConcurrentOpenHashSet(org.apache.pulsar.common.util.collections.ConcurrentOpenHashSet) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) ClientBuilderImpl(org.apache.pulsar.client.impl.ClientBuilderImpl) ManagedLedgerFactory(org.apache.bookkeeper.mledger.ManagedLedgerFactory) ChannelOption(io.netty.channel.ChannelOption) AuthenticationService(org.apache.pulsar.broker.authentication.AuthenticationService) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) EventType(org.apache.pulsar.broker.zookeeper.aspectj.ClientCnxnAspect.EventType) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) Lists(com.google.common.collect.Lists) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) PulsarClient(org.apache.pulsar.client.api.PulsarClient) NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) PersistentDispatcherMultipleConsumers(org.apache.pulsar.broker.service.persistent.PersistentDispatcherMultipleConsumers) ClientCnxnAspect(org.apache.pulsar.broker.zookeeper.aspectj.ClientCnxnAspect) PulsarWebResource(org.apache.pulsar.broker.web.PulsarWebResource) SslContext(io.netty.handler.ssl.SslContext) IOException(java.io.IOException) Field(java.lang.reflect.Field) PulsarService(org.apache.pulsar.broker.PulsarService) OpenLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback) POLICIES(org.apache.pulsar.broker.cache.ConfigurationCacheService.POLICIES) CollectionUtils.isEmpty(org.apache.commons.collections.CollectionUtils.isEmpty) AuthorizationService(org.apache.pulsar.broker.authorization.AuthorizationService) Metrics(org.apache.pulsar.common.stats.Metrics) DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) PersistentTopicStats(org.apache.pulsar.common.policies.data.PersistentTopicStats) Ids(org.apache.zookeeper.ZooDefs.Ids) AdminResource(org.apache.pulsar.broker.admin.AdminResource) ObjectMapperFactory(org.apache.pulsar.common.util.ObjectMapperFactory) LoggerFactory(org.slf4j.LoggerFactory) ClusterData(org.apache.pulsar.common.policies.data.ClusterData) Stat(org.apache.zookeeper.data.Stat) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) ManagedLedgerConfig(org.apache.bookkeeper.mledger.ManagedLedgerConfig) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) URI(java.net.URI) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) DigestType(org.apache.bookkeeper.client.BookKeeper.DigestType) EventLoopUtil(org.apache.pulsar.common.util.netty.EventLoopUtil) OrderedScheduler(org.apache.bookkeeper.common.util.OrderedScheduler) Predicate(java.util.function.Predicate) InetSocketAddress(java.net.InetSocketAddress) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) Queues(com.google.common.collect.Queues) ClientConfigurationData(org.apache.pulsar.client.impl.conf.ClientConfigurationData) EventListner(org.apache.pulsar.broker.zookeeper.aspectj.ClientCnxnAspect.EventListner) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Optional(java.util.Optional) NamespaceBundleStats(org.apache.pulsar.policies.data.loadbalancer.NamespaceBundleStats) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) LongAdder(java.util.concurrent.atomic.LongAdder) TopicName(org.apache.pulsar.common.naming.TopicName) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) SafeRun.safeRun(org.apache.bookkeeper.mledger.util.SafeRun.safeRun) ByteBuf(io.netty.buffer.ByteBuf) AdaptiveRecvByteBufAllocator(io.netty.channel.AdaptiveRecvByteBufAllocator) TopicDomain(org.apache.pulsar.common.naming.TopicDomain) ClusterReplicationMetrics(org.apache.pulsar.broker.stats.ClusterReplicationMetrics) FieldParser(org.apache.pulsar.common.util.FieldParser) RetentionPolicies(org.apache.pulsar.common.policies.data.RetentionPolicies) Logger(org.slf4j.Logger) EventLoopGroup(io.netty.channel.EventLoopGroup) KeeperException(org.apache.zookeeper.KeeperException) Semaphore(java.util.concurrent.Semaphore) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) PersistenceException(org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException) Maps(com.google.common.collect.Maps) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Policies(org.apache.pulsar.common.policies.data.Policies) Closeable(java.io.Closeable) NonPersistentTopic(org.apache.pulsar.broker.service.nonpersistent.NonPersistentTopic) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) Collections(java.util.Collections) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) TopicName(org.apache.pulsar.common.naming.TopicName) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) NonPersistentTopic(org.apache.pulsar.broker.service.nonpersistent.NonPersistentTopic) PersistenceException(org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException) NamingException(org.apache.pulsar.broker.service.BrokerServiceException.NamingException) OpenLedgerCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.OpenLedgerCallback)

Example 3 with ServiceUnitNotReadyException

use of org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException in project incubator-pulsar by apache.

the class ServerCnx method handleProducer.

@Override
protected void handleProducer(final CommandProducer cmdProducer) {
    checkArgument(state == State.Connected);
    final long producerId = cmdProducer.getProducerId();
    final long requestId = cmdProducer.getRequestId();
    // Use producer name provided by client if present
    final String producerName = cmdProducer.hasProducerName() ? cmdProducer.getProducerName() : service.generateUniqueProducerName();
    final boolean isEncrypted = cmdProducer.getEncrypted();
    final Map<String, String> metadata = CommandUtils.metadataFromCommand(cmdProducer);
    TopicName topicName = validateTopicName(cmdProducer.getTopic(), requestId, cmdProducer);
    if (topicName == null) {
        return;
    }
    if (invalidOriginalPrincipal(originalPrincipal)) {
        final String msg = "Valid Proxy Client role should be provided while creating producer ";
        log.warn("[{}] {} with role {} and proxyClientAuthRole {} on topic {}", remoteAddress, msg, authRole, originalPrincipal, topicName);
        ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
        return;
    }
    CompletableFuture<Boolean> isProxyAuthorizedFuture;
    if (service.isAuthorizationEnabled() && originalPrincipal != null) {
        isProxyAuthorizedFuture = service.getAuthorizationService().canProduceAsync(topicName, authRole, authenticationData);
    } else {
        isProxyAuthorizedFuture = CompletableFuture.completedFuture(true);
    }
    isProxyAuthorizedFuture.thenApply(isProxyAuthorized -> {
        if (isProxyAuthorized) {
            CompletableFuture<Boolean> authorizationFuture;
            if (service.isAuthorizationEnabled()) {
                authorizationFuture = service.getAuthorizationService().canProduceAsync(topicName, originalPrincipal != null ? originalPrincipal : authRole, authenticationData);
            } else {
                authorizationFuture = CompletableFuture.completedFuture(true);
            }
            authorizationFuture.thenApply(isAuthorized -> {
                if (isAuthorized) {
                    if (log.isDebugEnabled()) {
                        log.debug("[{}] Client is authorized to Produce with role {}", remoteAddress, authRole);
                    }
                    CompletableFuture<Producer> producerFuture = new CompletableFuture<>();
                    CompletableFuture<Producer> existingProducerFuture = producers.putIfAbsent(producerId, producerFuture);
                    if (existingProducerFuture != null) {
                        if (existingProducerFuture.isDone() && !existingProducerFuture.isCompletedExceptionally()) {
                            Producer producer = existingProducerFuture.getNow(null);
                            log.info("[{}] Producer with the same id is already created: {}", remoteAddress, producer);
                            ctx.writeAndFlush(Commands.newProducerSuccess(requestId, producer.getProducerName(), producer.getSchemaVersion()));
                            return null;
                        } else {
                            // There was an early request to create a producer with
                            // same producerId. This can happen when
                            // client
                            // timeout is lower the broker timeouts. We need to wait
                            // until the previous producer creation
                            // request
                            // either complete or fails.
                            ServerError error = !existingProducerFuture.isDone() ? ServerError.ServiceNotReady : getErrorCode(existingProducerFuture);
                            log.warn("[{}][{}] Producer is already present on the connection", remoteAddress, topicName);
                            ctx.writeAndFlush(Commands.newError(requestId, error, "Producer is already present on the connection"));
                            return null;
                        }
                    }
                    log.info("[{}][{}] Creating producer. producerId={}", remoteAddress, topicName, producerId);
                    service.getTopic(topicName.toString()).thenAccept((Topic topic) -> {
                        // on topic
                        if (topic.isBacklogQuotaExceeded(producerName)) {
                            IllegalStateException illegalStateException = new IllegalStateException("Cannot create producer on topic with backlog quota exceeded");
                            BacklogQuota.RetentionPolicy retentionPolicy = topic.getBacklogQuota().getPolicy();
                            if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_request_hold) {
                                ctx.writeAndFlush(Commands.newError(requestId, ServerError.ProducerBlockedQuotaExceededError, illegalStateException.getMessage()));
                            } else if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_exception) {
                                ctx.writeAndFlush(Commands.newError(requestId, ServerError.ProducerBlockedQuotaExceededException, illegalStateException.getMessage()));
                            }
                            producerFuture.completeExceptionally(illegalStateException);
                            producers.remove(producerId, producerFuture);
                            return;
                        }
                        // Check whether the producer will publish encrypted messages or not
                        if (topic.isEncryptionRequired() && !isEncrypted) {
                            String msg = String.format("Encryption is required in %s", topicName);
                            log.warn("[{}] {}", remoteAddress, msg);
                            ctx.writeAndFlush(Commands.newError(requestId, ServerError.MetadataError, msg));
                            return;
                        }
                        disableTcpNoDelayIfNeeded(topicName.toString(), producerName);
                        CompletableFuture<SchemaVersion> schemaVersionFuture;
                        if (cmdProducer.hasSchema()) {
                            schemaVersionFuture = topic.addSchema(getSchema(cmdProducer.getSchema()));
                        } else {
                            schemaVersionFuture = CompletableFuture.completedFuture(SchemaVersion.Empty);
                        }
                        schemaVersionFuture.exceptionally(exception -> {
                            ctx.writeAndFlush(Commands.newError(requestId, ServerError.UnknownError, exception.getMessage()));
                            producers.remove(producerId, producerFuture);
                            return null;
                        });
                        schemaVersionFuture.thenAccept(schemaVersion -> {
                            Producer producer = new Producer(topic, ServerCnx.this, producerId, producerName, authRole, isEncrypted, metadata, schemaVersion);
                            try {
                                topic.addProducer(producer);
                                if (isActive()) {
                                    if (producerFuture.complete(producer)) {
                                        log.info("[{}] Created new producer: {}", remoteAddress, producer);
                                        ctx.writeAndFlush(Commands.newProducerSuccess(requestId, producerName, producer.getLastSequenceId(), producer.getSchemaVersion()));
                                        return;
                                    } else {
                                        // The producer's future was completed before by
                                        // a close command
                                        producer.closeNow();
                                        log.info("[{}] Cleared producer created after timeout on client side {}", remoteAddress, producer);
                                    }
                                } else {
                                    producer.closeNow();
                                    log.info("[{}] Cleared producer created after connection was closed: {}", remoteAddress, producer);
                                    producerFuture.completeExceptionally(new IllegalStateException("Producer created after connection was closed"));
                                }
                            } catch (BrokerServiceException ise) {
                                log.error("[{}] Failed to add producer to topic {}: {}", remoteAddress, topicName, ise.getMessage());
                                ctx.writeAndFlush(Commands.newError(requestId, BrokerServiceException.getClientErrorCode(ise), ise.getMessage()));
                                producerFuture.completeExceptionally(ise);
                            }
                            producers.remove(producerId, producerFuture);
                        });
                    }).exceptionally(exception -> {
                        Throwable cause = exception.getCause();
                        if (!(cause instanceof ServiceUnitNotReadyException)) {
                            // Do not print stack traces for expected exceptions
                            log.error("[{}] Failed to create topic {}", remoteAddress, topicName, exception);
                        }
                        // client, only if not completed already.
                        if (producerFuture.completeExceptionally(exception)) {
                            ctx.writeAndFlush(Commands.newError(requestId, BrokerServiceException.getClientErrorCode(cause), cause.getMessage()));
                        }
                        producers.remove(producerId, producerFuture);
                        return null;
                    });
                } else {
                    String msg = "Client is not authorized to Produce";
                    log.warn("[{}] {} with role {}", remoteAddress, msg, authRole);
                    ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
                }
                return null;
            }).exceptionally(e -> {
                String msg = String.format("[%s] %s with role %s", remoteAddress, e.getMessage(), authRole);
                log.warn(msg);
                ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, e.getMessage()));
                return null;
            });
        } else {
            final String msg = "Proxy Client is not authorized to Produce";
            log.warn("[{}] {} with role {} on topic {}", remoteAddress, msg, authRole, topicName);
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
        }
        return null;
    }).exceptionally(ex -> {
        String msg = String.format("[%s] %s with role %s", remoteAddress, ex.getMessage(), authRole);
        log.warn(msg);
        ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, ex.getMessage()));
        return null;
    });
}
Also used : PulsarApi(org.apache.pulsar.common.api.proto.PulsarApi) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandUtils(org.apache.pulsar.common.api.CommandUtils) SocketAddress(java.net.SocketAddress) PersistentTopicsBase.getPartitionedTopicMetadata(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.getPartitionedTopicMetadata) SchemaVersion(org.apache.pulsar.common.schema.SchemaVersion) CommandAck(org.apache.pulsar.common.api.proto.PulsarApi.CommandAck) LoggerFactory(org.slf4j.LoggerFactory) AuthenticationException(javax.naming.AuthenticationException) StringUtils(org.apache.commons.lang3.StringUtils) CommandCloseConsumer(org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseConsumer) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.PulsarApi.CommandGetLastMessageId) CommandSend(org.apache.pulsar.common.api.proto.PulsarApi.CommandSend) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) PulsarHandler(org.apache.pulsar.common.api.PulsarHandler) Map(java.util.Map) RestException(org.apache.pulsar.broker.web.RestException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.PulsarApi.CommandGetTopicsOfNamespace) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.PulsarApi.ProtocolVersion.v5) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) CommandConnect(org.apache.pulsar.common.api.proto.PulsarApi.CommandConnect) Commands(org.apache.pulsar.common.api.Commands) Commands.newLookupErrorResponse(org.apache.pulsar.common.api.Commands.newLookupErrorResponse) CommandSubscribe(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe) Set(java.util.Set) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.PulsarApi.CommandRedeliverUnacknowledgedMessages) Position(org.apache.bookkeeper.mledger.Position) CommandCloseProducer(org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer) CommandFlow(org.apache.pulsar.common.api.proto.PulsarApi.CommandFlow) Collectors(java.util.stream.Collectors) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) SchemaData(org.apache.pulsar.common.schema.SchemaData) CommandConsumerStatsResponse(org.apache.pulsar.common.api.proto.PulsarApi.CommandConsumerStatsResponse) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.PulsarApi.CommandPartitionedTopicMetadata) MessageIdData(org.apache.pulsar.common.api.proto.PulsarApi.MessageIdData) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) TopicName(org.apache.pulsar.common.naming.TopicName) ChannelOption(io.netty.channel.ChannelOption) CommandConsumerStats(org.apache.pulsar.common.api.proto.PulsarApi.CommandConsumerStats) GeneratedMessageLite(com.google.protobuf.GeneratedMessageLite) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) ProtocolVersion(org.apache.pulsar.common.api.proto.PulsarApi.ProtocolVersion) SchemaType(org.apache.pulsar.common.schema.SchemaType) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) ByteBuf(io.netty.buffer.ByteBuf) MessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata) CommandProducer(org.apache.pulsar.common.api.proto.PulsarApi.CommandProducer) CommandSeek(org.apache.pulsar.common.api.proto.PulsarApi.CommandSeek) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) Metadata(org.apache.pulsar.common.naming.Metadata) Logger(org.slf4j.Logger) SubType(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.SubType) Semaphore(java.util.concurrent.Semaphore) CommandLookupTopic(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic) TimeUnit(java.util.concurrent.TimeUnit) CommandUnsubscribe(org.apache.pulsar.common.api.proto.PulsarApi.CommandUnsubscribe) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) TopicLookup.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookup.lookupTopicAsync) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) ConsumerStats(org.apache.pulsar.common.policies.data.ConsumerStats) InitialPosition(org.apache.pulsar.common.api.proto.PulsarApi.CommandSubscribe.InitialPosition) ServerError(org.apache.pulsar.common.api.proto.PulsarApi.ServerError) TopicName(org.apache.pulsar.common.naming.TopicName) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CompletableFuture(java.util.concurrent.CompletableFuture) CommandCloseProducer(org.apache.pulsar.common.api.proto.PulsarApi.CommandCloseProducer) CommandProducer(org.apache.pulsar.common.api.proto.PulsarApi.CommandProducer) CommandLookupTopic(org.apache.pulsar.common.api.proto.PulsarApi.CommandLookupTopic)

Example 4 with ServiceUnitNotReadyException

use of org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException in project incubator-pulsar by apache.

the class NamespaceService method splitAndOwnBundleOnceAndRetry.

void splitAndOwnBundleOnceAndRetry(NamespaceBundle bundle, boolean unload, AtomicInteger counter, CompletableFuture<Void> unloadFuture) {
    CompletableFuture<NamespaceBundles> updateFuture = new CompletableFuture<>();
    final Pair<NamespaceBundles, List<NamespaceBundle>> splittedBundles = bundleFactory.splitBundles(bundle, 2);
    // Split and updateNamespaceBundles. Update may fail because of concurrent write to Zookeeper.
    if (splittedBundles != null) {
        checkNotNull(splittedBundles.getLeft());
        checkNotNull(splittedBundles.getRight());
        checkArgument(splittedBundles.getRight().size() == 2, "bundle has to be split in two bundles");
        NamespaceName nsname = bundle.getNamespaceObject();
        if (LOG.isDebugEnabled()) {
            LOG.debug("[{}] splitAndOwnBundleOnce: {}, counter: {},  2 bundles: {}, {}", nsname.toString(), bundle.getBundleRange(), counter.get(), splittedBundles != null ? splittedBundles.getRight().get(0).getBundleRange() : "null splittedBundles", splittedBundles != null ? splittedBundles.getRight().get(1).getBundleRange() : "null splittedBundles");
        }
        try {
            // take ownership of newly split bundles
            for (NamespaceBundle sBundle : splittedBundles.getRight()) {
                checkNotNull(ownershipCache.tryAcquiringOwnership(sBundle));
            }
            updateNamespaceBundles(nsname, splittedBundles.getLeft(), (rc, path, zkCtx, stat) -> {
                if (rc == Code.OK.intValue()) {
                    // invalidate cache as zookeeper has new split
                    // namespace bundle
                    bundleFactory.invalidateBundleCache(bundle.getNamespaceObject());
                    updateFuture.complete(splittedBundles.getLeft());
                } else if (rc == Code.BADVERSION.intValue()) {
                    KeeperException keeperException = KeeperException.create(KeeperException.Code.get(rc));
                    String msg = format("failed to update namespace policies [%s], NamespaceBundle: %s " + "due to %s, counter: %d", nsname.toString(), bundle.getBundleRange(), keeperException.getMessage(), counter.get());
                    LOG.warn(msg);
                    updateFuture.completeExceptionally(new ServerMetadataException(keeperException));
                } else {
                    String msg = format("failed to update namespace policies [%s], NamespaceBundle: %s due to %s", nsname.toString(), bundle.getBundleRange(), KeeperException.create(KeeperException.Code.get(rc)).getMessage());
                    LOG.warn(msg);
                    updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
                }
            });
        } catch (Exception e) {
            String msg = format("failed to acquire ownership of split bundle for namespace [%s], %s", nsname.toString(), e.getMessage());
            LOG.warn(msg, e);
            updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
        }
    } else {
        String msg = format("bundle %s not found under namespace", bundle.toString());
        LOG.warn(msg);
        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
    }
    // If success updateNamespaceBundles, then do invalidateBundleCache and unload.
    // Else retry splitAndOwnBundleOnceAndRetry.
    updateFuture.whenCompleteAsync((r, t) -> {
        if (t != null) {
            // retry several times on BadVersion
            if ((t instanceof ServerMetadataException) && (counter.decrementAndGet() >= 0)) {
                pulsar.getOrderedExecutor().submit(() -> splitAndOwnBundleOnceAndRetry(bundle, unload, counter, unloadFuture));
            } else {
                // Retry enough, or meet other exception
                String msg2 = format(" %s not success update nsBundles, counter %d, reason %s", bundle.toString(), counter.get(), t.getMessage());
                LOG.warn(msg2);
                unloadFuture.completeExceptionally(new ServiceUnitNotReadyException(msg2));
            }
            return;
        }
        // success updateNamespaceBundles
        try {
            // disable old bundle in memory
            getOwnershipCache().updateBundleState(bundle, false);
            // update bundled_topic cache for load-report-generation
            pulsar.getBrokerService().refreshTopicToStatsMaps(bundle);
            loadManager.get().setLoadReportForceUpdateFlag();
            if (unload) {
                // unload new split bundles
                r.getBundles().forEach(splitBundle -> {
                    try {
                        unloadNamespaceBundle(splitBundle);
                    } catch (Exception e) {
                        LOG.warn("Failed to unload split bundle {}", splitBundle, e);
                        throw new RuntimeException("Failed to unload split bundle " + splitBundle, e);
                    }
                });
            }
            unloadFuture.complete(null);
        } catch (Exception e) {
            String msg1 = format("failed to disable bundle %s under namespace [%s] with error %s", bundle.getNamespaceObject().toString(), bundle.toString(), e.getMessage());
            LOG.warn(msg1, e);
            unloadFuture.completeExceptionally(new ServiceUnitNotReadyException(msg1));
        }
        return;
    }, pulsar.getOrderedExecutor());
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) NamespaceBundles(org.apache.pulsar.common.naming.NamespaceBundles) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) KeeperException(org.apache.zookeeper.KeeperException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CompletableFuture(java.util.concurrent.CompletableFuture) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) List(java.util.List) KeeperException(org.apache.zookeeper.KeeperException)

Aggregations

ServerMetadataException (org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException)4 ServiceUnitNotReadyException (org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException)4 List (java.util.List)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)3 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 ByteBuf (io.netty.buffer.ByteBuf)2 ChannelOption (io.netty.channel.ChannelOption)2 IOException (java.io.IOException)2 Map (java.util.Map)2 Set (java.util.Set)2 Semaphore (java.util.concurrent.Semaphore)2 TimeUnit (java.util.concurrent.TimeUnit)2 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)2 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)2 NamingException (org.apache.pulsar.broker.service.BrokerServiceException.NamingException)2 NotAllowedException (org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException)2 PersistenceException (org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException)2 NamespaceName (org.apache.pulsar.common.naming.NamespaceName)2 TopicName (org.apache.pulsar.common.naming.TopicName)2