Search in sources :

Example 1 with TopicNotFoundException

use of org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException in project 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 long epoch = cmdProducer.getEpoch();
    final boolean userProvidedProducerName = cmdProducer.isUserProvidedProducerName();
    final boolean isEncrypted = cmdProducer.isEncrypted();
    final Map<String, String> metadata = CommandUtils.metadataFromCommand(cmdProducer);
    final SchemaData schema = cmdProducer.hasSchema() ? getSchema(cmdProducer.getSchema()) : null;
    final ProducerAccessMode producerAccessMode = cmdProducer.getProducerAccessMode();
    final Optional<Long> topicEpoch = cmdProducer.hasTopicEpoch() ? Optional.of(cmdProducer.getTopicEpoch()) : Optional.empty();
    final boolean isTxnEnabled = cmdProducer.isTxnEnabled();
    final String initialSubscriptionName = cmdProducer.hasInitialSubscriptionName() ? cmdProducer.getInitialSubscriptionName() : null;
    final boolean supportsPartialProducer = supportsPartialProducer();
    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);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, msg);
        return;
    }
    CompletableFuture<Boolean> isAuthorizedFuture = isTopicOperationAllowed(topicName, TopicOperation.PRODUCE);
    if (!Strings.isNullOrEmpty(initialSubscriptionName)) {
        isAuthorizedFuture = isAuthorizedFuture.thenCombine(isTopicOperationAllowed(topicName, TopicOperation.SUBSCRIBE), (canProduce, canSubscribe) -> canProduce && canSubscribe);
    }
    isAuthorizedFuture.thenApply(isAuthorized -> {
        if (!isAuthorized) {
            String msg = "Client is not authorized to Produce";
            log.warn("[{}] {} with role {}", remoteAddress, msg, getPrincipal());
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("[{}] Client is authorized to Produce with role {}", remoteAddress, getPrincipal());
        }
        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:" + " producerId={}, producer={}", remoteAddress, producerId, producer);
                commandSender.sendProducerSuccessResponse(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 than the broker timeouts.
                // We need to wait until the previous producer creation request
                // either complete or fails.
                ServerError error = null;
                if (!existingProducerFuture.isDone()) {
                    error = ServerError.ServiceNotReady;
                } else {
                    error = getErrorCode(existingProducerFuture);
                    // remove producer with producerId as it's already completed with exception
                    producers.remove(producerId, existingProducerFuture);
                }
                log.warn("[{}][{}] Producer with id is already present on the connection, producerId={}", remoteAddress, topicName, producerId);
                commandSender.sendErrorResponse(requestId, error, "Producer is already present on the connection");
                return null;
            }
        }
        log.info("[{}][{}] Creating producer. producerId={}", remoteAddress, topicName, producerId);
        service.getOrCreateTopic(topicName.toString()).thenCompose((Topic topic) -> {
            // Before creating producer, check if backlog quota exceeded
            // on topic for size based limit and time based limit
            CompletableFuture<Void> backlogQuotaCheckFuture = CompletableFuture.allOf(topic.checkBacklogQuotaExceeded(producerName, BacklogQuotaType.destination_storage), topic.checkBacklogQuotaExceeded(producerName, BacklogQuotaType.message_age));
            backlogQuotaCheckFuture.thenRun(() -> {
                // Check whether the producer will publish encrypted messages or not
                if ((topic.isEncryptionRequired() || encryptionRequireOnProducer) && !isEncrypted) {
                    String msg = String.format("Encryption is required in %s", topicName);
                    log.warn("[{}] {}", remoteAddress, msg);
                    if (producerFuture.completeExceptionally(new ServerMetadataException(msg))) {
                        commandSender.sendErrorResponse(requestId, ServerError.MetadataError, msg);
                    }
                    producers.remove(producerId, producerFuture);
                    return;
                }
                disableTcpNoDelayIfNeeded(topicName.toString(), producerName);
                CompletableFuture<SchemaVersion> schemaVersionFuture = tryAddSchema(topic, schema);
                schemaVersionFuture.exceptionally(exception -> {
                    if (producerFuture.completeExceptionally(exception)) {
                        String message = exception.getMessage();
                        if (exception.getCause() != null) {
                            message += (" caused by " + exception.getCause());
                        }
                        commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(exception), message);
                    }
                    producers.remove(producerId, producerFuture);
                    return null;
                });
                schemaVersionFuture.thenAccept(schemaVersion -> {
                    topic.checkIfTransactionBufferRecoverCompletely(isTxnEnabled).thenAccept(future -> {
                        CompletableFuture<Subscription> createInitSubFuture;
                        if (!Strings.isNullOrEmpty(initialSubscriptionName) && topic.isPersistent() && !topic.getSubscriptions().containsKey(initialSubscriptionName)) {
                            if (!this.getBrokerService().isAllowAutoSubscriptionCreation(topicName)) {
                                String msg = "Could not create the initial subscription due to the auto subscription " + "creation is not allowed.";
                                if (producerFuture.completeExceptionally(new BrokerServiceException.NotAllowedException(msg))) {
                                    log.warn("[{}] {} initialSubscriptionName: {}, topic: {}", remoteAddress, msg, initialSubscriptionName, topicName);
                                    commandSender.sendErrorResponse(requestId, ServerError.NotAllowedError, msg);
                                }
                                producers.remove(producerId, producerFuture);
                                return;
                            }
                            createInitSubFuture = topic.createSubscription(initialSubscriptionName, InitialPosition.Earliest, false);
                        } else {
                            createInitSubFuture = CompletableFuture.completedFuture(null);
                        }
                        createInitSubFuture.whenComplete((sub, ex) -> {
                            if (ex != null) {
                                String msg = "Failed to create the initial subscription: " + ex.getCause().getMessage();
                                log.warn("[{}] {} initialSubscriptionName: {}, topic: {}", remoteAddress, msg, initialSubscriptionName, topicName);
                                if (producerFuture.completeExceptionally(ex)) {
                                    commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(ex), msg);
                                }
                                producers.remove(producerId, producerFuture);
                                return;
                            }
                            buildProducerAndAddTopic(topic, producerId, producerName, requestId, isEncrypted, metadata, schemaVersion, epoch, userProvidedProducerName, topicName, producerAccessMode, topicEpoch, supportsPartialProducer, producerFuture);
                        });
                    }).exceptionally(exception -> {
                        Throwable cause = exception.getCause();
                        log.error("producerId {}, requestId {} : TransactionBuffer recover failed", producerId, requestId, exception);
                        if (producerFuture.completeExceptionally(exception)) {
                            commandSender.sendErrorResponse(requestId, ServiceUnitNotReadyException.getClientErrorCode(cause), cause.getMessage());
                        }
                        producers.remove(producerId, producerFuture);
                        return null;
                    });
                });
            });
            return backlogQuotaCheckFuture;
        }).exceptionally(exception -> {
            Throwable cause = exception.getCause();
            if (cause instanceof BrokerServiceException.TopicBacklogQuotaExceededException) {
                BrokerServiceException.TopicBacklogQuotaExceededException tbqe = (BrokerServiceException.TopicBacklogQuotaExceededException) cause;
                IllegalStateException illegalStateException = new IllegalStateException(tbqe);
                BacklogQuota.RetentionPolicy retentionPolicy = tbqe.getRetentionPolicy();
                if (producerFuture.completeExceptionally(illegalStateException)) {
                    if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_request_hold) {
                        commandSender.sendErrorResponse(requestId, ServerError.ProducerBlockedQuotaExceededError, illegalStateException.getMessage());
                    } else if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_exception) {
                        commandSender.sendErrorResponse(requestId, ServerError.ProducerBlockedQuotaExceededException, illegalStateException.getMessage());
                    }
                }
                producers.remove(producerId, producerFuture);
                return null;
            }
            // Do not print stack traces for expected exceptions
            if (cause instanceof NoSuchElementException) {
                cause = new TopicNotFoundException("Topic Not Found.");
                log.info("[{}] Failed to load topic {}, producerId={}: Topic not found", remoteAddress, topicName, producerId);
            } else if (!Exceptions.areExceptionsPresentInChain(cause, ServiceUnitNotReadyException.class, ManagedLedgerException.class)) {
                log.error("[{}] Failed to create topic {}, producerId={}", remoteAddress, topicName, producerId, exception);
            }
            // client, only if not completed already.
            if (producerFuture.completeExceptionally(exception)) {
                commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(cause), cause.getMessage());
            }
            producers.remove(producerId, producerFuture);
            return null;
        });
        return null;
    }).exceptionally(ex -> {
        logAuthException(remoteAddress, "producer", getPrincipal(), Optional.of(topicName), ex);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, ex.getMessage());
        return null;
    });
}
Also used : CommandAuthResponse(org.apache.pulsar.common.api.proto.CommandAuthResponse) CommandUnsubscribe(org.apache.pulsar.common.api.proto.CommandUnsubscribe) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) StringUtils(org.apache.commons.lang3.StringUtils) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) TxnID(org.apache.pulsar.client.api.transaction.TxnID) MLTransactionMetadataStore(org.apache.pulsar.transaction.coordinator.impl.MLTransactionMetadataStore) TopicOperation(org.apache.pulsar.common.policies.data.TopicOperation) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Map(java.util.Map) BrokerInterceptor(org.apache.pulsar.broker.intercept.BrokerInterceptor) RestException(org.apache.pulsar.broker.web.RestException) NamespaceOperation(org.apache.pulsar.common.policies.data.NamespaceOperation) BaseCommand(org.apache.pulsar.common.api.proto.BaseCommand) CommandAck(org.apache.pulsar.common.api.proto.CommandAck) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) InterceptException(org.apache.pulsar.common.intercept.InterceptException) CommandFlow(org.apache.pulsar.common.api.proto.CommandFlow) CommandConsumerStats(org.apache.pulsar.common.api.proto.CommandConsumerStats) ServerError(org.apache.pulsar.common.api.proto.ServerError) Set(java.util.Set) CommandNewTxn(org.apache.pulsar.common.api.proto.CommandNewTxn) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) ExceptionUtils(org.apache.commons.lang3.exception.ExceptionUtils) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) ChannelOption(io.netty.channel.ChannelOption) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.CommandGetTopicsOfNamespace) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) SchemaType(org.apache.pulsar.common.schema.SchemaType) Commands(org.apache.pulsar.common.protocol.Commands) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) Strings(com.google.common.base.Strings) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) CommandGetOrCreateSchema(org.apache.pulsar.common.api.proto.CommandGetOrCreateSchema) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.ProtocolVersion.v5) CommandGetSchema(org.apache.pulsar.common.api.proto.CommandGetSchema) SchemaInfoUtil(org.apache.pulsar.client.impl.schema.SchemaInfoUtil) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.CommandRedeliverUnacknowledgedMessages) Metadata(org.apache.pulsar.common.naming.Metadata) Promise(io.netty.util.concurrent.Promise) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) lombok.val(lombok.val) PulsarService(org.apache.pulsar.broker.PulsarService) KeySharedMode(org.apache.pulsar.common.api.proto.KeySharedMode) CommandEndTxnOnSubscription(org.apache.pulsar.common.api.proto.CommandEndTxnOnSubscription) CommandConnect(org.apache.pulsar.common.api.proto.CommandConnect) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) MutableInt(org.apache.commons.lang3.mutable.MutableInt) SocketAddress(java.net.SocketAddress) CommandAddPartitionToTxn(org.apache.pulsar.common.api.proto.CommandAddPartitionToTxn) LoggerFactory(org.slf4j.LoggerFactory) AuthData(org.apache.pulsar.common.api.AuthData) Exceptions(org.apache.pulsar.functions.utils.Exceptions) AuthenticationException(javax.naming.AuthenticationException) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync) CommandEndTxnOnPartition(org.apache.pulsar.common.api.proto.CommandEndTxnOnPartition) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BacklogQuotaType(org.apache.pulsar.common.policies.data.BacklogQuota.BacklogQuotaType) Gauge(io.prometheus.client.Gauge) TxnAction(org.apache.pulsar.common.api.proto.TxnAction) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Schema(org.apache.pulsar.common.api.proto.Schema) TransactionMetadataStoreService(org.apache.pulsar.broker.TransactionMetadataStoreService) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IdentityHashMap(java.util.IdentityHashMap) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException) Position(org.apache.bookkeeper.mledger.Position) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) CommandEndTxn(org.apache.pulsar.common.api.proto.CommandEndTxn) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Objects(java.util.Objects) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Optional(java.util.Optional) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) PulsarHandler(org.apache.pulsar.common.protocol.PulsarHandler) CommandTcClientConnectRequest(org.apache.pulsar.common.api.proto.CommandTcClientConnectRequest) TopicName(org.apache.pulsar.common.naming.TopicName) CommandAddSubscriptionToTxn(org.apache.pulsar.common.api.proto.CommandAddSubscriptionToTxn) Entry(org.apache.bookkeeper.mledger.Entry) CommandSend(org.apache.pulsar.common.api.proto.CommandSend) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) TopicLookupBase.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) CommandSubscribe(org.apache.pulsar.common.api.proto.CommandSubscribe) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) CoordinatorException(org.apache.pulsar.transaction.coordinator.exceptions.CoordinatorException) FastThreadLocal(io.netty.util.concurrent.FastThreadLocal) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.CommandPartitionedTopicMetadata) CommandSeek(org.apache.pulsar.common.api.proto.CommandSeek) ConsumerStatsImpl(org.apache.pulsar.common.policies.data.stats.ConsumerStatsImpl) NoSuchElementException(java.util.NoSuchElementException) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.CommandGetLastMessageId) CommandUtils(org.apache.pulsar.common.protocol.CommandUtils) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) FeatureFlags(org.apache.pulsar.common.api.proto.FeatureFlags) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) Commands.newLookupErrorResponse(org.apache.pulsar.common.protocol.Commands.newLookupErrorResponse) TimeUnit(java.util.concurrent.TimeUnit) HAProxyMessage(io.netty.handler.codec.haproxy.HAProxyMessage) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TransactionCoordinatorID(org.apache.pulsar.transaction.coordinator.TransactionCoordinatorID) Collections(java.util.Collections) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) ServerError(org.apache.pulsar.common.api.proto.ServerError) TopicName(org.apache.pulsar.common.naming.TopicName) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) MutableLong(org.apache.commons.lang3.mutable.MutableLong) NoSuchElementException(java.util.NoSuchElementException)

Example 2 with TopicNotFoundException

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

the class ServerCnx method handleSubscribe.

@Override
protected void handleSubscribe(final CommandSubscribe subscribe) {
    checkArgument(state == State.Connected);
    final long requestId = subscribe.getRequestId();
    final long consumerId = subscribe.getConsumerId();
    TopicName topicName = validateTopicName(subscribe.getTopic(), requestId, subscribe);
    if (topicName == null) {
        return;
    }
    if (log.isDebugEnabled()) {
        log.debug("[{}] Handle subscribe command: auth role = {}, original auth role = {}", remoteAddress, authRole, originalPrincipal);
    }
    if (invalidOriginalPrincipal(originalPrincipal)) {
        final String msg = "Valid Proxy Client role should be provided while subscribing ";
        log.warn("[{}] {} with role {} and proxyClientAuthRole {} on topic {}", remoteAddress, msg, authRole, originalPrincipal, topicName);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, msg);
        return;
    }
    final String subscriptionName = subscribe.getSubscription();
    final SubType subType = subscribe.getSubType();
    final String consumerName = subscribe.hasConsumerName() ? subscribe.getConsumerName() : "";
    final boolean isDurable = subscribe.isDurable();
    final MessageIdImpl startMessageId = subscribe.hasStartMessageId() ? new BatchMessageIdImpl(subscribe.getStartMessageId().getLedgerId(), subscribe.getStartMessageId().getEntryId(), subscribe.getStartMessageId().getPartition(), subscribe.getStartMessageId().getBatchIndex()) : null;
    final int priorityLevel = subscribe.hasPriorityLevel() ? subscribe.getPriorityLevel() : 0;
    final boolean readCompacted = subscribe.hasReadCompacted() && subscribe.isReadCompacted();
    final Map<String, String> metadata = CommandUtils.metadataFromCommand(subscribe);
    final InitialPosition initialPosition = subscribe.getInitialPosition();
    final long startMessageRollbackDurationSec = subscribe.hasStartMessageRollbackDurationSec() ? subscribe.getStartMessageRollbackDurationSec() : -1;
    final SchemaData schema = subscribe.hasSchema() ? getSchema(subscribe.getSchema()) : null;
    final boolean isReplicated = subscribe.hasReplicateSubscriptionState() && subscribe.isReplicateSubscriptionState();
    final boolean forceTopicCreation = subscribe.isForceTopicCreation();
    final KeySharedMeta keySharedMeta = subscribe.hasKeySharedMeta() ? new KeySharedMeta().copyFrom(subscribe.getKeySharedMeta()) : emptyKeySharedMeta;
    if (log.isDebugEnabled()) {
        log.debug("Topic name = {}, subscription name = {}, schema is {}", topicName, subscriptionName, schema == null ? "absent" : "present");
    }
    CompletableFuture<Boolean> isAuthorizedFuture = isTopicOperationAllowed(topicName, subscriptionName, TopicOperation.CONSUME);
    // Make sure the consumer future is put into the consumers map first to avoid the same consumer
    // epoch using different consumer futures, and only remove the consumer future from the map
    // if subscribe failed .
    CompletableFuture<Consumer> consumerFuture = new CompletableFuture<>();
    CompletableFuture<Consumer> existingConsumerFuture = consumers.putIfAbsent(consumerId, consumerFuture);
    isAuthorizedFuture.thenApply(isAuthorized -> {
        if (isAuthorized) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Client is authorized to subscribe with role {}", remoteAddress, getPrincipal());
            }
            log.info("[{}] Subscribing on topic {} / {}", remoteAddress, topicName, subscriptionName);
            try {
                Metadata.validateMetadata(metadata, service.getPulsar().getConfiguration().getMaxConsumerMetadataSize());
            } catch (IllegalArgumentException iae) {
                final String msg = iae.getMessage();
                consumers.remove(consumerId, consumerFuture);
                commandSender.sendErrorResponse(requestId, ServerError.MetadataError, msg);
                return null;
            }
            if (existingConsumerFuture != null) {
                if (!existingConsumerFuture.isDone()) {
                    // There was an early request to create a consumer with same consumerId. This can happen
                    // when
                    // client timeout is lower the broker timeouts. We need to wait until the previous
                    // consumer
                    // creation request either complete or fails.
                    log.warn("[{}][{}][{}] Consumer with id is already present on the connection," + " consumerId={}", remoteAddress, topicName, subscriptionName, consumerId);
                    commandSender.sendErrorResponse(requestId, ServerError.ServiceNotReady, "Consumer is already present on the connection");
                } else if (existingConsumerFuture.isCompletedExceptionally()) {
                    ServerError error = getErrorCodeWithErrorLog(existingConsumerFuture, true, String.format("Consumer subscribe failure. remoteAddress: %s, subscription: %s", remoteAddress, subscriptionName));
                    consumers.remove(consumerId, existingConsumerFuture);
                    commandSender.sendErrorResponse(requestId, error, "Consumer that failed is already present on the connection");
                } else {
                    Consumer consumer = existingConsumerFuture.getNow(null);
                    log.info("[{}] Consumer with the same id is already created:" + " consumerId={}, consumer={}", remoteAddress, consumerId, consumer);
                    commandSender.sendSuccessResponse(requestId);
                }
                return null;
            }
            boolean createTopicIfDoesNotExist = forceTopicCreation && service.isAllowAutoTopicCreation(topicName.toString());
            final long consumerEpoch;
            if (subscribe.hasConsumerEpoch()) {
                consumerEpoch = subscribe.getConsumerEpoch();
            } else {
                consumerEpoch = DEFAULT_CONSUMER_EPOCH;
            }
            Optional<Map<String, String>> subscriptionProperties = SubscriptionOption.getPropertiesMap(subscribe.getSubscriptionPropertiesList());
            service.getTopic(topicName.toString(), createTopicIfDoesNotExist).thenCompose(optTopic -> {
                if (!optTopic.isPresent()) {
                    return FutureUtil.failedFuture(new TopicNotFoundException("Topic " + topicName + " does not exist"));
                }
                Topic topic = optTopic.get();
                boolean rejectSubscriptionIfDoesNotExist = isDurable && !service.isAllowAutoSubscriptionCreation(topicName.toString()) && !topic.getSubscriptions().containsKey(subscriptionName) && topic.isPersistent();
                if (rejectSubscriptionIfDoesNotExist) {
                    return FutureUtil.failedFuture(new SubscriptionNotFoundException("Subscription does not exist"));
                }
                SubscriptionOption option = SubscriptionOption.builder().cnx(ServerCnx.this).subscriptionName(subscriptionName).consumerId(consumerId).subType(subType).priorityLevel(priorityLevel).consumerName(consumerName).isDurable(isDurable).startMessageId(startMessageId).metadata(metadata).readCompacted(readCompacted).initialPosition(initialPosition).startMessageRollbackDurationSec(startMessageRollbackDurationSec).replicatedSubscriptionStateArg(isReplicated).keySharedMeta(keySharedMeta).subscriptionProperties(subscriptionProperties).consumerEpoch(consumerEpoch).build();
                if (schema != null) {
                    return topic.addSchemaIfIdleOrCheckCompatible(schema).thenCompose(v -> topic.subscribe(option));
                } else {
                    return topic.subscribe(option);
                }
            }).thenAccept(consumer -> {
                if (consumerFuture.complete(consumer)) {
                    log.info("[{}] Created subscription on topic {} / {}", remoteAddress, topicName, subscriptionName);
                    commandSender.sendSuccessResponse(requestId);
                    if (getBrokerService().getInterceptor() != null) {
                        getBrokerService().getInterceptor().consumerCreated(this, consumer, metadata);
                    }
                } else {
                    // The consumer future was completed before by a close command
                    try {
                        consumer.close();
                        log.info("[{}] Cleared consumer created after timeout on client side {}", remoteAddress, consumer);
                    } catch (BrokerServiceException e) {
                        log.warn("[{}] Error closing consumer created" + " after timeout on client side {}: {}", remoteAddress, consumer, e.getMessage());
                    }
                    consumers.remove(consumerId, consumerFuture);
                }
            }).exceptionally(exception -> {
                if (exception.getCause() instanceof ConsumerBusyException) {
                    if (log.isDebugEnabled()) {
                        log.debug("[{}][{}][{}] Failed to create consumer because exclusive consumer" + " is already connected: {}", remoteAddress, topicName, subscriptionName, exception.getCause().getMessage());
                    }
                } else if (exception.getCause() instanceof BrokerServiceException) {
                    log.warn("[{}][{}][{}] Failed to create consumer: consumerId={}, {}", remoteAddress, topicName, subscriptionName, consumerId, exception.getCause().getMessage());
                } else {
                    log.warn("[{}][{}][{}] Failed to create consumer: consumerId={}, {}", remoteAddress, topicName, subscriptionName, consumerId, exception.getCause().getMessage(), exception);
                }
                // back to client, only if not completed already.
                if (consumerFuture.completeExceptionally(exception)) {
                    commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(exception), exception.getCause().getMessage());
                }
                consumers.remove(consumerId, consumerFuture);
                return null;
            });
        } else {
            String msg = "Client is not authorized to subscribe";
            log.warn("[{}] {} with role {}", remoteAddress, msg, getPrincipal());
            consumers.remove(consumerId, consumerFuture);
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
        }
        return null;
    }).exceptionally(ex -> {
        logAuthException(remoteAddress, "subscribe", getPrincipal(), Optional.of(topicName), ex);
        consumers.remove(consumerId, consumerFuture);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, ex.getMessage());
        return null;
    });
}
Also used : CommandAuthResponse(org.apache.pulsar.common.api.proto.CommandAuthResponse) CommandUnsubscribe(org.apache.pulsar.common.api.proto.CommandUnsubscribe) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) StringUtils(org.apache.commons.lang3.StringUtils) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) TxnID(org.apache.pulsar.client.api.transaction.TxnID) MLTransactionMetadataStore(org.apache.pulsar.transaction.coordinator.impl.MLTransactionMetadataStore) TopicOperation(org.apache.pulsar.common.policies.data.TopicOperation) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Map(java.util.Map) BrokerInterceptor(org.apache.pulsar.broker.intercept.BrokerInterceptor) RestException(org.apache.pulsar.broker.web.RestException) NamespaceOperation(org.apache.pulsar.common.policies.data.NamespaceOperation) BaseCommand(org.apache.pulsar.common.api.proto.BaseCommand) CommandAck(org.apache.pulsar.common.api.proto.CommandAck) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) InterceptException(org.apache.pulsar.common.intercept.InterceptException) CommandFlow(org.apache.pulsar.common.api.proto.CommandFlow) CommandConsumerStats(org.apache.pulsar.common.api.proto.CommandConsumerStats) ServerError(org.apache.pulsar.common.api.proto.ServerError) Set(java.util.Set) CommandNewTxn(org.apache.pulsar.common.api.proto.CommandNewTxn) TopicList(org.apache.pulsar.common.topics.TopicList) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) ExceptionUtils(org.apache.commons.lang3.exception.ExceptionUtils) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) ChannelOption(io.netty.channel.ChannelOption) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.CommandGetTopicsOfNamespace) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) SchemaType(org.apache.pulsar.common.schema.SchemaType) Commands(org.apache.pulsar.common.protocol.Commands) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) Strings(com.google.common.base.Strings) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) CommandGetOrCreateSchema(org.apache.pulsar.common.api.proto.CommandGetOrCreateSchema) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.ProtocolVersion.v5) CommandGetSchema(org.apache.pulsar.common.api.proto.CommandGetSchema) SchemaInfoUtil(org.apache.pulsar.client.impl.schema.SchemaInfoUtil) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.CommandRedeliverUnacknowledgedMessages) Metadata(org.apache.pulsar.common.naming.Metadata) Promise(io.netty.util.concurrent.Promise) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) lombok.val(lombok.val) PulsarService(org.apache.pulsar.broker.PulsarService) KeySharedMode(org.apache.pulsar.common.api.proto.KeySharedMode) CommandEndTxnOnSubscription(org.apache.pulsar.common.api.proto.CommandEndTxnOnSubscription) CommandConnect(org.apache.pulsar.common.api.proto.CommandConnect) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) MutableInt(org.apache.commons.lang3.mutable.MutableInt) SocketAddress(java.net.SocketAddress) CommandAddPartitionToTxn(org.apache.pulsar.common.api.proto.CommandAddPartitionToTxn) LoggerFactory(org.slf4j.LoggerFactory) AuthData(org.apache.pulsar.common.api.AuthData) Exceptions(org.apache.pulsar.functions.utils.Exceptions) AuthenticationException(javax.naming.AuthenticationException) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync) CommandEndTxnOnPartition(org.apache.pulsar.common.api.proto.CommandEndTxnOnPartition) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BacklogQuotaType(org.apache.pulsar.common.policies.data.BacklogQuota.BacklogQuotaType) Gauge(io.prometheus.client.Gauge) TxnAction(org.apache.pulsar.common.api.proto.TxnAction) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Schema(org.apache.pulsar.common.api.proto.Schema) TransactionMetadataStoreService(org.apache.pulsar.broker.TransactionMetadataStoreService) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IdentityHashMap(java.util.IdentityHashMap) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException) Position(org.apache.bookkeeper.mledger.Position) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) CommandEndTxn(org.apache.pulsar.common.api.proto.CommandEndTxn) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Objects(java.util.Objects) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Optional(java.util.Optional) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) PulsarHandler(org.apache.pulsar.common.protocol.PulsarHandler) CommandTcClientConnectRequest(org.apache.pulsar.common.api.proto.CommandTcClientConnectRequest) TopicName(org.apache.pulsar.common.naming.TopicName) CommandAddSubscriptionToTxn(org.apache.pulsar.common.api.proto.CommandAddSubscriptionToTxn) Entry(org.apache.bookkeeper.mledger.Entry) CommandSend(org.apache.pulsar.common.api.proto.CommandSend) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) TopicLookupBase.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) CommandSubscribe(org.apache.pulsar.common.api.proto.CommandSubscribe) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) CoordinatorException(org.apache.pulsar.transaction.coordinator.exceptions.CoordinatorException) FastThreadLocal(io.netty.util.concurrent.FastThreadLocal) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.CommandPartitionedTopicMetadata) ChannelFutureListener(io.netty.channel.ChannelFutureListener) CommandSeek(org.apache.pulsar.common.api.proto.CommandSeek) ConsumerStatsImpl(org.apache.pulsar.common.policies.data.stats.ConsumerStatsImpl) NoSuchElementException(java.util.NoSuchElementException) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.CommandGetLastMessageId) CommandUtils(org.apache.pulsar.common.protocol.CommandUtils) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) FeatureFlags(org.apache.pulsar.common.api.proto.FeatureFlags) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) Commands.newLookupErrorResponse(org.apache.pulsar.common.protocol.Commands.newLookupErrorResponse) TimeUnit(java.util.concurrent.TimeUnit) HAProxyMessage(io.netty.handler.codec.haproxy.HAProxyMessage) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TransactionCoordinatorID(org.apache.pulsar.transaction.coordinator.TransactionCoordinatorID) Collections(java.util.Collections) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) CompletableFuture(java.util.concurrent.CompletableFuture) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) Optional(java.util.Optional) ServerError(org.apache.pulsar.common.api.proto.ServerError) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) TopicName(org.apache.pulsar.common.naming.TopicName) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException)

Example 3 with TopicNotFoundException

use of org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException 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 long epoch = cmdProducer.getEpoch();
    final boolean userProvidedProducerName = cmdProducer.isUserProvidedProducerName();
    final boolean isEncrypted = cmdProducer.isEncrypted();
    final Map<String, String> metadata = CommandUtils.metadataFromCommand(cmdProducer);
    final SchemaData schema = cmdProducer.hasSchema() ? getSchema(cmdProducer.getSchema()) : null;
    final ProducerAccessMode producerAccessMode = cmdProducer.getProducerAccessMode();
    final Optional<Long> topicEpoch = cmdProducer.hasTopicEpoch() ? Optional.of(cmdProducer.getTopicEpoch()) : Optional.empty();
    final boolean isTxnEnabled = cmdProducer.isTxnEnabled();
    final String initialSubscriptionName = cmdProducer.hasInitialSubscriptionName() ? cmdProducer.getInitialSubscriptionName() : null;
    final boolean supportsPartialProducer = supportsPartialProducer();
    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);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, msg);
        return;
    }
    CompletableFuture<Boolean> isAuthorizedFuture = isTopicOperationAllowed(topicName, TopicOperation.PRODUCE);
    if (!Strings.isNullOrEmpty(initialSubscriptionName)) {
        isAuthorizedFuture = isAuthorizedFuture.thenCombine(isTopicOperationAllowed(topicName, TopicOperation.SUBSCRIBE), (canProduce, canSubscribe) -> canProduce && canSubscribe);
    }
    isAuthorizedFuture.thenApply(isAuthorized -> {
        if (!isAuthorized) {
            String msg = "Client is not authorized to Produce";
            log.warn("[{}] {} with role {}", remoteAddress, msg, getPrincipal());
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("[{}] Client is authorized to Produce with role {}", remoteAddress, getPrincipal());
        }
        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:" + " producerId={}, producer={}", remoteAddress, producerId, producer);
                commandSender.sendProducerSuccessResponse(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 than the broker timeouts.
                // We need to wait until the previous producer creation request
                // either complete or fails.
                ServerError error = null;
                if (!existingProducerFuture.isDone()) {
                    error = ServerError.ServiceNotReady;
                } else {
                    error = getErrorCode(existingProducerFuture);
                    // remove producer with producerId as it's already completed with exception
                    producers.remove(producerId, existingProducerFuture);
                }
                log.warn("[{}][{}] Producer with id is already present on the connection, producerId={}", remoteAddress, topicName, producerId);
                commandSender.sendErrorResponse(requestId, error, "Producer is already present on the connection");
                return null;
            }
        }
        log.info("[{}][{}] Creating producer. producerId={}, schema is {}", remoteAddress, topicName, producerId, schema == null ? "absent" : "present");
        service.getOrCreateTopic(topicName.toString()).thenCompose((Topic topic) -> {
            // Before creating producer, check if backlog quota exceeded
            // on topic for size based limit and time based limit
            CompletableFuture<Void> backlogQuotaCheckFuture = CompletableFuture.allOf(topic.checkBacklogQuotaExceeded(producerName, BacklogQuotaType.destination_storage), topic.checkBacklogQuotaExceeded(producerName, BacklogQuotaType.message_age));
            backlogQuotaCheckFuture.thenRun(() -> {
                // Check whether the producer will publish encrypted messages or not
                if ((topic.isEncryptionRequired() || encryptionRequireOnProducer) && !isEncrypted) {
                    String msg = String.format("Encryption is required in %s", topicName);
                    log.warn("[{}] {}", remoteAddress, msg);
                    if (producerFuture.completeExceptionally(new ServerMetadataException(msg))) {
                        commandSender.sendErrorResponse(requestId, ServerError.MetadataError, msg);
                    }
                    producers.remove(producerId, producerFuture);
                    return;
                }
                disableTcpNoDelayIfNeeded(topicName.toString(), producerName);
                CompletableFuture<SchemaVersion> schemaVersionFuture = tryAddSchema(topic, schema);
                schemaVersionFuture.exceptionally(exception -> {
                    if (producerFuture.completeExceptionally(exception)) {
                        String message = exception.getMessage();
                        if (exception.getCause() != null) {
                            message += (" caused by " + exception.getCause());
                        }
                        commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(exception), message);
                    }
                    log.error("Try add schema failed, remote address {}, topic {}, producerId {}", remoteAddress, topicName, producerId, exception);
                    producers.remove(producerId, producerFuture);
                    return null;
                });
                schemaVersionFuture.thenAccept(schemaVersion -> {
                    topic.checkIfTransactionBufferRecoverCompletely(isTxnEnabled).thenAccept(future -> {
                        CompletableFuture<Subscription> createInitSubFuture;
                        if (!Strings.isNullOrEmpty(initialSubscriptionName) && topic.isPersistent() && !topic.getSubscriptions().containsKey(initialSubscriptionName)) {
                            if (!this.getBrokerService().isAllowAutoSubscriptionCreation(topicName)) {
                                String msg = "Could not create the initial subscription due to the auto subscription " + "creation is not allowed.";
                                if (producerFuture.completeExceptionally(new BrokerServiceException.NotAllowedException(msg))) {
                                    log.warn("[{}] {} initialSubscriptionName: {}, topic: {}", remoteAddress, msg, initialSubscriptionName, topicName);
                                    commandSender.sendErrorResponse(requestId, ServerError.NotAllowedError, msg);
                                }
                                producers.remove(producerId, producerFuture);
                                return;
                            }
                            createInitSubFuture = topic.createSubscription(initialSubscriptionName, InitialPosition.Earliest, false, null);
                        } else {
                            createInitSubFuture = CompletableFuture.completedFuture(null);
                        }
                        createInitSubFuture.whenComplete((sub, ex) -> {
                            if (ex != null) {
                                String msg = "Failed to create the initial subscription: " + ex.getCause().getMessage();
                                log.warn("[{}] {} initialSubscriptionName: {}, topic: {}", remoteAddress, msg, initialSubscriptionName, topicName);
                                if (producerFuture.completeExceptionally(ex)) {
                                    commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(ex), msg);
                                }
                                producers.remove(producerId, producerFuture);
                                return;
                            }
                            buildProducerAndAddTopic(topic, producerId, producerName, requestId, isEncrypted, metadata, schemaVersion, epoch, userProvidedProducerName, topicName, producerAccessMode, topicEpoch, supportsPartialProducer, producerFuture);
                        });
                    }).exceptionally(exception -> {
                        Throwable cause = exception.getCause();
                        log.error("producerId {}, requestId {} : TransactionBuffer recover failed", producerId, requestId, exception);
                        if (producerFuture.completeExceptionally(exception)) {
                            commandSender.sendErrorResponse(requestId, ServiceUnitNotReadyException.getClientErrorCode(cause), cause.getMessage());
                        }
                        producers.remove(producerId, producerFuture);
                        return null;
                    });
                });
            });
            return backlogQuotaCheckFuture;
        }).exceptionally(exception -> {
            Throwable cause = exception.getCause();
            if (cause instanceof BrokerServiceException.TopicBacklogQuotaExceededException) {
                BrokerServiceException.TopicBacklogQuotaExceededException tbqe = (BrokerServiceException.TopicBacklogQuotaExceededException) cause;
                IllegalStateException illegalStateException = new IllegalStateException(tbqe);
                BacklogQuota.RetentionPolicy retentionPolicy = tbqe.getRetentionPolicy();
                if (producerFuture.completeExceptionally(illegalStateException)) {
                    if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_request_hold) {
                        commandSender.sendErrorResponse(requestId, ServerError.ProducerBlockedQuotaExceededError, illegalStateException.getMessage());
                    } else if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_exception) {
                        commandSender.sendErrorResponse(requestId, ServerError.ProducerBlockedQuotaExceededException, illegalStateException.getMessage());
                    }
                }
                producers.remove(producerId, producerFuture);
                return null;
            }
            // Do not print stack traces for expected exceptions
            if (cause instanceof NoSuchElementException) {
                cause = new TopicNotFoundException("Topic Not Found.");
                log.info("[{}] Failed to load topic {}, producerId={}: Topic not found", remoteAddress, topicName, producerId);
            } else if (!Exceptions.areExceptionsPresentInChain(cause, ServiceUnitNotReadyException.class, ManagedLedgerException.class)) {
                log.error("[{}] Failed to create topic {}, producerId={}", remoteAddress, topicName, producerId, exception);
            }
            // client, only if not completed already.
            if (producerFuture.completeExceptionally(exception)) {
                commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(cause), cause.getMessage());
            }
            producers.remove(producerId, producerFuture);
            return null;
        });
        return null;
    }).exceptionally(ex -> {
        logAuthException(remoteAddress, "producer", getPrincipal(), Optional.of(topicName), ex);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, ex.getMessage());
        return null;
    });
}
Also used : CommandAuthResponse(org.apache.pulsar.common.api.proto.CommandAuthResponse) CommandUnsubscribe(org.apache.pulsar.common.api.proto.CommandUnsubscribe) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) StringUtils(org.apache.commons.lang3.StringUtils) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) TxnID(org.apache.pulsar.client.api.transaction.TxnID) MLTransactionMetadataStore(org.apache.pulsar.transaction.coordinator.impl.MLTransactionMetadataStore) TopicOperation(org.apache.pulsar.common.policies.data.TopicOperation) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Map(java.util.Map) BrokerInterceptor(org.apache.pulsar.broker.intercept.BrokerInterceptor) RestException(org.apache.pulsar.broker.web.RestException) NamespaceOperation(org.apache.pulsar.common.policies.data.NamespaceOperation) BaseCommand(org.apache.pulsar.common.api.proto.BaseCommand) CommandAck(org.apache.pulsar.common.api.proto.CommandAck) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) InterceptException(org.apache.pulsar.common.intercept.InterceptException) CommandFlow(org.apache.pulsar.common.api.proto.CommandFlow) CommandConsumerStats(org.apache.pulsar.common.api.proto.CommandConsumerStats) ServerError(org.apache.pulsar.common.api.proto.ServerError) Set(java.util.Set) CommandNewTxn(org.apache.pulsar.common.api.proto.CommandNewTxn) TopicList(org.apache.pulsar.common.topics.TopicList) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) ExceptionUtils(org.apache.commons.lang3.exception.ExceptionUtils) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) ChannelOption(io.netty.channel.ChannelOption) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.CommandGetTopicsOfNamespace) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) SchemaType(org.apache.pulsar.common.schema.SchemaType) Commands(org.apache.pulsar.common.protocol.Commands) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) Strings(com.google.common.base.Strings) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) CommandGetOrCreateSchema(org.apache.pulsar.common.api.proto.CommandGetOrCreateSchema) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.ProtocolVersion.v5) CommandGetSchema(org.apache.pulsar.common.api.proto.CommandGetSchema) SchemaInfoUtil(org.apache.pulsar.client.impl.schema.SchemaInfoUtil) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.CommandRedeliverUnacknowledgedMessages) Metadata(org.apache.pulsar.common.naming.Metadata) Promise(io.netty.util.concurrent.Promise) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) lombok.val(lombok.val) PulsarService(org.apache.pulsar.broker.PulsarService) KeySharedMode(org.apache.pulsar.common.api.proto.KeySharedMode) CommandEndTxnOnSubscription(org.apache.pulsar.common.api.proto.CommandEndTxnOnSubscription) CommandConnect(org.apache.pulsar.common.api.proto.CommandConnect) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) MutableInt(org.apache.commons.lang3.mutable.MutableInt) SocketAddress(java.net.SocketAddress) CommandAddPartitionToTxn(org.apache.pulsar.common.api.proto.CommandAddPartitionToTxn) LoggerFactory(org.slf4j.LoggerFactory) AuthData(org.apache.pulsar.common.api.AuthData) Exceptions(org.apache.pulsar.functions.utils.Exceptions) AuthenticationException(javax.naming.AuthenticationException) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync) CommandEndTxnOnPartition(org.apache.pulsar.common.api.proto.CommandEndTxnOnPartition) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BacklogQuotaType(org.apache.pulsar.common.policies.data.BacklogQuota.BacklogQuotaType) Gauge(io.prometheus.client.Gauge) TxnAction(org.apache.pulsar.common.api.proto.TxnAction) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Schema(org.apache.pulsar.common.api.proto.Schema) TransactionMetadataStoreService(org.apache.pulsar.broker.TransactionMetadataStoreService) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IdentityHashMap(java.util.IdentityHashMap) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException) Position(org.apache.bookkeeper.mledger.Position) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) CommandEndTxn(org.apache.pulsar.common.api.proto.CommandEndTxn) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Objects(java.util.Objects) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Optional(java.util.Optional) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) PulsarHandler(org.apache.pulsar.common.protocol.PulsarHandler) CommandTcClientConnectRequest(org.apache.pulsar.common.api.proto.CommandTcClientConnectRequest) TopicName(org.apache.pulsar.common.naming.TopicName) CommandAddSubscriptionToTxn(org.apache.pulsar.common.api.proto.CommandAddSubscriptionToTxn) Entry(org.apache.bookkeeper.mledger.Entry) CommandSend(org.apache.pulsar.common.api.proto.CommandSend) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) TopicLookupBase.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) CommandSubscribe(org.apache.pulsar.common.api.proto.CommandSubscribe) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) CoordinatorException(org.apache.pulsar.transaction.coordinator.exceptions.CoordinatorException) FastThreadLocal(io.netty.util.concurrent.FastThreadLocal) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.CommandPartitionedTopicMetadata) ChannelFutureListener(io.netty.channel.ChannelFutureListener) CommandSeek(org.apache.pulsar.common.api.proto.CommandSeek) ConsumerStatsImpl(org.apache.pulsar.common.policies.data.stats.ConsumerStatsImpl) NoSuchElementException(java.util.NoSuchElementException) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.CommandGetLastMessageId) CommandUtils(org.apache.pulsar.common.protocol.CommandUtils) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) FeatureFlags(org.apache.pulsar.common.api.proto.FeatureFlags) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) Commands.newLookupErrorResponse(org.apache.pulsar.common.protocol.Commands.newLookupErrorResponse) TimeUnit(java.util.concurrent.TimeUnit) HAProxyMessage(io.netty.handler.codec.haproxy.HAProxyMessage) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TransactionCoordinatorID(org.apache.pulsar.transaction.coordinator.TransactionCoordinatorID) Collections(java.util.Collections) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) ServerError(org.apache.pulsar.common.api.proto.ServerError) TopicName(org.apache.pulsar.common.naming.TopicName) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) MutableLong(org.apache.commons.lang3.mutable.MutableLong) NoSuchElementException(java.util.NoSuchElementException)

Example 4 with TopicNotFoundException

use of org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException in project pulsar by yahoo.

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 long epoch = cmdProducer.getEpoch();
    final boolean userProvidedProducerName = cmdProducer.isUserProvidedProducerName();
    final boolean isEncrypted = cmdProducer.isEncrypted();
    final Map<String, String> metadata = CommandUtils.metadataFromCommand(cmdProducer);
    final SchemaData schema = cmdProducer.hasSchema() ? getSchema(cmdProducer.getSchema()) : null;
    final ProducerAccessMode producerAccessMode = cmdProducer.getProducerAccessMode();
    final Optional<Long> topicEpoch = cmdProducer.hasTopicEpoch() ? Optional.of(cmdProducer.getTopicEpoch()) : Optional.empty();
    final boolean isTxnEnabled = cmdProducer.isTxnEnabled();
    final String initialSubscriptionName = cmdProducer.hasInitialSubscriptionName() ? cmdProducer.getInitialSubscriptionName() : null;
    final boolean supportsPartialProducer = supportsPartialProducer();
    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);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, msg);
        return;
    }
    CompletableFuture<Boolean> isAuthorizedFuture = isTopicOperationAllowed(topicName, TopicOperation.PRODUCE);
    if (!Strings.isNullOrEmpty(initialSubscriptionName)) {
        isAuthorizedFuture = isAuthorizedFuture.thenCombine(isTopicOperationAllowed(topicName, TopicOperation.SUBSCRIBE), (canProduce, canSubscribe) -> canProduce && canSubscribe);
    }
    isAuthorizedFuture.thenApply(isAuthorized -> {
        if (!isAuthorized) {
            String msg = "Client is not authorized to Produce";
            log.warn("[{}] {} with role {}", remoteAddress, msg, getPrincipal());
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("[{}] Client is authorized to Produce with role {}", remoteAddress, getPrincipal());
        }
        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:" + " producerId={}, producer={}", remoteAddress, producerId, producer);
                commandSender.sendProducerSuccessResponse(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 than the broker timeouts.
                // We need to wait until the previous producer creation request
                // either complete or fails.
                ServerError error = null;
                if (!existingProducerFuture.isDone()) {
                    error = ServerError.ServiceNotReady;
                } else {
                    error = getErrorCode(existingProducerFuture);
                    // remove producer with producerId as it's already completed with exception
                    producers.remove(producerId, existingProducerFuture);
                }
                log.warn("[{}][{}] Producer with id is already present on the connection, producerId={}", remoteAddress, topicName, producerId);
                commandSender.sendErrorResponse(requestId, error, "Producer is already present on the connection");
                return null;
            }
        }
        log.info("[{}][{}] Creating producer. producerId={}, schema is {}", remoteAddress, topicName, producerId, schema == null ? "absent" : "present");
        service.getOrCreateTopic(topicName.toString()).thenCompose((Topic topic) -> {
            // Before creating producer, check if backlog quota exceeded
            // on topic for size based limit and time based limit
            CompletableFuture<Void> backlogQuotaCheckFuture = CompletableFuture.allOf(topic.checkBacklogQuotaExceeded(producerName, BacklogQuotaType.destination_storage), topic.checkBacklogQuotaExceeded(producerName, BacklogQuotaType.message_age));
            backlogQuotaCheckFuture.thenRun(() -> {
                // Check whether the producer will publish encrypted messages or not
                if ((topic.isEncryptionRequired() || encryptionRequireOnProducer) && !isEncrypted) {
                    String msg = String.format("Encryption is required in %s", topicName);
                    log.warn("[{}] {}", remoteAddress, msg);
                    if (producerFuture.completeExceptionally(new ServerMetadataException(msg))) {
                        commandSender.sendErrorResponse(requestId, ServerError.MetadataError, msg);
                    }
                    producers.remove(producerId, producerFuture);
                    return;
                }
                disableTcpNoDelayIfNeeded(topicName.toString(), producerName);
                CompletableFuture<SchemaVersion> schemaVersionFuture = tryAddSchema(topic, schema);
                schemaVersionFuture.exceptionally(exception -> {
                    if (producerFuture.completeExceptionally(exception)) {
                        String message = exception.getMessage();
                        if (exception.getCause() != null) {
                            message += (" caused by " + exception.getCause());
                        }
                        commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(exception), message);
                    }
                    log.error("Try add schema failed, remote address {}, topic {}, producerId {}", remoteAddress, topicName, producerId, exception);
                    producers.remove(producerId, producerFuture);
                    return null;
                });
                schemaVersionFuture.thenAccept(schemaVersion -> {
                    topic.checkIfTransactionBufferRecoverCompletely(isTxnEnabled).thenAccept(future -> {
                        CompletableFuture<Subscription> createInitSubFuture;
                        if (!Strings.isNullOrEmpty(initialSubscriptionName) && topic.isPersistent() && !topic.getSubscriptions().containsKey(initialSubscriptionName)) {
                            if (!this.getBrokerService().isAllowAutoSubscriptionCreation(topicName)) {
                                String msg = "Could not create the initial subscription due to the auto subscription " + "creation is not allowed.";
                                if (producerFuture.completeExceptionally(new BrokerServiceException.NotAllowedException(msg))) {
                                    log.warn("[{}] {} initialSubscriptionName: {}, topic: {}", remoteAddress, msg, initialSubscriptionName, topicName);
                                    commandSender.sendErrorResponse(requestId, ServerError.NotAllowedError, msg);
                                }
                                producers.remove(producerId, producerFuture);
                                return;
                            }
                            createInitSubFuture = topic.createSubscription(initialSubscriptionName, InitialPosition.Earliest, false, null);
                        } else {
                            createInitSubFuture = CompletableFuture.completedFuture(null);
                        }
                        createInitSubFuture.whenComplete((sub, ex) -> {
                            if (ex != null) {
                                String msg = "Failed to create the initial subscription: " + ex.getCause().getMessage();
                                log.warn("[{}] {} initialSubscriptionName: {}, topic: {}", remoteAddress, msg, initialSubscriptionName, topicName);
                                if (producerFuture.completeExceptionally(ex)) {
                                    commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(ex), msg);
                                }
                                producers.remove(producerId, producerFuture);
                                return;
                            }
                            buildProducerAndAddTopic(topic, producerId, producerName, requestId, isEncrypted, metadata, schemaVersion, epoch, userProvidedProducerName, topicName, producerAccessMode, topicEpoch, supportsPartialProducer, producerFuture);
                        });
                    }).exceptionally(exception -> {
                        Throwable cause = exception.getCause();
                        log.error("producerId {}, requestId {} : TransactionBuffer recover failed", producerId, requestId, exception);
                        if (producerFuture.completeExceptionally(exception)) {
                            commandSender.sendErrorResponse(requestId, ServiceUnitNotReadyException.getClientErrorCode(cause), cause.getMessage());
                        }
                        producers.remove(producerId, producerFuture);
                        return null;
                    });
                });
            });
            return backlogQuotaCheckFuture;
        }).exceptionally(exception -> {
            Throwable cause = exception.getCause();
            if (cause instanceof BrokerServiceException.TopicBacklogQuotaExceededException) {
                BrokerServiceException.TopicBacklogQuotaExceededException tbqe = (BrokerServiceException.TopicBacklogQuotaExceededException) cause;
                IllegalStateException illegalStateException = new IllegalStateException(tbqe);
                BacklogQuota.RetentionPolicy retentionPolicy = tbqe.getRetentionPolicy();
                if (producerFuture.completeExceptionally(illegalStateException)) {
                    if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_request_hold) {
                        commandSender.sendErrorResponse(requestId, ServerError.ProducerBlockedQuotaExceededError, illegalStateException.getMessage());
                    } else if (retentionPolicy == BacklogQuota.RetentionPolicy.producer_exception) {
                        commandSender.sendErrorResponse(requestId, ServerError.ProducerBlockedQuotaExceededException, illegalStateException.getMessage());
                    }
                }
                producers.remove(producerId, producerFuture);
                return null;
            }
            // Do not print stack traces for expected exceptions
            if (cause instanceof NoSuchElementException) {
                cause = new TopicNotFoundException("Topic Not Found.");
                log.info("[{}] Failed to load topic {}, producerId={}: Topic not found", remoteAddress, topicName, producerId);
            } else if (!Exceptions.areExceptionsPresentInChain(cause, ServiceUnitNotReadyException.class, ManagedLedgerException.class)) {
                log.error("[{}] Failed to create topic {}, producerId={}", remoteAddress, topicName, producerId, exception);
            }
            // client, only if not completed already.
            if (producerFuture.completeExceptionally(exception)) {
                commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(cause), cause.getMessage());
            }
            producers.remove(producerId, producerFuture);
            return null;
        });
        return null;
    }).exceptionally(ex -> {
        logAuthException(remoteAddress, "producer", getPrincipal(), Optional.of(topicName), ex);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, ex.getMessage());
        return null;
    });
}
Also used : CommandAuthResponse(org.apache.pulsar.common.api.proto.CommandAuthResponse) CommandUnsubscribe(org.apache.pulsar.common.api.proto.CommandUnsubscribe) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) StringUtils(org.apache.commons.lang3.StringUtils) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) TxnID(org.apache.pulsar.client.api.transaction.TxnID) MLTransactionMetadataStore(org.apache.pulsar.transaction.coordinator.impl.MLTransactionMetadataStore) TopicOperation(org.apache.pulsar.common.policies.data.TopicOperation) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Map(java.util.Map) BrokerInterceptor(org.apache.pulsar.broker.intercept.BrokerInterceptor) RestException(org.apache.pulsar.broker.web.RestException) NamespaceOperation(org.apache.pulsar.common.policies.data.NamespaceOperation) BaseCommand(org.apache.pulsar.common.api.proto.BaseCommand) CommandAck(org.apache.pulsar.common.api.proto.CommandAck) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) InterceptException(org.apache.pulsar.common.intercept.InterceptException) CommandFlow(org.apache.pulsar.common.api.proto.CommandFlow) CommandConsumerStats(org.apache.pulsar.common.api.proto.CommandConsumerStats) ServerError(org.apache.pulsar.common.api.proto.ServerError) Set(java.util.Set) CommandNewTxn(org.apache.pulsar.common.api.proto.CommandNewTxn) TopicList(org.apache.pulsar.common.topics.TopicList) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) ExceptionUtils(org.apache.commons.lang3.exception.ExceptionUtils) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) ChannelOption(io.netty.channel.ChannelOption) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.CommandGetTopicsOfNamespace) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) SchemaType(org.apache.pulsar.common.schema.SchemaType) Commands(org.apache.pulsar.common.protocol.Commands) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) Strings(com.google.common.base.Strings) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) CommandGetOrCreateSchema(org.apache.pulsar.common.api.proto.CommandGetOrCreateSchema) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.ProtocolVersion.v5) CommandGetSchema(org.apache.pulsar.common.api.proto.CommandGetSchema) SchemaInfoUtil(org.apache.pulsar.client.impl.schema.SchemaInfoUtil) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.CommandRedeliverUnacknowledgedMessages) Metadata(org.apache.pulsar.common.naming.Metadata) Promise(io.netty.util.concurrent.Promise) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) lombok.val(lombok.val) PulsarService(org.apache.pulsar.broker.PulsarService) KeySharedMode(org.apache.pulsar.common.api.proto.KeySharedMode) CommandEndTxnOnSubscription(org.apache.pulsar.common.api.proto.CommandEndTxnOnSubscription) CommandConnect(org.apache.pulsar.common.api.proto.CommandConnect) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) MutableInt(org.apache.commons.lang3.mutable.MutableInt) SocketAddress(java.net.SocketAddress) CommandAddPartitionToTxn(org.apache.pulsar.common.api.proto.CommandAddPartitionToTxn) LoggerFactory(org.slf4j.LoggerFactory) AuthData(org.apache.pulsar.common.api.AuthData) Exceptions(org.apache.pulsar.functions.utils.Exceptions) AuthenticationException(javax.naming.AuthenticationException) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync) CommandEndTxnOnPartition(org.apache.pulsar.common.api.proto.CommandEndTxnOnPartition) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BacklogQuotaType(org.apache.pulsar.common.policies.data.BacklogQuota.BacklogQuotaType) Gauge(io.prometheus.client.Gauge) TxnAction(org.apache.pulsar.common.api.proto.TxnAction) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Schema(org.apache.pulsar.common.api.proto.Schema) TransactionMetadataStoreService(org.apache.pulsar.broker.TransactionMetadataStoreService) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IdentityHashMap(java.util.IdentityHashMap) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException) Position(org.apache.bookkeeper.mledger.Position) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) CommandEndTxn(org.apache.pulsar.common.api.proto.CommandEndTxn) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Objects(java.util.Objects) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Optional(java.util.Optional) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) PulsarHandler(org.apache.pulsar.common.protocol.PulsarHandler) CommandTcClientConnectRequest(org.apache.pulsar.common.api.proto.CommandTcClientConnectRequest) TopicName(org.apache.pulsar.common.naming.TopicName) CommandAddSubscriptionToTxn(org.apache.pulsar.common.api.proto.CommandAddSubscriptionToTxn) Entry(org.apache.bookkeeper.mledger.Entry) CommandSend(org.apache.pulsar.common.api.proto.CommandSend) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) TopicLookupBase.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) CommandSubscribe(org.apache.pulsar.common.api.proto.CommandSubscribe) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) CoordinatorException(org.apache.pulsar.transaction.coordinator.exceptions.CoordinatorException) FastThreadLocal(io.netty.util.concurrent.FastThreadLocal) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.CommandPartitionedTopicMetadata) ChannelFutureListener(io.netty.channel.ChannelFutureListener) CommandSeek(org.apache.pulsar.common.api.proto.CommandSeek) ConsumerStatsImpl(org.apache.pulsar.common.policies.data.stats.ConsumerStatsImpl) NoSuchElementException(java.util.NoSuchElementException) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.CommandGetLastMessageId) CommandUtils(org.apache.pulsar.common.protocol.CommandUtils) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) FeatureFlags(org.apache.pulsar.common.api.proto.FeatureFlags) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) Commands.newLookupErrorResponse(org.apache.pulsar.common.protocol.Commands.newLookupErrorResponse) TimeUnit(java.util.concurrent.TimeUnit) HAProxyMessage(io.netty.handler.codec.haproxy.HAProxyMessage) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TransactionCoordinatorID(org.apache.pulsar.transaction.coordinator.TransactionCoordinatorID) Collections(java.util.Collections) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) ServerError(org.apache.pulsar.common.api.proto.ServerError) TopicName(org.apache.pulsar.common.naming.TopicName) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) MutableLong(org.apache.commons.lang3.mutable.MutableLong) NoSuchElementException(java.util.NoSuchElementException)

Example 5 with TopicNotFoundException

use of org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException in project pulsar by yahoo.

the class ServerCnx method handleSubscribe.

@Override
protected void handleSubscribe(final CommandSubscribe subscribe) {
    checkArgument(state == State.Connected);
    final long requestId = subscribe.getRequestId();
    final long consumerId = subscribe.getConsumerId();
    TopicName topicName = validateTopicName(subscribe.getTopic(), requestId, subscribe);
    if (topicName == null) {
        return;
    }
    if (log.isDebugEnabled()) {
        log.debug("[{}] Handle subscribe command: auth role = {}, original auth role = {}", remoteAddress, authRole, originalPrincipal);
    }
    if (invalidOriginalPrincipal(originalPrincipal)) {
        final String msg = "Valid Proxy Client role should be provided while subscribing ";
        log.warn("[{}] {} with role {} and proxyClientAuthRole {} on topic {}", remoteAddress, msg, authRole, originalPrincipal, topicName);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, msg);
        return;
    }
    final String subscriptionName = subscribe.getSubscription();
    final SubType subType = subscribe.getSubType();
    final String consumerName = subscribe.hasConsumerName() ? subscribe.getConsumerName() : "";
    final boolean isDurable = subscribe.isDurable();
    final MessageIdImpl startMessageId = subscribe.hasStartMessageId() ? new BatchMessageIdImpl(subscribe.getStartMessageId().getLedgerId(), subscribe.getStartMessageId().getEntryId(), subscribe.getStartMessageId().getPartition(), subscribe.getStartMessageId().getBatchIndex()) : null;
    final int priorityLevel = subscribe.hasPriorityLevel() ? subscribe.getPriorityLevel() : 0;
    final boolean readCompacted = subscribe.hasReadCompacted() && subscribe.isReadCompacted();
    final Map<String, String> metadata = CommandUtils.metadataFromCommand(subscribe);
    final InitialPosition initialPosition = subscribe.getInitialPosition();
    final long startMessageRollbackDurationSec = subscribe.hasStartMessageRollbackDurationSec() ? subscribe.getStartMessageRollbackDurationSec() : -1;
    final SchemaData schema = subscribe.hasSchema() ? getSchema(subscribe.getSchema()) : null;
    final boolean isReplicated = subscribe.hasReplicateSubscriptionState() && subscribe.isReplicateSubscriptionState();
    final boolean forceTopicCreation = subscribe.isForceTopicCreation();
    final KeySharedMeta keySharedMeta = subscribe.hasKeySharedMeta() ? new KeySharedMeta().copyFrom(subscribe.getKeySharedMeta()) : emptyKeySharedMeta;
    if (log.isDebugEnabled()) {
        log.debug("Topic name = {}, subscription name = {}, schema is {}", topicName, subscriptionName, schema == null ? "absent" : "present");
    }
    CompletableFuture<Boolean> isAuthorizedFuture = isTopicOperationAllowed(topicName, subscriptionName, TopicOperation.CONSUME);
    // Make sure the consumer future is put into the consumers map first to avoid the same consumer
    // epoch using different consumer futures, and only remove the consumer future from the map
    // if subscribe failed .
    CompletableFuture<Consumer> consumerFuture = new CompletableFuture<>();
    CompletableFuture<Consumer> existingConsumerFuture = consumers.putIfAbsent(consumerId, consumerFuture);
    isAuthorizedFuture.thenApply(isAuthorized -> {
        if (isAuthorized) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Client is authorized to subscribe with role {}", remoteAddress, getPrincipal());
            }
            log.info("[{}] Subscribing on topic {} / {}", remoteAddress, topicName, subscriptionName);
            try {
                Metadata.validateMetadata(metadata, service.getPulsar().getConfiguration().getMaxConsumerMetadataSize());
            } catch (IllegalArgumentException iae) {
                final String msg = iae.getMessage();
                consumers.remove(consumerId, consumerFuture);
                commandSender.sendErrorResponse(requestId, ServerError.MetadataError, msg);
                return null;
            }
            if (existingConsumerFuture != null) {
                if (!existingConsumerFuture.isDone()) {
                    // There was an early request to create a consumer with same consumerId. This can happen
                    // when
                    // client timeout is lower the broker timeouts. We need to wait until the previous
                    // consumer
                    // creation request either complete or fails.
                    log.warn("[{}][{}][{}] Consumer with id is already present on the connection," + " consumerId={}", remoteAddress, topicName, subscriptionName, consumerId);
                    commandSender.sendErrorResponse(requestId, ServerError.ServiceNotReady, "Consumer is already present on the connection");
                } else if (existingConsumerFuture.isCompletedExceptionally()) {
                    ServerError error = getErrorCodeWithErrorLog(existingConsumerFuture, true, String.format("Consumer subscribe failure. remoteAddress: %s, subscription: %s", remoteAddress, subscriptionName));
                    consumers.remove(consumerId, existingConsumerFuture);
                    commandSender.sendErrorResponse(requestId, error, "Consumer that failed is already present on the connection");
                } else {
                    Consumer consumer = existingConsumerFuture.getNow(null);
                    log.info("[{}] Consumer with the same id is already created:" + " consumerId={}, consumer={}", remoteAddress, consumerId, consumer);
                    commandSender.sendSuccessResponse(requestId);
                }
                return null;
            }
            boolean createTopicIfDoesNotExist = forceTopicCreation && service.isAllowAutoTopicCreation(topicName.toString());
            final long consumerEpoch;
            if (subscribe.hasConsumerEpoch()) {
                consumerEpoch = subscribe.getConsumerEpoch();
            } else {
                consumerEpoch = DEFAULT_CONSUMER_EPOCH;
            }
            Optional<Map<String, String>> subscriptionProperties = SubscriptionOption.getPropertiesMap(subscribe.getSubscriptionPropertiesList());
            service.getTopic(topicName.toString(), createTopicIfDoesNotExist).thenCompose(optTopic -> {
                if (!optTopic.isPresent()) {
                    return FutureUtil.failedFuture(new TopicNotFoundException("Topic " + topicName + " does not exist"));
                }
                Topic topic = optTopic.get();
                boolean rejectSubscriptionIfDoesNotExist = isDurable && !service.isAllowAutoSubscriptionCreation(topicName.toString()) && !topic.getSubscriptions().containsKey(subscriptionName) && topic.isPersistent();
                if (rejectSubscriptionIfDoesNotExist) {
                    return FutureUtil.failedFuture(new SubscriptionNotFoundException("Subscription does not exist"));
                }
                SubscriptionOption option = SubscriptionOption.builder().cnx(ServerCnx.this).subscriptionName(subscriptionName).consumerId(consumerId).subType(subType).priorityLevel(priorityLevel).consumerName(consumerName).isDurable(isDurable).startMessageId(startMessageId).metadata(metadata).readCompacted(readCompacted).initialPosition(initialPosition).startMessageRollbackDurationSec(startMessageRollbackDurationSec).replicatedSubscriptionStateArg(isReplicated).keySharedMeta(keySharedMeta).subscriptionProperties(subscriptionProperties).consumerEpoch(consumerEpoch).build();
                if (schema != null) {
                    return topic.addSchemaIfIdleOrCheckCompatible(schema).thenCompose(v -> topic.subscribe(option));
                } else {
                    return topic.subscribe(option);
                }
            }).thenAccept(consumer -> {
                if (consumerFuture.complete(consumer)) {
                    log.info("[{}] Created subscription on topic {} / {}", remoteAddress, topicName, subscriptionName);
                    commandSender.sendSuccessResponse(requestId);
                    if (getBrokerService().getInterceptor() != null) {
                        getBrokerService().getInterceptor().consumerCreated(this, consumer, metadata);
                    }
                } else {
                    // The consumer future was completed before by a close command
                    try {
                        consumer.close();
                        log.info("[{}] Cleared consumer created after timeout on client side {}", remoteAddress, consumer);
                    } catch (BrokerServiceException e) {
                        log.warn("[{}] Error closing consumer created" + " after timeout on client side {}: {}", remoteAddress, consumer, e.getMessage());
                    }
                    consumers.remove(consumerId, consumerFuture);
                }
            }).exceptionally(exception -> {
                if (exception.getCause() instanceof ConsumerBusyException) {
                    if (log.isDebugEnabled()) {
                        log.debug("[{}][{}][{}] Failed to create consumer because exclusive consumer" + " is already connected: {}", remoteAddress, topicName, subscriptionName, exception.getCause().getMessage());
                    }
                } else if (exception.getCause() instanceof BrokerServiceException) {
                    log.warn("[{}][{}][{}] Failed to create consumer: consumerId={}, {}", remoteAddress, topicName, subscriptionName, consumerId, exception.getCause().getMessage());
                } else {
                    log.warn("[{}][{}][{}] Failed to create consumer: consumerId={}, {}", remoteAddress, topicName, subscriptionName, consumerId, exception.getCause().getMessage(), exception);
                }
                // back to client, only if not completed already.
                if (consumerFuture.completeExceptionally(exception)) {
                    commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(exception), exception.getCause().getMessage());
                }
                consumers.remove(consumerId, consumerFuture);
                return null;
            });
        } else {
            String msg = "Client is not authorized to subscribe";
            log.warn("[{}] {} with role {}", remoteAddress, msg, getPrincipal());
            consumers.remove(consumerId, consumerFuture);
            ctx.writeAndFlush(Commands.newError(requestId, ServerError.AuthorizationError, msg));
        }
        return null;
    }).exceptionally(ex -> {
        logAuthException(remoteAddress, "subscribe", getPrincipal(), Optional.of(topicName), ex);
        consumers.remove(consumerId, consumerFuture);
        commandSender.sendErrorResponse(requestId, ServerError.AuthorizationError, ex.getMessage());
        return null;
    });
}
Also used : CommandAuthResponse(org.apache.pulsar.common.api.proto.CommandAuthResponse) CommandUnsubscribe(org.apache.pulsar.common.api.proto.CommandUnsubscribe) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) MessageIdData(org.apache.pulsar.common.api.proto.MessageIdData) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) StringUtils(org.apache.commons.lang3.StringUtils) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) TxnID(org.apache.pulsar.client.api.transaction.TxnID) MLTransactionMetadataStore(org.apache.pulsar.transaction.coordinator.impl.MLTransactionMetadataStore) TopicOperation(org.apache.pulsar.common.policies.data.TopicOperation) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Map(java.util.Map) BrokerInterceptor(org.apache.pulsar.broker.intercept.BrokerInterceptor) RestException(org.apache.pulsar.broker.web.RestException) NamespaceOperation(org.apache.pulsar.common.policies.data.NamespaceOperation) BaseCommand(org.apache.pulsar.common.api.proto.BaseCommand) CommandAck(org.apache.pulsar.common.api.proto.CommandAck) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) InterceptException(org.apache.pulsar.common.intercept.InterceptException) CommandFlow(org.apache.pulsar.common.api.proto.CommandFlow) CommandConsumerStats(org.apache.pulsar.common.api.proto.CommandConsumerStats) ServerError(org.apache.pulsar.common.api.proto.ServerError) Set(java.util.Set) CommandNewTxn(org.apache.pulsar.common.api.proto.CommandNewTxn) TopicList(org.apache.pulsar.common.topics.TopicList) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) SafeRun(org.apache.bookkeeper.mledger.util.SafeRun) SslHandler(io.netty.handler.ssl.SslHandler) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) ExceptionUtils(org.apache.commons.lang3.exception.ExceptionUtils) ClientCnx(org.apache.pulsar.client.impl.ClientCnx) ChannelOption(io.netty.channel.ChannelOption) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState) CommandGetTopicsOfNamespace(org.apache.pulsar.common.api.proto.CommandGetTopicsOfNamespace) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) SchemaType(org.apache.pulsar.common.schema.SchemaType) Commands(org.apache.pulsar.common.protocol.Commands) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer) Strings(com.google.common.base.Strings) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SSLSession(javax.net.ssl.SSLSession) CommandGetOrCreateSchema(org.apache.pulsar.common.api.proto.CommandGetOrCreateSchema) ProtocolVersion.v5(org.apache.pulsar.common.api.proto.ProtocolVersion.v5) CommandGetSchema(org.apache.pulsar.common.api.proto.CommandGetSchema) SchemaInfoUtil(org.apache.pulsar.client.impl.schema.SchemaInfoUtil) CommandRedeliverUnacknowledgedMessages(org.apache.pulsar.common.api.proto.CommandRedeliverUnacknowledgedMessages) Metadata(org.apache.pulsar.common.naming.Metadata) Promise(io.netty.util.concurrent.Promise) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) lombok.val(lombok.val) PulsarService(org.apache.pulsar.broker.PulsarService) KeySharedMode(org.apache.pulsar.common.api.proto.KeySharedMode) CommandEndTxnOnSubscription(org.apache.pulsar.common.api.proto.CommandEndTxnOnSubscription) CommandConnect(org.apache.pulsar.common.api.proto.CommandConnect) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) ProducerAccessMode(org.apache.pulsar.common.api.proto.ProducerAccessMode) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) MutableInt(org.apache.commons.lang3.mutable.MutableInt) SocketAddress(java.net.SocketAddress) CommandAddPartitionToTxn(org.apache.pulsar.common.api.proto.CommandAddPartitionToTxn) LoggerFactory(org.slf4j.LoggerFactory) AuthData(org.apache.pulsar.common.api.AuthData) Exceptions(org.apache.pulsar.functions.utils.Exceptions) AuthenticationException(javax.naming.AuthenticationException) KeyValue(org.apache.pulsar.common.api.proto.KeyValue) PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync(org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.unsafeGetPartitionedTopicMetadataAsync) CommandEndTxnOnPartition(org.apache.pulsar.common.api.proto.CommandEndTxnOnPartition) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BacklogQuotaType(org.apache.pulsar.common.policies.data.BacklogQuota.BacklogQuotaType) Gauge(io.prometheus.client.Gauge) TxnAction(org.apache.pulsar.common.api.proto.TxnAction) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Schema(org.apache.pulsar.common.api.proto.Schema) TransactionMetadataStoreService(org.apache.pulsar.broker.TransactionMetadataStoreService) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) IdentityHashMap(java.util.IdentityHashMap) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException) Position(org.apache.bookkeeper.mledger.Position) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) CommandEndTxn(org.apache.pulsar.common.api.proto.CommandEndTxn) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) Objects(java.util.Objects) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Optional(java.util.Optional) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) PulsarHandler(org.apache.pulsar.common.protocol.PulsarHandler) CommandTcClientConnectRequest(org.apache.pulsar.common.api.proto.CommandTcClientConnectRequest) TopicName(org.apache.pulsar.common.naming.TopicName) CommandAddSubscriptionToTxn(org.apache.pulsar.common.api.proto.CommandAddSubscriptionToTxn) Entry(org.apache.bookkeeper.mledger.Entry) CommandSend(org.apache.pulsar.common.api.proto.CommandSend) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) TopicLookupBase.lookupTopicAsync(org.apache.pulsar.broker.lookup.TopicLookupBase.lookupTopicAsync) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) CommandSubscribe(org.apache.pulsar.common.api.proto.CommandSubscribe) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) CoordinatorException(org.apache.pulsar.transaction.coordinator.exceptions.CoordinatorException) FastThreadLocal(io.netty.util.concurrent.FastThreadLocal) CommandPartitionedTopicMetadata(org.apache.pulsar.common.api.proto.CommandPartitionedTopicMetadata) ChannelFutureListener(io.netty.channel.ChannelFutureListener) CommandSeek(org.apache.pulsar.common.api.proto.CommandSeek) ConsumerStatsImpl(org.apache.pulsar.common.policies.data.stats.ConsumerStatsImpl) NoSuchElementException(java.util.NoSuchElementException) CommandGetLastMessageId(org.apache.pulsar.common.api.proto.CommandGetLastMessageId) CommandUtils(org.apache.pulsar.common.protocol.CommandUtils) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) AuthenticationDataCommand(org.apache.pulsar.broker.authentication.AuthenticationDataCommand) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) FeatureFlags(org.apache.pulsar.common.api.proto.FeatureFlags) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) Commands.newLookupErrorResponse(org.apache.pulsar.common.protocol.Commands.newLookupErrorResponse) TimeUnit(java.util.concurrent.TimeUnit) HAProxyMessage(io.netty.handler.codec.haproxy.HAProxyMessage) ConcurrentLongHashMap(org.apache.pulsar.common.util.collections.ConcurrentLongHashMap) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) ChannelHandler(io.netty.channel.ChannelHandler) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TransactionCoordinatorID(org.apache.pulsar.transaction.coordinator.TransactionCoordinatorID) Collections(java.util.Collections) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) CompletableFuture(java.util.concurrent.CompletableFuture) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) CommandCloseConsumer(org.apache.pulsar.common.api.proto.CommandCloseConsumer) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) CommandLookupTopic(org.apache.pulsar.common.api.proto.CommandLookupTopic) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) Optional(java.util.Optional) ServerError(org.apache.pulsar.common.api.proto.ServerError) BatchMessageIdImpl(org.apache.pulsar.client.impl.BatchMessageIdImpl) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) TopicName(org.apache.pulsar.common.naming.TopicName) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)6 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)6 Strings (com.google.common.base.Strings)6 ByteBuf (io.netty.buffer.ByteBuf)6 ChannelHandler (io.netty.channel.ChannelHandler)6 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)6 ChannelOption (io.netty.channel.ChannelOption)6 HAProxyMessage (io.netty.handler.codec.haproxy.HAProxyMessage)6 SslHandler (io.netty.handler.ssl.SslHandler)6 FastThreadLocal (io.netty.util.concurrent.FastThreadLocal)6 Promise (io.netty.util.concurrent.Promise)6 Gauge (io.prometheus.client.Gauge)6 InetSocketAddress (java.net.InetSocketAddress)6 SocketAddress (java.net.SocketAddress)6 Collections (java.util.Collections)6 IdentityHashMap (java.util.IdentityHashMap)6 Map (java.util.Map)6 NoSuchElementException (java.util.NoSuchElementException)6 Objects (java.util.Objects)6 Optional (java.util.Optional)6