Search in sources :

Example 1 with SchemaVersion

use of org.apache.pulsar.common.protocol.schema.SchemaVersion in project pulsar by apache.

the class AbstractTopic method addSchema.

@Override
public CompletableFuture<SchemaVersion> addSchema(SchemaData schema) {
    if (schema == null) {
        return CompletableFuture.completedFuture(SchemaVersion.Empty);
    }
    String base = TopicName.get(getName()).getPartitionedTopicName();
    String id = TopicName.get(base).getSchemaName();
    SchemaRegistryService schemaRegistryService = brokerService.pulsar().getSchemaRegistryService();
    if (allowAutoUpdateSchema()) {
        return schemaRegistryService.putSchemaIfAbsent(id, schema, getSchemaCompatibilityStrategy());
    } else {
        return schemaRegistryService.trimDeletedSchemaAndGetList(id).thenCompose(schemaAndMetadataList -> schemaRegistryService.getSchemaVersionBySchemaData(schemaAndMetadataList, schema).thenCompose(schemaVersion -> {
            if (schemaVersion == null) {
                return FutureUtil.failedFuture(new IncompatibleSchemaException("Schema not found and schema auto updating is disabled."));
            } else {
                return CompletableFuture.completedFuture(schemaVersion);
            }
        }));
    }
}
Also used : StatsBuckets(org.apache.bookkeeper.mledger.util.StatsBuckets) Arrays(java.util.Arrays) BookkeeperSchemaStorage(org.apache.pulsar.broker.service.schema.BookkeeperSchemaStorage) LoggerFactory(org.slf4j.LoggerFactory) DelayedDeliveryPolicies(org.apache.pulsar.common.policies.data.DelayedDeliveryPolicies) ProducerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ProducerBusyException) SubscribeRate(org.apache.pulsar.common.policies.data.SubscribeRate) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Pair(org.apache.commons.lang3.tuple.Pair) ResourceGroup(org.apache.pulsar.broker.resourcegroup.ResourceGroup) Map(java.util.Map) DispatchRateImpl(org.apache.pulsar.common.policies.data.impl.DispatchRateImpl) EnumSet(java.util.EnumSet) InactiveTopicPolicies(org.apache.pulsar.common.policies.data.InactiveTopicPolicies) SchemaCompatibilityStrategy(org.apache.pulsar.common.policies.data.SchemaCompatibilityStrategy) ResourceGroupPublishLimiter(org.apache.pulsar.broker.resourcegroup.ResourceGroupPublishLimiter) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) PublishRate(org.apache.pulsar.common.policies.data.PublishRate) HierarchyTopicPolicies(org.apache.pulsar.common.policies.data.HierarchyTopicPolicies) Objects(java.util.Objects) List(java.util.List) FutureUtil(org.apache.pulsar.common.util.FutureUtil) TopicTerminatedException(org.apache.pulsar.broker.service.BrokerServiceException.TopicTerminatedException) Optional(java.util.Optional) ENTRY_LATENCY_BUCKETS_USEC(org.apache.bookkeeper.mledger.impl.ManagedLedgerMBeanImpl.ENTRY_LATENCY_BUCKETS_USEC) Queue(java.util.Queue) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) LongAdder(java.util.concurrent.atomic.LongAdder) ProducerFencedException(org.apache.pulsar.broker.service.BrokerServiceException.ProducerFencedException) TopicName(org.apache.pulsar.common.naming.TopicName) Getter(lombok.Getter) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService) BacklogQuota(org.apache.pulsar.common.policies.data.BacklogQuota) CompletableFuture(java.util.concurrent.CompletableFuture) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) CollectionUtils(org.apache.commons.collections4.CollectionUtils) SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) Lists(com.google.common.collect.Lists) MapUtils(org.apache.commons.collections4.MapUtils) RetentionPolicies(org.apache.pulsar.common.policies.data.RetentionPolicies) Summary(org.apache.pulsar.broker.stats.prometheus.metrics.Summary) Logger(org.slf4j.Logger) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) MoreObjects(com.google.common.base.MoreObjects) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) TopicPolicies(org.apache.pulsar.common.policies.data.TopicPolicies) SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) TimeUnit(java.util.concurrent.TimeUnit) Policies(org.apache.pulsar.common.policies.data.Policies) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException) SchemaData(org.apache.pulsar.common.protocol.schema.SchemaData) Collections(java.util.Collections) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) SchemaRegistryService(org.apache.pulsar.broker.service.schema.SchemaRegistryService)

Example 2 with SchemaVersion

use of org.apache.pulsar.common.protocol.schema.SchemaVersion in project pulsar by apache.

the class ServerCnx method buildProducerAndAddTopic.

private void buildProducerAndAddTopic(Topic topic, long producerId, String producerName, long requestId, boolean isEncrypted, Map<String, String> metadata, SchemaVersion schemaVersion, long epoch, boolean userProvidedProducerName, TopicName topicName, ProducerAccessMode producerAccessMode, Optional<Long> topicEpoch, boolean supportsPartialProducer, CompletableFuture<Producer> producerFuture) {
    CompletableFuture<Void> producerQueuedFuture = new CompletableFuture<>();
    Producer producer = new Producer(topic, ServerCnx.this, producerId, producerName, getPrincipal(), isEncrypted, metadata, schemaVersion, epoch, userProvidedProducerName, producerAccessMode, topicEpoch, supportsPartialProducer);
    topic.addProducer(producer, producerQueuedFuture).thenAccept(newTopicEpoch -> {
        if (isActive()) {
            if (producerFuture.complete(producer)) {
                log.info("[{}] Created new producer: {}", remoteAddress, producer);
                commandSender.sendProducerSuccessResponse(requestId, producerName, producer.getLastSequenceId(), producer.getSchemaVersion(), newTopicEpoch, true);
                if (getBrokerService().getInterceptor() != null) {
                    getBrokerService().getInterceptor().producerCreated(this, producer, metadata);
                }
                return;
            } else {
                // The producer's future was completed before by
                // a close command
                producer.closeNow(true);
                log.info("[{}] Cleared producer created after" + " timeout on client side {}", remoteAddress, producer);
            }
        } else {
            producer.closeNow(true);
            log.info("[{}] Cleared producer created after connection was closed: {}", remoteAddress, producer);
            producerFuture.completeExceptionally(new IllegalStateException("Producer created after connection was closed"));
        }
        producers.remove(producerId, producerFuture);
    }).exceptionally(ex -> {
        if (ex.getCause() instanceof BrokerServiceException.ProducerFencedException) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] Failed to add producer to topic {}: producerId={}, {}", remoteAddress, topicName, producerId, ex.getCause().getMessage());
            }
        } else {
            log.warn("[{}] Failed to add producer to topic {}: producerId={}, {}", remoteAddress, topicName, producerId, ex.getCause().getMessage());
        }
        producer.closeNow(true);
        if (producerFuture.completeExceptionally(ex)) {
            commandSender.sendErrorResponse(requestId, BrokerServiceException.getClientErrorCode(ex), ex.getMessage());
        }
        return null;
    });
    producerQueuedFuture.thenRun(() -> {
        // that we need to pass to client
        if (isActive()) {
            log.info("[{}] Producer is waiting in queue: {}", remoteAddress, producer);
            commandSender.sendProducerSuccessResponse(requestId, producerName, producer.getLastSequenceId(), producer.getSchemaVersion(), Optional.empty(), false);
            if (getBrokerService().getInterceptor() != null) {
                getBrokerService().getInterceptor().producerCreated(this, producer, metadata);
            }
        }
    });
}
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) CompletableFuture(java.util.concurrent.CompletableFuture) CommandProducer(org.apache.pulsar.common.api.proto.CommandProducer) CommandCloseProducer(org.apache.pulsar.common.api.proto.CommandCloseProducer)

Example 3 with SchemaVersion

use of org.apache.pulsar.common.protocol.schema.SchemaVersion in project pulsar by apache.

the class AutoConsumeSchema method validate.

public void validate(byte[] message, byte[] schemaVersion) {
    SchemaVersion sv = getSchemaVersion(schemaVersion);
    ensureSchemaInitialized(sv);
    schemaMap.get(sv).validate(message);
}
Also used : SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) BytesSchemaVersion(org.apache.pulsar.common.protocol.schema.BytesSchemaVersion)

Example 4 with SchemaVersion

use of org.apache.pulsar.common.protocol.schema.SchemaVersion in project pulsar by apache.

the class AutoConsumeSchema method atSchemaVersion.

public Schema<?> atSchemaVersion(byte[] schemaVersion) {
    SchemaVersion sv = getSchemaVersion(schemaVersion);
    fetchSchemaIfNeeded(sv);
    ensureSchemaInitialized(sv);
    Schema<?> topicVersionedSchema = schemaMap.get(sv);
    if (topicVersionedSchema.supportSchemaVersioning() && topicVersionedSchema instanceof AbstractSchema) {
        return ((AbstractSchema<?>) topicVersionedSchema).atSchemaVersion(schemaVersion);
    } else {
        return topicVersionedSchema;
    }
}
Also used : SchemaVersion(org.apache.pulsar.common.protocol.schema.SchemaVersion) BytesSchemaVersion(org.apache.pulsar.common.protocol.schema.BytesSchemaVersion)

Example 5 with SchemaVersion

use of org.apache.pulsar.common.protocol.schema.SchemaVersion 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)

Aggregations

SchemaVersion (org.apache.pulsar.common.protocol.schema.SchemaVersion)19 CompletableFuture (java.util.concurrent.CompletableFuture)11 SchemaData (org.apache.pulsar.common.protocol.schema.SchemaData)8 ByteBuf (io.netty.buffer.ByteBuf)7 Optional (java.util.Optional)7 TopicName (org.apache.pulsar.common.naming.TopicName)7 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)6 Collections (java.util.Collections)6 IncompatibleSchemaException (org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException)6 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)6 Commands (org.apache.pulsar.common.protocol.Commands)6 FutureUtil (org.apache.pulsar.common.util.FutureUtil)6 Logger (org.slf4j.Logger)5 LoggerFactory (org.slf4j.LoggerFactory)5 VisibleForTesting (com.google.common.annotations.VisibleForTesting)4 Strings (com.google.common.base.Strings)4 ChannelHandler (io.netty.channel.ChannelHandler)4 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)4 ChannelOption (io.netty.channel.ChannelOption)4 HAProxyMessage (io.netty.handler.codec.haproxy.HAProxyMessage)4