Search in sources :

Example 1 with AppendRecordsContext

use of io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext in project starlight-for-kafka by datastax.

the class KafkaRequestHandler method handleWriteTxnMarkers.

@Override
protected void handleWriteTxnMarkers(KafkaHeaderAndRequest kafkaHeaderAndRequest, CompletableFuture<AbstractResponse> response) {
    WriteTxnMarkersRequest request = (WriteTxnMarkersRequest) kafkaHeaderAndRequest.getRequest();
    Map<Long, Map<TopicPartition, Errors>> errors = new ConcurrentHashMap<>();
    List<WriteTxnMarkersRequest.TxnMarkerEntry> markers = request.markers();
    AtomicInteger numAppends = new AtomicInteger(markers.size());
    if (numAppends.get() == 0) {
        response.complete(new WriteTxnMarkersResponse(errors));
        return;
    }
    BiConsumer<Long, Map<TopicPartition, Errors>> updateErrors = (producerId, currentErrors) -> {
        Map<TopicPartition, Errors> previousErrors = errors.putIfAbsent(producerId, currentErrors);
        if (previousErrors != null) {
            previousErrors.putAll(currentErrors);
        }
    };
    Runnable completeOne = () -> {
        if (numAppends.decrementAndGet() == 0) {
            response.complete(new WriteTxnMarkersResponse(errors));
        }
    };
    for (WriteTxnMarkersRequest.TxnMarkerEntry marker : markers) {
        long producerId = marker.producerId();
        TransactionResult transactionResult = marker.transactionResult();
        Map<TopicPartition, MemoryRecords> controlRecords = generateTxnMarkerRecords(marker);
        AppendRecordsContext appendRecordsContext = AppendRecordsContext.get(topicManager, requestStats, this::startSendOperationForThrottling, this::completeSendOperationForThrottling, this.pendingTopicFuturesMap);
        getReplicaManager().appendRecords(kafkaConfig.getRequestTimeoutMs(), true, currentNamespacePrefix(), controlRecords, PartitionLog.AppendOrigin.Coordinator, appendRecordsContext).whenComplete((result, ex) -> {
            appendRecordsContext.recycle();
            if (ex != null) {
                log.error("[{}] Append txn marker ({}) failed.", ctx.channel(), marker, ex);
                Map<TopicPartition, Errors> currentErrors = new HashMap<>();
                controlRecords.forEach(((topicPartition, partitionResponse) -> {
                    currentErrors.put(topicPartition, Errors.KAFKA_STORAGE_ERROR);
                }));
                updateErrors.accept(producerId, currentErrors);
                completeOne.run();
                return;
            }
            Map<TopicPartition, Errors> currentErrors = new HashMap<>();
            result.forEach(((topicPartition, partitionResponse) -> {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Append txn marker to topic : [{}], response: [{}].", ctx.channel(), topicPartition, partitionResponse);
                }
                currentErrors.put(topicPartition, partitionResponse.error);
            }));
            updateErrors.accept(producerId, currentErrors);
            final String metadataNamespace = kafkaConfig.getKafkaMetadataNamespace();
            Set<TopicPartition> successfulOffsetsPartitions = result.keySet().stream().filter(topicPartition -> KopTopic.isGroupMetadataTopicName(topicPartition.topic(), metadataNamespace)).collect(Collectors.toSet());
            if (!successfulOffsetsPartitions.isEmpty()) {
                getGroupCoordinator().scheduleHandleTxnCompletion(producerId, successfulOffsetsPartitions.stream().map(TopicPartition::partition).collect(Collectors.toSet()), transactionResult).whenComplete((__, e) -> {
                    if (e != null) {
                        log.error("Received an exception while trying to update the offsets cache on " + "transaction marker append", e);
                        ConcurrentHashMap<TopicPartition, Errors> updatedErrors = new ConcurrentHashMap<>();
                        successfulOffsetsPartitions.forEach(partition -> updatedErrors.put(partition, Errors.forException(e.getCause())));
                        updateErrors.accept(producerId, updatedErrors);
                    }
                    completeOne.run();
                });
                return;
            }
            completeOne.run();
        });
    }
}
Also used : IsolationLevel(org.apache.kafka.common.requests.IsolationLevel) KafkaResponseUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaResponseUtils) LeaveGroupRequest(org.apache.kafka.common.requests.LeaveGroupRequest) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) HeartbeatResponse(org.apache.kafka.common.requests.HeartbeatResponse) SaslAuthenticator(io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator) Pair(org.apache.commons.lang3.tuple.Pair) SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) MetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MetadataUtils) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) MutableRecordBatch(org.apache.kafka.common.record.MutableRecordBatch) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DeleteGroupsRequest(org.apache.kafka.common.requests.DeleteGroupsRequest) Set(java.util.Set) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) AddPartitionsToTxnRequest(org.apache.kafka.common.requests.AddPartitionsToTxnRequest) ListOffsetResponse(org.apache.kafka.common.requests.ListOffsetResponse) ListGroupsRequest(org.apache.kafka.common.requests.ListGroupsRequest) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) Stream(java.util.stream.Stream) DeleteRecordsRequest(org.apache.kafka.common.requests.DeleteRecordsRequest) ListOffsetRequest(org.apache.kafka.common.requests.ListOffsetRequest) Errors(org.apache.kafka.common.protocol.Errors) Murmur3_32Hash(org.apache.pulsar.common.util.Murmur3_32Hash) Node(org.apache.kafka.common.Node) FetchRequest(org.apache.kafka.common.requests.FetchRequest) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) EntryFormatterFactory(io.streamnative.pulsar.handlers.kop.format.EntryFormatterFactory) Joiner(com.google.common.base.Joiner) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) AuthenticationException(org.apache.kafka.common.errors.AuthenticationException) TopicNameUtils(io.streamnative.pulsar.handlers.kop.utils.TopicNameUtils) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) WriteTxnMarkersRequest(org.apache.kafka.common.requests.WriteTxnMarkersRequest) MetadataStoreExtended(org.apache.pulsar.metadata.api.extended.MetadataStoreExtended) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) InvalidRecordException(org.apache.kafka.common.record.InvalidRecordException) ArrayList(java.util.ArrayList) GroupOverview(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.GroupOverview) FindCoordinatorRequest(org.apache.kafka.common.requests.FindCoordinatorRequest) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) THROTTLE_TIME_MS(org.apache.kafka.common.protocol.CommonFields.THROTTLE_TIME_MS) OffsetFetchResponse(org.apache.kafka.common.requests.OffsetFetchResponse) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) TENANT_ALLNAMESPACES_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_ALLNAMESPACES_PLACEHOLDER) GroupIdUtils(io.streamnative.pulsar.handlers.kop.utils.GroupIdUtils) OffsetCommitResponse(org.apache.kafka.common.requests.OffsetCommitResponse) ResourceType(io.streamnative.pulsar.handlers.kop.security.auth.ResourceType) TxnOffsetCommitResponse(org.apache.kafka.common.requests.TxnOffsetCommitResponse) Executor(java.util.concurrent.Executor) SystemTime(org.apache.kafka.common.utils.SystemTime) OffsetMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetMetadata) DeleteRecordsResponse(org.apache.kafka.common.requests.DeleteRecordsResponse) AclOperation(org.apache.kafka.common.acl.AclOperation) PulsarService(org.apache.pulsar.broker.PulsarService) TENANT_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_PLACEHOLDER) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) AddOffsetsToTxnResponse(org.apache.kafka.common.requests.AddOffsetsToTxnResponse) WriteTxnMarkersResponse(org.apache.kafka.common.requests.WriteTxnMarkersResponse) SimpleAclAuthorizer(io.streamnative.pulsar.handlers.kop.security.auth.SimpleAclAuthorizer) GroupCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupCoordinator) InitProducerIdRequest(org.apache.kafka.common.requests.InitProducerIdRequest) JoinGroupRequest(org.apache.kafka.common.requests.JoinGroupRequest) TopicDetails(org.apache.kafka.common.requests.CreateTopicsRequest.TopicDetails) ProduceRequest(org.apache.kafka.common.requests.ProduceRequest) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) DescribeGroupsRequest(org.apache.kafka.common.requests.DescribeGroupsRequest) ByteBuffer(java.nio.ByteBuffer) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) TopicMetadata(org.apache.kafka.common.requests.MetadataResponse.TopicMetadata) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CreatePartitionsRequest(org.apache.kafka.common.requests.CreatePartitionsRequest) ListUtils(org.apache.commons.collections4.ListUtils) DelayedOperationPurgatory(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationPurgatory) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) TopicPartition(org.apache.kafka.common.TopicPartition) OrderedScheduler(org.apache.bookkeeper.common.util.OrderedScheduler) Time(org.apache.kafka.common.utils.Time) Collection(java.util.Collection) EndTxnResponse(org.apache.kafka.common.requests.EndTxnResponse) PartitionLog(io.streamnative.pulsar.handlers.kop.storage.PartitionLog) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MessageMetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MessageMetadataUtils) PulsarMetadataAccessor(io.streamnative.pulsar.handlers.kop.security.auth.PulsarMetadataAccessor) Position(org.apache.bookkeeper.mledger.Position) TransactionCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.transaction.TransactionCoordinator) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) CoreUtils(io.streamnative.pulsar.handlers.kop.utils.CoreUtils) DescribeConfigsRequest(org.apache.kafka.common.requests.DescribeConfigsRequest) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) InitProducerIdResponse(org.apache.kafka.common.requests.InitProducerIdResponse) Optional(java.util.Optional) OffsetFinder(io.streamnative.pulsar.handlers.kop.utils.OffsetFinder) HeartbeatRequest(org.apache.kafka.common.requests.HeartbeatRequest) ReplicaManager(io.streamnative.pulsar.handlers.kop.storage.ReplicaManager) JoinGroupResponse(org.apache.kafka.common.requests.JoinGroupResponse) KoPTopicException(io.streamnative.pulsar.handlers.kop.exceptions.KoPTopicException) NotImplementedException(org.apache.commons.lang3.NotImplementedException) DeleteTopicsRequest(org.apache.kafka.common.requests.DeleteTopicsRequest) AddOffsetsToTxnRequest(org.apache.kafka.common.requests.AddOffsetsToTxnRequest) TopicName(org.apache.pulsar.common.naming.TopicName) Getter(lombok.Getter) CreateTopicsRequest(org.apache.kafka.common.requests.CreateTopicsRequest) EndTransactionMarker(org.apache.kafka.common.record.EndTransactionMarker) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) LeaderNotAvailableException(org.apache.kafka.common.errors.LeaderNotAvailableException) DescribeConfigsResponse(org.apache.kafka.common.requests.DescribeConfigsResponse) ApiError(org.apache.kafka.common.requests.ApiError) PartitionMetadata(org.apache.kafka.common.requests.MetadataResponse.PartitionMetadata) HashSet(java.util.HashSet) KeyValue(org.apache.pulsar.common.schema.KeyValue) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Resource(io.streamnative.pulsar.handlers.kop.security.auth.Resource) ConfigResource(org.apache.kafka.common.config.ConfigResource) EntryFormatter(io.streamnative.pulsar.handlers.kop.format.EntryFormatter) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) ByteBuf(io.netty.buffer.ByteBuf) EndTxnRequest(org.apache.kafka.common.requests.EndTxnRequest) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) SyncGroupResponse(org.apache.kafka.common.requests.SyncGroupResponse) Session(io.streamnative.pulsar.handlers.kop.security.Session) Authorizer(io.streamnative.pulsar.handlers.kop.security.auth.Authorizer) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) Utils(org.apache.kafka.common.utils.Utils) DelayedOperation(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperation) KafkaRequestUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaRequestUtils) KopTopic(io.streamnative.pulsar.handlers.kop.utils.KopTopic) OffsetCommitRequest(org.apache.kafka.common.requests.OffsetCommitRequest) Iterator(java.util.Iterator) SaslAuthenticateResponse(org.apache.kafka.common.requests.SaslAuthenticateResponse) AlterConfigsResponse(org.apache.kafka.common.requests.AlterConfigsResponse) TransactionResult(org.apache.kafka.common.requests.TransactionResult) UTF_8(java.nio.charset.StandardCharsets.UTF_8) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) OffsetFetchRequest(org.apache.kafka.common.requests.OffsetFetchRequest) TxnOffsetCommitRequest(org.apache.kafka.common.requests.TxnOffsetCommitRequest) ApiKeys(org.apache.kafka.common.protocol.ApiKeys) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AlterConfigsRequest(org.apache.kafka.common.requests.AlterConfigsRequest) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) ApiException(org.apache.kafka.common.errors.ApiException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) WriteTxnMarkersResponse(org.apache.kafka.common.requests.WriteTxnMarkersResponse) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) TransactionResult(org.apache.kafka.common.requests.TransactionResult) WriteTxnMarkersRequest(org.apache.kafka.common.requests.WriteTxnMarkersRequest) Errors(org.apache.kafka.common.protocol.Errors) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TopicPartition(org.apache.kafka.common.TopicPartition) AtomicLong(java.util.concurrent.atomic.AtomicLong) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) MemoryRecords(org.apache.kafka.common.record.MemoryRecords)

Example 2 with AppendRecordsContext

use of io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext in project kop by streamnative.

the class KafkaRequestHandler method handleProduceRequest.

@Override
protected void handleProduceRequest(KafkaHeaderAndRequest produceHar, CompletableFuture<AbstractResponse> resultFuture) {
    checkArgument(produceHar.getRequest() instanceof ProduceRequest);
    ProduceRequest produceRequest = (ProduceRequest) produceHar.getRequest();
    final int numPartitions = produceRequest.partitionRecordsOrFail().size();
    if (numPartitions == 0) {
        resultFuture.complete(new ProduceResponse(Collections.emptyMap()));
        return;
    }
    final Map<TopicPartition, PartitionResponse> unauthorizedTopicResponsesMap = new ConcurrentHashMap<>();
    final Map<TopicPartition, PartitionResponse> invalidRequestResponses = new HashMap<>();
    final Map<TopicPartition, MemoryRecords> authorizedRequestInfo = new ConcurrentHashMap<>();
    int timeoutMs = produceRequest.timeout();
    String namespacePrefix = currentNamespacePrefix();
    final AtomicInteger unfinishedAuthorizationCount = new AtomicInteger(numPartitions);
    Runnable completeOne = () -> {
        // When complete one authorization or failed, will do the action first.
        if (unfinishedAuthorizationCount.decrementAndGet() == 0) {
            if (authorizedRequestInfo.isEmpty()) {
                resultFuture.complete(new ProduceResponse(unauthorizedTopicResponsesMap));
                return;
            }
            AppendRecordsContext appendRecordsContext = AppendRecordsContext.get(topicManager, requestStats, this::startSendOperationForThrottling, this::completeSendOperationForThrottling, pendingTopicFuturesMap);
            getReplicaManager().appendRecords(timeoutMs, false, namespacePrefix, authorizedRequestInfo, PartitionLog.AppendOrigin.Client, appendRecordsContext).whenComplete((response, ex) -> {
                appendRecordsContext.recycle();
                if (ex != null) {
                    resultFuture.completeExceptionally(ex.getCause());
                    return;
                }
                Map<TopicPartition, PartitionResponse> mergedResponse = new HashMap<>();
                mergedResponse.putAll(response);
                mergedResponse.putAll(unauthorizedTopicResponsesMap);
                mergedResponse.putAll(invalidRequestResponses);
                resultFuture.complete(new ProduceResponse(mergedResponse));
            });
        }
    };
    produceRequest.partitionRecordsOrFail().forEach((topicPartition, records) -> {
        try {
            validateRecords(produceHar.getRequest().version(), records);
        } catch (ApiException ex) {
            invalidRequestResponses.put(topicPartition, new ProduceResponse.PartitionResponse(Errors.forException(ex)));
            completeOne.run();
            return;
        }
        final String fullPartitionName = KopTopic.toString(topicPartition, namespacePrefix);
        authorize(AclOperation.WRITE, Resource.of(ResourceType.TOPIC, fullPartitionName)).whenComplete((isAuthorized, ex) -> {
            if (ex != null) {
                log.error("Write topic authorize failed, topic - {}. {}", fullPartitionName, ex.getMessage());
                unauthorizedTopicResponsesMap.put(topicPartition, new ProduceResponse.PartitionResponse(Errors.TOPIC_AUTHORIZATION_FAILED));
                completeOne.run();
                return;
            }
            if (!isAuthorized) {
                unauthorizedTopicResponsesMap.put(topicPartition, new ProduceResponse.PartitionResponse(Errors.TOPIC_AUTHORIZATION_FAILED));
                completeOne.run();
                return;
            }
            authorizedRequestInfo.put(topicPartition, records);
            completeOne.run();
        });
    });
}
Also used : IsolationLevel(org.apache.kafka.common.requests.IsolationLevel) KafkaResponseUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaResponseUtils) LeaveGroupRequest(org.apache.kafka.common.requests.LeaveGroupRequest) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) HeartbeatResponse(org.apache.kafka.common.requests.HeartbeatResponse) SaslAuthenticator(io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator) Pair(org.apache.commons.lang3.tuple.Pair) SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) MetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MetadataUtils) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) MutableRecordBatch(org.apache.kafka.common.record.MutableRecordBatch) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DeleteGroupsRequest(org.apache.kafka.common.requests.DeleteGroupsRequest) Set(java.util.Set) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) AddPartitionsToTxnRequest(org.apache.kafka.common.requests.AddPartitionsToTxnRequest) ListOffsetResponse(org.apache.kafka.common.requests.ListOffsetResponse) ListGroupsRequest(org.apache.kafka.common.requests.ListGroupsRequest) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) Stream(java.util.stream.Stream) DeleteRecordsRequest(org.apache.kafka.common.requests.DeleteRecordsRequest) ListOffsetRequest(org.apache.kafka.common.requests.ListOffsetRequest) Errors(org.apache.kafka.common.protocol.Errors) Murmur3_32Hash(org.apache.pulsar.common.util.Murmur3_32Hash) Node(org.apache.kafka.common.Node) FetchRequest(org.apache.kafka.common.requests.FetchRequest) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) EntryFormatterFactory(io.streamnative.pulsar.handlers.kop.format.EntryFormatterFactory) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) AuthenticationException(org.apache.kafka.common.errors.AuthenticationException) TopicNameUtils(io.streamnative.pulsar.handlers.kop.utils.TopicNameUtils) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) NewPartitions(org.apache.kafka.clients.admin.NewPartitions) WriteTxnMarkersRequest(org.apache.kafka.common.requests.WriteTxnMarkersRequest) MetadataStoreExtended(org.apache.pulsar.metadata.api.extended.MetadataStoreExtended) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) InvalidRecordException(org.apache.kafka.common.record.InvalidRecordException) ArrayList(java.util.ArrayList) GroupOverview(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.GroupOverview) FindCoordinatorRequest(org.apache.kafka.common.requests.FindCoordinatorRequest) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) THROTTLE_TIME_MS(org.apache.kafka.common.protocol.CommonFields.THROTTLE_TIME_MS) OffsetFetchResponse(org.apache.kafka.common.requests.OffsetFetchResponse) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) TENANT_ALLNAMESPACES_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_ALLNAMESPACES_PLACEHOLDER) GroupIdUtils(io.streamnative.pulsar.handlers.kop.utils.GroupIdUtils) OffsetCommitResponse(org.apache.kafka.common.requests.OffsetCommitResponse) ResourceType(io.streamnative.pulsar.handlers.kop.security.auth.ResourceType) TxnOffsetCommitResponse(org.apache.kafka.common.requests.TxnOffsetCommitResponse) Executor(java.util.concurrent.Executor) SystemTime(org.apache.kafka.common.utils.SystemTime) OffsetMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetMetadata) DeleteRecordsResponse(org.apache.kafka.common.requests.DeleteRecordsResponse) AclOperation(org.apache.kafka.common.acl.AclOperation) PulsarService(org.apache.pulsar.broker.PulsarService) TENANT_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_PLACEHOLDER) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) AddOffsetsToTxnResponse(org.apache.kafka.common.requests.AddOffsetsToTxnResponse) WriteTxnMarkersResponse(org.apache.kafka.common.requests.WriteTxnMarkersResponse) SimpleAclAuthorizer(io.streamnative.pulsar.handlers.kop.security.auth.SimpleAclAuthorizer) GroupCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupCoordinator) InitProducerIdRequest(org.apache.kafka.common.requests.InitProducerIdRequest) JoinGroupRequest(org.apache.kafka.common.requests.JoinGroupRequest) TopicDetails(org.apache.kafka.common.requests.CreateTopicsRequest.TopicDetails) ProduceRequest(org.apache.kafka.common.requests.ProduceRequest) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) DescribeGroupsRequest(org.apache.kafka.common.requests.DescribeGroupsRequest) ByteBuffer(java.nio.ByteBuffer) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) TopicMetadata(org.apache.kafka.common.requests.MetadataResponse.TopicMetadata) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CreatePartitionsRequest(org.apache.kafka.common.requests.CreatePartitionsRequest) ListUtils(org.apache.commons.collections4.ListUtils) DelayedOperationPurgatory(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationPurgatory) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) TopicPartition(org.apache.kafka.common.TopicPartition) OrderedScheduler(org.apache.bookkeeper.common.util.OrderedScheduler) Time(org.apache.kafka.common.utils.Time) Collection(java.util.Collection) EndTxnResponse(org.apache.kafka.common.requests.EndTxnResponse) PartitionLog(io.streamnative.pulsar.handlers.kop.storage.PartitionLog) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MessageMetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MessageMetadataUtils) Position(org.apache.bookkeeper.mledger.Position) TransactionCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.transaction.TransactionCoordinator) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) CoreUtils(io.streamnative.pulsar.handlers.kop.utils.CoreUtils) DescribeConfigsRequest(org.apache.kafka.common.requests.DescribeConfigsRequest) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) InitProducerIdResponse(org.apache.kafka.common.requests.InitProducerIdResponse) Optional(java.util.Optional) OffsetFinder(io.streamnative.pulsar.handlers.kop.utils.OffsetFinder) HeartbeatRequest(org.apache.kafka.common.requests.HeartbeatRequest) ReplicaManager(io.streamnative.pulsar.handlers.kop.storage.ReplicaManager) JoinGroupResponse(org.apache.kafka.common.requests.JoinGroupResponse) KoPTopicException(io.streamnative.pulsar.handlers.kop.exceptions.KoPTopicException) NotImplementedException(org.apache.commons.lang3.NotImplementedException) DeleteTopicsRequest(org.apache.kafka.common.requests.DeleteTopicsRequest) AddOffsetsToTxnRequest(org.apache.kafka.common.requests.AddOffsetsToTxnRequest) TopicName(org.apache.pulsar.common.naming.TopicName) Getter(lombok.Getter) CreateTopicsRequest(org.apache.kafka.common.requests.CreateTopicsRequest) EndTransactionMarker(org.apache.kafka.common.record.EndTransactionMarker) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) LeaderNotAvailableException(org.apache.kafka.common.errors.LeaderNotAvailableException) DescribeConfigsResponse(org.apache.kafka.common.requests.DescribeConfigsResponse) ApiError(org.apache.kafka.common.requests.ApiError) PartitionMetadata(org.apache.kafka.common.requests.MetadataResponse.PartitionMetadata) HashSet(java.util.HashSet) KeyValue(org.apache.pulsar.common.schema.KeyValue) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Resource(io.streamnative.pulsar.handlers.kop.security.auth.Resource) ConfigResource(org.apache.kafka.common.config.ConfigResource) EntryFormatter(io.streamnative.pulsar.handlers.kop.format.EntryFormatter) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) ByteBuf(io.netty.buffer.ByteBuf) EndTxnRequest(org.apache.kafka.common.requests.EndTxnRequest) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) SyncGroupResponse(org.apache.kafka.common.requests.SyncGroupResponse) Session(io.streamnative.pulsar.handlers.kop.security.Session) Authorizer(io.streamnative.pulsar.handlers.kop.security.auth.Authorizer) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) Utils(org.apache.kafka.common.utils.Utils) DelayedOperation(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperation) KafkaRequestUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaRequestUtils) KopTopic(io.streamnative.pulsar.handlers.kop.utils.KopTopic) OffsetCommitRequest(org.apache.kafka.common.requests.OffsetCommitRequest) Iterator(java.util.Iterator) SaslAuthenticateResponse(org.apache.kafka.common.requests.SaslAuthenticateResponse) AlterConfigsResponse(org.apache.kafka.common.requests.AlterConfigsResponse) TransactionResult(org.apache.kafka.common.requests.TransactionResult) UTF_8(java.nio.charset.StandardCharsets.UTF_8) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) OffsetFetchRequest(org.apache.kafka.common.requests.OffsetFetchRequest) TxnOffsetCommitRequest(org.apache.kafka.common.requests.TxnOffsetCommitRequest) ApiKeys(org.apache.kafka.common.protocol.ApiKeys) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AlterConfigsRequest(org.apache.kafka.common.requests.AlterConfigsRequest) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) ApiException(org.apache.kafka.common.errors.ApiException) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) ProduceRequest(org.apache.kafka.common.requests.ProduceRequest) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TopicPartition(org.apache.kafka.common.TopicPartition) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) ApiException(org.apache.kafka.common.errors.ApiException)

Example 3 with AppendRecordsContext

use of io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext in project starlight-for-kafka by datastax.

the class KafkaRequestHandler method handleProduceRequest.

@Override
protected void handleProduceRequest(KafkaHeaderAndRequest produceHar, CompletableFuture<AbstractResponse> resultFuture) {
    checkArgument(produceHar.getRequest() instanceof ProduceRequest);
    ProduceRequest produceRequest = (ProduceRequest) produceHar.getRequest();
    final int numPartitions = produceRequest.partitionRecordsOrFail().size();
    if (numPartitions == 0) {
        resultFuture.complete(new ProduceResponse(Collections.emptyMap()));
        return;
    }
    final Map<TopicPartition, PartitionResponse> unauthorizedTopicResponsesMap = new ConcurrentHashMap<>();
    final Map<TopicPartition, PartitionResponse> invalidRequestResponses = new HashMap<>();
    final Map<TopicPartition, MemoryRecords> authorizedRequestInfo = new ConcurrentHashMap<>();
    int timeoutMs = produceRequest.timeout();
    String namespacePrefix = currentNamespacePrefix();
    final AtomicInteger unfinishedAuthorizationCount = new AtomicInteger(numPartitions);
    Runnable completeOne = () -> {
        // When complete one authorization or failed, will do the action first.
        if (unfinishedAuthorizationCount.decrementAndGet() == 0) {
            if (authorizedRequestInfo.isEmpty()) {
                resultFuture.complete(new ProduceResponse(unauthorizedTopicResponsesMap));
                return;
            }
            AppendRecordsContext appendRecordsContext = AppendRecordsContext.get(topicManager, requestStats, this::startSendOperationForThrottling, this::completeSendOperationForThrottling, pendingTopicFuturesMap);
            getReplicaManager().appendRecords(timeoutMs, false, namespacePrefix, authorizedRequestInfo, PartitionLog.AppendOrigin.Client, appendRecordsContext).whenComplete((response, ex) -> {
                appendRecordsContext.recycle();
                if (ex != null) {
                    resultFuture.completeExceptionally(ex.getCause());
                    return;
                }
                Map<TopicPartition, PartitionResponse> mergedResponse = new HashMap<>();
                mergedResponse.putAll(response);
                mergedResponse.putAll(unauthorizedTopicResponsesMap);
                mergedResponse.putAll(invalidRequestResponses);
                resultFuture.complete(new ProduceResponse(mergedResponse));
            });
        }
    };
    produceRequest.partitionRecordsOrFail().forEach((topicPartition, records) -> {
        try {
            validateRecords(produceHar.getRequest().version(), records);
        } catch (ApiException ex) {
            invalidRequestResponses.put(topicPartition, new ProduceResponse.PartitionResponse(Errors.forException(ex)));
            completeOne.run();
            return;
        }
        final String fullPartitionName = KopTopic.toString(topicPartition, namespacePrefix);
        authorize(AclOperation.WRITE, Resource.of(ResourceType.TOPIC, fullPartitionName)).whenComplete((isAuthorized, ex) -> {
            if (ex != null) {
                log.error("Write topic authorize failed, topic - {}. {}", fullPartitionName, ex.getMessage());
                unauthorizedTopicResponsesMap.put(topicPartition, new ProduceResponse.PartitionResponse(Errors.TOPIC_AUTHORIZATION_FAILED));
                completeOne.run();
                return;
            }
            if (!isAuthorized) {
                unauthorizedTopicResponsesMap.put(topicPartition, new ProduceResponse.PartitionResponse(Errors.TOPIC_AUTHORIZATION_FAILED));
                completeOne.run();
                return;
            }
            authorizedRequestInfo.put(topicPartition, records);
            completeOne.run();
        });
    });
}
Also used : IsolationLevel(org.apache.kafka.common.requests.IsolationLevel) KafkaResponseUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaResponseUtils) LeaveGroupRequest(org.apache.kafka.common.requests.LeaveGroupRequest) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) HeartbeatResponse(org.apache.kafka.common.requests.HeartbeatResponse) SaslAuthenticator(io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator) Pair(org.apache.commons.lang3.tuple.Pair) SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) MetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MetadataUtils) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) MutableRecordBatch(org.apache.kafka.common.record.MutableRecordBatch) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DeleteGroupsRequest(org.apache.kafka.common.requests.DeleteGroupsRequest) Set(java.util.Set) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) AddPartitionsToTxnRequest(org.apache.kafka.common.requests.AddPartitionsToTxnRequest) ListOffsetResponse(org.apache.kafka.common.requests.ListOffsetResponse) ListGroupsRequest(org.apache.kafka.common.requests.ListGroupsRequest) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) Stream(java.util.stream.Stream) DeleteRecordsRequest(org.apache.kafka.common.requests.DeleteRecordsRequest) ListOffsetRequest(org.apache.kafka.common.requests.ListOffsetRequest) Errors(org.apache.kafka.common.protocol.Errors) Murmur3_32Hash(org.apache.pulsar.common.util.Murmur3_32Hash) Node(org.apache.kafka.common.Node) FetchRequest(org.apache.kafka.common.requests.FetchRequest) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) EntryFormatterFactory(io.streamnative.pulsar.handlers.kop.format.EntryFormatterFactory) Joiner(com.google.common.base.Joiner) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) AuthenticationException(org.apache.kafka.common.errors.AuthenticationException) TopicNameUtils(io.streamnative.pulsar.handlers.kop.utils.TopicNameUtils) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) WriteTxnMarkersRequest(org.apache.kafka.common.requests.WriteTxnMarkersRequest) MetadataStoreExtended(org.apache.pulsar.metadata.api.extended.MetadataStoreExtended) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) InvalidRecordException(org.apache.kafka.common.record.InvalidRecordException) ArrayList(java.util.ArrayList) GroupOverview(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.GroupOverview) FindCoordinatorRequest(org.apache.kafka.common.requests.FindCoordinatorRequest) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) THROTTLE_TIME_MS(org.apache.kafka.common.protocol.CommonFields.THROTTLE_TIME_MS) OffsetFetchResponse(org.apache.kafka.common.requests.OffsetFetchResponse) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) TENANT_ALLNAMESPACES_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_ALLNAMESPACES_PLACEHOLDER) GroupIdUtils(io.streamnative.pulsar.handlers.kop.utils.GroupIdUtils) OffsetCommitResponse(org.apache.kafka.common.requests.OffsetCommitResponse) ResourceType(io.streamnative.pulsar.handlers.kop.security.auth.ResourceType) TxnOffsetCommitResponse(org.apache.kafka.common.requests.TxnOffsetCommitResponse) Executor(java.util.concurrent.Executor) SystemTime(org.apache.kafka.common.utils.SystemTime) OffsetMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetMetadata) DeleteRecordsResponse(org.apache.kafka.common.requests.DeleteRecordsResponse) AclOperation(org.apache.kafka.common.acl.AclOperation) PulsarService(org.apache.pulsar.broker.PulsarService) TENANT_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_PLACEHOLDER) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) AddOffsetsToTxnResponse(org.apache.kafka.common.requests.AddOffsetsToTxnResponse) WriteTxnMarkersResponse(org.apache.kafka.common.requests.WriteTxnMarkersResponse) SimpleAclAuthorizer(io.streamnative.pulsar.handlers.kop.security.auth.SimpleAclAuthorizer) GroupCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupCoordinator) InitProducerIdRequest(org.apache.kafka.common.requests.InitProducerIdRequest) JoinGroupRequest(org.apache.kafka.common.requests.JoinGroupRequest) TopicDetails(org.apache.kafka.common.requests.CreateTopicsRequest.TopicDetails) ProduceRequest(org.apache.kafka.common.requests.ProduceRequest) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) DescribeGroupsRequest(org.apache.kafka.common.requests.DescribeGroupsRequest) ByteBuffer(java.nio.ByteBuffer) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) TopicMetadata(org.apache.kafka.common.requests.MetadataResponse.TopicMetadata) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CreatePartitionsRequest(org.apache.kafka.common.requests.CreatePartitionsRequest) ListUtils(org.apache.commons.collections4.ListUtils) DelayedOperationPurgatory(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationPurgatory) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) TopicPartition(org.apache.kafka.common.TopicPartition) OrderedScheduler(org.apache.bookkeeper.common.util.OrderedScheduler) Time(org.apache.kafka.common.utils.Time) Collection(java.util.Collection) EndTxnResponse(org.apache.kafka.common.requests.EndTxnResponse) PartitionLog(io.streamnative.pulsar.handlers.kop.storage.PartitionLog) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MessageMetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MessageMetadataUtils) PulsarMetadataAccessor(io.streamnative.pulsar.handlers.kop.security.auth.PulsarMetadataAccessor) Position(org.apache.bookkeeper.mledger.Position) TransactionCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.transaction.TransactionCoordinator) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) CoreUtils(io.streamnative.pulsar.handlers.kop.utils.CoreUtils) DescribeConfigsRequest(org.apache.kafka.common.requests.DescribeConfigsRequest) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) InitProducerIdResponse(org.apache.kafka.common.requests.InitProducerIdResponse) Optional(java.util.Optional) OffsetFinder(io.streamnative.pulsar.handlers.kop.utils.OffsetFinder) HeartbeatRequest(org.apache.kafka.common.requests.HeartbeatRequest) ReplicaManager(io.streamnative.pulsar.handlers.kop.storage.ReplicaManager) JoinGroupResponse(org.apache.kafka.common.requests.JoinGroupResponse) KoPTopicException(io.streamnative.pulsar.handlers.kop.exceptions.KoPTopicException) NotImplementedException(org.apache.commons.lang3.NotImplementedException) DeleteTopicsRequest(org.apache.kafka.common.requests.DeleteTopicsRequest) AddOffsetsToTxnRequest(org.apache.kafka.common.requests.AddOffsetsToTxnRequest) TopicName(org.apache.pulsar.common.naming.TopicName) Getter(lombok.Getter) CreateTopicsRequest(org.apache.kafka.common.requests.CreateTopicsRequest) EndTransactionMarker(org.apache.kafka.common.record.EndTransactionMarker) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) LeaderNotAvailableException(org.apache.kafka.common.errors.LeaderNotAvailableException) DescribeConfigsResponse(org.apache.kafka.common.requests.DescribeConfigsResponse) ApiError(org.apache.kafka.common.requests.ApiError) PartitionMetadata(org.apache.kafka.common.requests.MetadataResponse.PartitionMetadata) HashSet(java.util.HashSet) KeyValue(org.apache.pulsar.common.schema.KeyValue) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Resource(io.streamnative.pulsar.handlers.kop.security.auth.Resource) ConfigResource(org.apache.kafka.common.config.ConfigResource) EntryFormatter(io.streamnative.pulsar.handlers.kop.format.EntryFormatter) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) ByteBuf(io.netty.buffer.ByteBuf) EndTxnRequest(org.apache.kafka.common.requests.EndTxnRequest) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) SyncGroupResponse(org.apache.kafka.common.requests.SyncGroupResponse) Session(io.streamnative.pulsar.handlers.kop.security.Session) Authorizer(io.streamnative.pulsar.handlers.kop.security.auth.Authorizer) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) Utils(org.apache.kafka.common.utils.Utils) DelayedOperation(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperation) KafkaRequestUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaRequestUtils) KopTopic(io.streamnative.pulsar.handlers.kop.utils.KopTopic) OffsetCommitRequest(org.apache.kafka.common.requests.OffsetCommitRequest) Iterator(java.util.Iterator) SaslAuthenticateResponse(org.apache.kafka.common.requests.SaslAuthenticateResponse) AlterConfigsResponse(org.apache.kafka.common.requests.AlterConfigsResponse) TransactionResult(org.apache.kafka.common.requests.TransactionResult) UTF_8(java.nio.charset.StandardCharsets.UTF_8) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) OffsetFetchRequest(org.apache.kafka.common.requests.OffsetFetchRequest) TxnOffsetCommitRequest(org.apache.kafka.common.requests.TxnOffsetCommitRequest) ApiKeys(org.apache.kafka.common.protocol.ApiKeys) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AlterConfigsRequest(org.apache.kafka.common.requests.AlterConfigsRequest) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) ApiException(org.apache.kafka.common.errors.ApiException) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) ProduceRequest(org.apache.kafka.common.requests.ProduceRequest) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TopicPartition(org.apache.kafka.common.TopicPartition) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) ApiException(org.apache.kafka.common.errors.ApiException)

Example 4 with AppendRecordsContext

use of io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext in project kop by streamnative.

the class KafkaRequestHandler method handleWriteTxnMarkers.

@Override
protected void handleWriteTxnMarkers(KafkaHeaderAndRequest kafkaHeaderAndRequest, CompletableFuture<AbstractResponse> response) {
    WriteTxnMarkersRequest request = (WriteTxnMarkersRequest) kafkaHeaderAndRequest.getRequest();
    Map<Long, Map<TopicPartition, Errors>> errors = new ConcurrentHashMap<>();
    List<WriteTxnMarkersRequest.TxnMarkerEntry> markers = request.markers();
    AtomicInteger numAppends = new AtomicInteger(markers.size());
    if (numAppends.get() == 0) {
        response.complete(new WriteTxnMarkersResponse(errors));
        return;
    }
    BiConsumer<Long, Map<TopicPartition, Errors>> updateErrors = (producerId, currentErrors) -> {
        Map<TopicPartition, Errors> previousErrors = errors.putIfAbsent(producerId, currentErrors);
        if (previousErrors != null) {
            previousErrors.putAll(currentErrors);
        }
    };
    Runnable completeOne = () -> {
        if (numAppends.decrementAndGet() == 0) {
            response.complete(new WriteTxnMarkersResponse(errors));
        }
    };
    for (WriteTxnMarkersRequest.TxnMarkerEntry marker : markers) {
        long producerId = marker.producerId();
        TransactionResult transactionResult = marker.transactionResult();
        Map<TopicPartition, MemoryRecords> controlRecords = generateTxnMarkerRecords(marker);
        AppendRecordsContext appendRecordsContext = AppendRecordsContext.get(topicManager, requestStats, this::startSendOperationForThrottling, this::completeSendOperationForThrottling, this.pendingTopicFuturesMap);
        getReplicaManager().appendRecords(kafkaConfig.getRequestTimeoutMs(), true, currentNamespacePrefix(), controlRecords, PartitionLog.AppendOrigin.Coordinator, appendRecordsContext).whenComplete((result, ex) -> {
            appendRecordsContext.recycle();
            if (ex != null) {
                log.error("[{}] Append txn marker ({}) failed.", ctx.channel(), marker, ex);
                Map<TopicPartition, Errors> currentErrors = new HashMap<>();
                controlRecords.forEach(((topicPartition, partitionResponse) -> {
                    currentErrors.put(topicPartition, Errors.KAFKA_STORAGE_ERROR);
                }));
                updateErrors.accept(producerId, currentErrors);
                completeOne.run();
                return;
            }
            Map<TopicPartition, Errors> currentErrors = new HashMap<>();
            result.forEach(((topicPartition, partitionResponse) -> {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Append txn marker to topic : [{}], response: [{}].", ctx.channel(), topicPartition, partitionResponse);
                }
                currentErrors.put(topicPartition, partitionResponse.error);
            }));
            updateErrors.accept(producerId, currentErrors);
            final String metadataNamespace = kafkaConfig.getKafkaMetadataNamespace();
            Set<TopicPartition> successfulOffsetsPartitions = result.keySet().stream().filter(topicPartition -> KopTopic.isGroupMetadataTopicName(topicPartition.topic(), metadataNamespace)).collect(Collectors.toSet());
            if (!successfulOffsetsPartitions.isEmpty()) {
                getGroupCoordinator().scheduleHandleTxnCompletion(producerId, successfulOffsetsPartitions.stream().map(TopicPartition::partition).collect(Collectors.toSet()), transactionResult).whenComplete((__, e) -> {
                    if (e != null) {
                        log.error("Received an exception while trying to update the offsets cache on " + "transaction marker append", e);
                        ConcurrentHashMap<TopicPartition, Errors> updatedErrors = new ConcurrentHashMap<>();
                        successfulOffsetsPartitions.forEach(partition -> updatedErrors.put(partition, Errors.forException(e.getCause())));
                        updateErrors.accept(producerId, updatedErrors);
                    }
                    completeOne.run();
                });
                return;
            }
            completeOne.run();
        });
    }
}
Also used : IsolationLevel(org.apache.kafka.common.requests.IsolationLevel) KafkaResponseUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaResponseUtils) LeaveGroupRequest(org.apache.kafka.common.requests.LeaveGroupRequest) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) HeartbeatResponse(org.apache.kafka.common.requests.HeartbeatResponse) SaslAuthenticator(io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator) Pair(org.apache.commons.lang3.tuple.Pair) SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) MetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MetadataUtils) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) MutableRecordBatch(org.apache.kafka.common.record.MutableRecordBatch) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DeleteGroupsRequest(org.apache.kafka.common.requests.DeleteGroupsRequest) Set(java.util.Set) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) AddPartitionsToTxnRequest(org.apache.kafka.common.requests.AddPartitionsToTxnRequest) ListOffsetResponse(org.apache.kafka.common.requests.ListOffsetResponse) ListGroupsRequest(org.apache.kafka.common.requests.ListGroupsRequest) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) Stream(java.util.stream.Stream) DeleteRecordsRequest(org.apache.kafka.common.requests.DeleteRecordsRequest) ListOffsetRequest(org.apache.kafka.common.requests.ListOffsetRequest) Errors(org.apache.kafka.common.protocol.Errors) Murmur3_32Hash(org.apache.pulsar.common.util.Murmur3_32Hash) Node(org.apache.kafka.common.Node) FetchRequest(org.apache.kafka.common.requests.FetchRequest) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) EntryFormatterFactory(io.streamnative.pulsar.handlers.kop.format.EntryFormatterFactory) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) AuthenticationException(org.apache.kafka.common.errors.AuthenticationException) TopicNameUtils(io.streamnative.pulsar.handlers.kop.utils.TopicNameUtils) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) NewPartitions(org.apache.kafka.clients.admin.NewPartitions) WriteTxnMarkersRequest(org.apache.kafka.common.requests.WriteTxnMarkersRequest) MetadataStoreExtended(org.apache.pulsar.metadata.api.extended.MetadataStoreExtended) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) InvalidRecordException(org.apache.kafka.common.record.InvalidRecordException) ArrayList(java.util.ArrayList) GroupOverview(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.GroupOverview) FindCoordinatorRequest(org.apache.kafka.common.requests.FindCoordinatorRequest) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) THROTTLE_TIME_MS(org.apache.kafka.common.protocol.CommonFields.THROTTLE_TIME_MS) OffsetFetchResponse(org.apache.kafka.common.requests.OffsetFetchResponse) ProduceResponse(org.apache.kafka.common.requests.ProduceResponse) TENANT_ALLNAMESPACES_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_ALLNAMESPACES_PLACEHOLDER) GroupIdUtils(io.streamnative.pulsar.handlers.kop.utils.GroupIdUtils) OffsetCommitResponse(org.apache.kafka.common.requests.OffsetCommitResponse) ResourceType(io.streamnative.pulsar.handlers.kop.security.auth.ResourceType) TxnOffsetCommitResponse(org.apache.kafka.common.requests.TxnOffsetCommitResponse) Executor(java.util.concurrent.Executor) SystemTime(org.apache.kafka.common.utils.SystemTime) OffsetMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetMetadata) DeleteRecordsResponse(org.apache.kafka.common.requests.DeleteRecordsResponse) AclOperation(org.apache.kafka.common.acl.AclOperation) PulsarService(org.apache.pulsar.broker.PulsarService) TENANT_PLACEHOLDER(io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_PLACEHOLDER) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) AddOffsetsToTxnResponse(org.apache.kafka.common.requests.AddOffsetsToTxnResponse) WriteTxnMarkersResponse(org.apache.kafka.common.requests.WriteTxnMarkersResponse) SimpleAclAuthorizer(io.streamnative.pulsar.handlers.kop.security.auth.SimpleAclAuthorizer) GroupCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupCoordinator) InitProducerIdRequest(org.apache.kafka.common.requests.InitProducerIdRequest) JoinGroupRequest(org.apache.kafka.common.requests.JoinGroupRequest) TopicDetails(org.apache.kafka.common.requests.CreateTopicsRequest.TopicDetails) ProduceRequest(org.apache.kafka.common.requests.ProduceRequest) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) DescribeGroupsRequest(org.apache.kafka.common.requests.DescribeGroupsRequest) ByteBuffer(java.nio.ByteBuffer) AddPartitionsToTxnResponse(org.apache.kafka.common.requests.AddPartitionsToTxnResponse) TopicMetadata(org.apache.kafka.common.requests.MetadataResponse.TopicMetadata) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CreatePartitionsRequest(org.apache.kafka.common.requests.CreatePartitionsRequest) ListUtils(org.apache.commons.collections4.ListUtils) DelayedOperationPurgatory(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationPurgatory) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) TopicPartition(org.apache.kafka.common.TopicPartition) OrderedScheduler(org.apache.bookkeeper.common.util.OrderedScheduler) Time(org.apache.kafka.common.utils.Time) Collection(java.util.Collection) EndTxnResponse(org.apache.kafka.common.requests.EndTxnResponse) PartitionLog(io.streamnative.pulsar.handlers.kop.storage.PartitionLog) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MessageMetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MessageMetadataUtils) Position(org.apache.bookkeeper.mledger.Position) TransactionCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.transaction.TransactionCoordinator) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) CoreUtils(io.streamnative.pulsar.handlers.kop.utils.CoreUtils) DescribeConfigsRequest(org.apache.kafka.common.requests.DescribeConfigsRequest) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) List(java.util.List) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) FutureUtil(org.apache.pulsar.common.util.FutureUtil) InitProducerIdResponse(org.apache.kafka.common.requests.InitProducerIdResponse) Optional(java.util.Optional) OffsetFinder(io.streamnative.pulsar.handlers.kop.utils.OffsetFinder) HeartbeatRequest(org.apache.kafka.common.requests.HeartbeatRequest) ReplicaManager(io.streamnative.pulsar.handlers.kop.storage.ReplicaManager) JoinGroupResponse(org.apache.kafka.common.requests.JoinGroupResponse) KoPTopicException(io.streamnative.pulsar.handlers.kop.exceptions.KoPTopicException) NotImplementedException(org.apache.commons.lang3.NotImplementedException) DeleteTopicsRequest(org.apache.kafka.common.requests.DeleteTopicsRequest) AddOffsetsToTxnRequest(org.apache.kafka.common.requests.AddOffsetsToTxnRequest) TopicName(org.apache.pulsar.common.naming.TopicName) Getter(lombok.Getter) CreateTopicsRequest(org.apache.kafka.common.requests.CreateTopicsRequest) EndTransactionMarker(org.apache.kafka.common.record.EndTransactionMarker) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) LeaderNotAvailableException(org.apache.kafka.common.errors.LeaderNotAvailableException) DescribeConfigsResponse(org.apache.kafka.common.requests.DescribeConfigsResponse) ApiError(org.apache.kafka.common.requests.ApiError) PartitionMetadata(org.apache.kafka.common.requests.MetadataResponse.PartitionMetadata) HashSet(java.util.HashSet) KeyValue(org.apache.pulsar.common.schema.KeyValue) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Resource(io.streamnative.pulsar.handlers.kop.security.auth.Resource) ConfigResource(org.apache.kafka.common.config.ConfigResource) EntryFormatter(io.streamnative.pulsar.handlers.kop.format.EntryFormatter) PartitionResponse(org.apache.kafka.common.requests.ProduceResponse.PartitionResponse) ByteBuf(io.netty.buffer.ByteBuf) EndTxnRequest(org.apache.kafka.common.requests.EndTxnRequest) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) SyncGroupResponse(org.apache.kafka.common.requests.SyncGroupResponse) Session(io.streamnative.pulsar.handlers.kop.security.Session) Authorizer(io.streamnative.pulsar.handlers.kop.security.auth.Authorizer) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) Utils(org.apache.kafka.common.utils.Utils) DelayedOperation(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperation) KafkaRequestUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaRequestUtils) KopTopic(io.streamnative.pulsar.handlers.kop.utils.KopTopic) OffsetCommitRequest(org.apache.kafka.common.requests.OffsetCommitRequest) Iterator(java.util.Iterator) SaslAuthenticateResponse(org.apache.kafka.common.requests.SaslAuthenticateResponse) AlterConfigsResponse(org.apache.kafka.common.requests.AlterConfigsResponse) TransactionResult(org.apache.kafka.common.requests.TransactionResult) UTF_8(java.nio.charset.StandardCharsets.UTF_8) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) OffsetFetchRequest(org.apache.kafka.common.requests.OffsetFetchRequest) TxnOffsetCommitRequest(org.apache.kafka.common.requests.TxnOffsetCommitRequest) ApiKeys(org.apache.kafka.common.protocol.ApiKeys) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AlterConfigsRequest(org.apache.kafka.common.requests.AlterConfigsRequest) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) ApiException(org.apache.kafka.common.errors.ApiException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) WriteTxnMarkersResponse(org.apache.kafka.common.requests.WriteTxnMarkersResponse) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AppendRecordsContext(io.streamnative.pulsar.handlers.kop.storage.AppendRecordsContext) TransactionResult(org.apache.kafka.common.requests.TransactionResult) WriteTxnMarkersRequest(org.apache.kafka.common.requests.WriteTxnMarkersRequest) Errors(org.apache.kafka.common.protocol.Errors) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TopicPartition(org.apache.kafka.common.TopicPartition) AtomicLong(java.util.concurrent.atomic.AtomicLong) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) MemoryRecords(org.apache.kafka.common.record.MemoryRecords)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)4 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)4 Preconditions.checkState (com.google.common.base.Preconditions.checkState)4 Maps (com.google.common.collect.Maps)4 Sets (com.google.common.collect.Sets)4 ByteBuf (io.netty.buffer.ByteBuf)4 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)4 TENANT_ALLNAMESPACES_PLACEHOLDER (io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_ALLNAMESPACES_PLACEHOLDER)4 TENANT_PLACEHOLDER (io.streamnative.pulsar.handlers.kop.KafkaServiceConfiguration.TENANT_PLACEHOLDER)4 GroupCoordinator (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupCoordinator)4 GroupOverview (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.GroupOverview)4 TransactionCoordinator (io.streamnative.pulsar.handlers.kop.coordinator.transaction.TransactionCoordinator)4 KoPTopicException (io.streamnative.pulsar.handlers.kop.exceptions.KoPTopicException)4 EntryFormatter (io.streamnative.pulsar.handlers.kop.format.EntryFormatter)4 EntryFormatterFactory (io.streamnative.pulsar.handlers.kop.format.EntryFormatterFactory)4 OffsetAndMetadata (io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata)4 OffsetMetadata (io.streamnative.pulsar.handlers.kop.offset.OffsetMetadata)4 SaslAuthenticator (io.streamnative.pulsar.handlers.kop.security.SaslAuthenticator)4 Session (io.streamnative.pulsar.handlers.kop.security.Session)4 Authorizer (io.streamnative.pulsar.handlers.kop.security.auth.Authorizer)4