Search in sources :

Example 11 with KafkaFuture

use of org.apache.kafka.common.KafkaFuture in project apache-kafka-on-k8s by banzaicloud.

the class KafkaAdminClient method alterReplicaLogDirs.

@Override
public AlterReplicaLogDirsResult alterReplicaLogDirs(Map<TopicPartitionReplica, String> replicaAssignment, final AlterReplicaLogDirsOptions options) {
    final Map<TopicPartitionReplica, KafkaFutureImpl<Void>> futures = new HashMap<>(replicaAssignment.size());
    for (TopicPartitionReplica replica : replicaAssignment.keySet()) futures.put(replica, new KafkaFutureImpl<Void>());
    Map<Integer, Map<TopicPartition, String>> replicaAssignmentByBroker = new HashMap<>();
    for (Map.Entry<TopicPartitionReplica, String> entry : replicaAssignment.entrySet()) {
        TopicPartitionReplica replica = entry.getKey();
        String logDir = entry.getValue();
        int brokerId = replica.brokerId();
        TopicPartition topicPartition = new TopicPartition(replica.topic(), replica.partition());
        if (!replicaAssignmentByBroker.containsKey(brokerId))
            replicaAssignmentByBroker.put(brokerId, new HashMap<TopicPartition, String>());
        replicaAssignmentByBroker.get(brokerId).put(topicPartition, logDir);
    }
    final long now = time.milliseconds();
    for (Map.Entry<Integer, Map<TopicPartition, String>> entry : replicaAssignmentByBroker.entrySet()) {
        final int brokerId = entry.getKey();
        final Map<TopicPartition, String> assignment = entry.getValue();
        runnable.call(new Call("alterReplicaLogDirs", calcDeadlineMs(now, options.timeoutMs()), new ConstantNodeIdProvider(brokerId)) {

            @Override
            public AbstractRequest.Builder createRequest(int timeoutMs) {
                return new AlterReplicaLogDirsRequest.Builder(assignment);
            }

            @Override
            public void handleResponse(AbstractResponse abstractResponse) {
                AlterReplicaLogDirsResponse response = (AlterReplicaLogDirsResponse) abstractResponse;
                for (Map.Entry<TopicPartition, Errors> responseEntry : response.responses().entrySet()) {
                    TopicPartition tp = responseEntry.getKey();
                    Errors error = responseEntry.getValue();
                    TopicPartitionReplica replica = new TopicPartitionReplica(tp.topic(), tp.partition(), brokerId);
                    KafkaFutureImpl<Void> future = futures.get(replica);
                    if (future == null) {
                        handleFailure(new IllegalStateException("The partition " + tp + " in the response from broker " + brokerId + " is not in the request"));
                    } else if (error == Errors.NONE) {
                        future.complete(null);
                    } else {
                        future.completeExceptionally(error.exception());
                    }
                }
            }

            @Override
            void handleFailure(Throwable throwable) {
                completeAllExceptionally(futures.values(), throwable);
            }
        }, now);
    }
    return new AlterReplicaLogDirsResult(new HashMap<TopicPartitionReplica, KafkaFuture<Void>>(futures));
}
Also used : AlterReplicaLogDirsResponse(org.apache.kafka.common.requests.AlterReplicaLogDirsResponse) HashMap(java.util.HashMap) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) TopicPartitionReplica(org.apache.kafka.common.TopicPartitionReplica) KafkaFuture(org.apache.kafka.common.KafkaFuture) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Errors(org.apache.kafka.common.protocol.Errors) TopicPartition(org.apache.kafka.common.TopicPartition) AlterReplicaLogDirsRequest(org.apache.kafka.common.requests.AlterReplicaLogDirsRequest) Map(java.util.Map) HashMap(java.util.HashMap)

Example 12 with KafkaFuture

use of org.apache.kafka.common.KafkaFuture in project apache-kafka-on-k8s by banzaicloud.

the class KafkaAdminClient method describeTopics.

@Override
public DescribeTopicsResult describeTopics(final Collection<String> topicNames, DescribeTopicsOptions options) {
    final Map<String, KafkaFutureImpl<TopicDescription>> topicFutures = new HashMap<>(topicNames.size());
    final ArrayList<String> topicNamesList = new ArrayList<>();
    for (String topicName : topicNames) {
        if (topicNameIsUnrepresentable(topicName)) {
            KafkaFutureImpl<TopicDescription> future = new KafkaFutureImpl<TopicDescription>();
            future.completeExceptionally(new InvalidTopicException("The given topic name '" + topicName + "' cannot be represented in a request."));
            topicFutures.put(topicName, future);
        } else if (!topicFutures.containsKey(topicName)) {
            topicFutures.put(topicName, new KafkaFutureImpl<TopicDescription>());
            topicNamesList.add(topicName);
        }
    }
    final long now = time.milliseconds();
    Call call = new Call("describeTopics", calcDeadlineMs(now, options.timeoutMs()), new ControllerNodeProvider()) {

        private boolean supportsDisablingTopicCreation = true;

        @Override
        AbstractRequest.Builder createRequest(int timeoutMs) {
            if (supportsDisablingTopicCreation)
                return new MetadataRequest.Builder(topicNamesList, false);
            else
                return MetadataRequest.Builder.allTopics();
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            MetadataResponse response = (MetadataResponse) abstractResponse;
            // Handle server responses for particular topics.
            Cluster cluster = response.cluster();
            Map<String, Errors> errors = response.errors();
            for (Map.Entry<String, KafkaFutureImpl<TopicDescription>> entry : topicFutures.entrySet()) {
                String topicName = entry.getKey();
                KafkaFutureImpl<TopicDescription> future = entry.getValue();
                Errors topicError = errors.get(topicName);
                if (topicError != null) {
                    future.completeExceptionally(topicError.exception());
                    continue;
                }
                if (!cluster.topics().contains(topicName)) {
                    future.completeExceptionally(new InvalidTopicException("Topic " + topicName + " not found."));
                    continue;
                }
                boolean isInternal = cluster.internalTopics().contains(topicName);
                List<PartitionInfo> partitionInfos = cluster.partitionsForTopic(topicName);
                List<TopicPartitionInfo> partitions = new ArrayList<>(partitionInfos.size());
                for (PartitionInfo partitionInfo : partitionInfos) {
                    TopicPartitionInfo topicPartitionInfo = new TopicPartitionInfo(partitionInfo.partition(), leader(partitionInfo), Arrays.asList(partitionInfo.replicas()), Arrays.asList(partitionInfo.inSyncReplicas()));
                    partitions.add(topicPartitionInfo);
                }
                Collections.sort(partitions, new Comparator<TopicPartitionInfo>() {

                    @Override
                    public int compare(TopicPartitionInfo tp1, TopicPartitionInfo tp2) {
                        return Integer.compare(tp1.partition(), tp2.partition());
                    }
                });
                TopicDescription topicDescription = new TopicDescription(topicName, isInternal, partitions);
                future.complete(topicDescription);
            }
        }

        private Node leader(PartitionInfo partitionInfo) {
            if (partitionInfo.leader() == null || partitionInfo.leader().id() == Node.noNode().id())
                return null;
            return partitionInfo.leader();
        }

        @Override
        boolean handleUnsupportedVersionException(UnsupportedVersionException exception) {
            if (supportsDisablingTopicCreation) {
                supportsDisablingTopicCreation = false;
                return true;
            }
            return false;
        }

        @Override
        void handleFailure(Throwable throwable) {
            completeAllExceptionally(topicFutures.values(), throwable);
        }
    };
    if (!topicNamesList.isEmpty()) {
        runnable.call(call, now);
    }
    return new DescribeTopicsResult(new HashMap<String, KafkaFuture<TopicDescription>>(topicFutures));
}
Also used : HashMap(java.util.HashMap) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ArrayList(java.util.ArrayList) MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) PartitionInfo(org.apache.kafka.common.PartitionInfo) TopicPartitionInfo(org.apache.kafka.common.TopicPartitionInfo) KafkaFuture(org.apache.kafka.common.KafkaFuture) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) Cluster(org.apache.kafka.common.Cluster) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) Errors(org.apache.kafka.common.protocol.Errors) MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) TopicPartitionInfo(org.apache.kafka.common.TopicPartitionInfo) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) Map(java.util.Map) HashMap(java.util.HashMap) UnsupportedVersionException(org.apache.kafka.common.errors.UnsupportedVersionException)

Example 13 with KafkaFuture

use of org.apache.kafka.common.KafkaFuture in project apache-kafka-on-k8s by banzaicloud.

the class KafkaAdminClient method deleteTopics.

@Override
public DeleteTopicsResult deleteTopics(final Collection<String> topicNames, DeleteTopicsOptions options) {
    final Map<String, KafkaFutureImpl<Void>> topicFutures = new HashMap<>(topicNames.size());
    for (String topicName : topicNames) {
        if (topicNameIsUnrepresentable(topicName)) {
            KafkaFutureImpl<Void> future = new KafkaFutureImpl<>();
            future.completeExceptionally(new InvalidTopicException("The given topic name '" + topicName + "' cannot be represented in a request."));
            topicFutures.put(topicName, future);
        } else if (!topicFutures.containsKey(topicName)) {
            topicFutures.put(topicName, new KafkaFutureImpl<Void>());
        }
    }
    final long now = time.milliseconds();
    Call call = new Call("deleteTopics", calcDeadlineMs(now, options.timeoutMs()), new ControllerNodeProvider()) {

        @Override
        AbstractRequest.Builder createRequest(int timeoutMs) {
            return new DeleteTopicsRequest.Builder(new HashSet<>(topicNames), timeoutMs);
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            DeleteTopicsResponse response = (DeleteTopicsResponse) abstractResponse;
            // Handle server responses for particular topics.
            for (Map.Entry<String, Errors> entry : response.errors().entrySet()) {
                KafkaFutureImpl<Void> future = topicFutures.get(entry.getKey());
                if (future == null) {
                    log.warn("Server response mentioned unknown topic {}", entry.getKey());
                } else {
                    ApiException exception = entry.getValue().exception();
                    if (exception != null) {
                        future.completeExceptionally(exception);
                    } else {
                        future.complete(null);
                    }
                }
            }
            // The server should send back a response for every topic. But do a sanity check anyway.
            for (Map.Entry<String, KafkaFutureImpl<Void>> entry : topicFutures.entrySet()) {
                KafkaFutureImpl<Void> future = entry.getValue();
                if (!future.isDone()) {
                    future.completeExceptionally(new ApiException("The server response did not " + "contain a reference to node " + entry.getKey()));
                }
            }
        }

        @Override
        void handleFailure(Throwable throwable) {
            completeAllExceptionally(topicFutures.values(), throwable);
        }
    };
    if (!topicNames.isEmpty()) {
        runnable.call(call, now);
    }
    return new DeleteTopicsResult(new HashMap<String, KafkaFuture<Void>>(topicFutures));
}
Also used : KafkaFuture(org.apache.kafka.common.KafkaFuture) HashMap(java.util.HashMap) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) DeleteTopicsResponse(org.apache.kafka.common.requests.DeleteTopicsResponse) Errors(org.apache.kafka.common.protocol.Errors) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) Map(java.util.Map) HashMap(java.util.HashMap) ApiException(org.apache.kafka.common.errors.ApiException)

Example 14 with KafkaFuture

use of org.apache.kafka.common.KafkaFuture in project apache-kafka-on-k8s by banzaicloud.

the class KafkaAdminClient method deleteAcls.

@Override
public DeleteAclsResult deleteAcls(Collection<AclBindingFilter> filters, DeleteAclsOptions options) {
    final long now = time.milliseconds();
    final Map<AclBindingFilter, KafkaFutureImpl<FilterResults>> futures = new HashMap<>();
    final List<AclBindingFilter> filterList = new ArrayList<>();
    for (AclBindingFilter filter : filters) {
        if (futures.get(filter) == null) {
            filterList.add(filter);
            futures.put(filter, new KafkaFutureImpl<FilterResults>());
        }
    }
    runnable.call(new Call("deleteAcls", calcDeadlineMs(now, options.timeoutMs()), new LeastLoadedNodeProvider()) {

        @Override
        AbstractRequest.Builder createRequest(int timeoutMs) {
            return new DeleteAclsRequest.Builder(filterList);
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            DeleteAclsResponse response = (DeleteAclsResponse) abstractResponse;
            List<AclFilterResponse> responses = response.responses();
            Iterator<AclFilterResponse> iter = responses.iterator();
            for (AclBindingFilter filter : filterList) {
                KafkaFutureImpl<FilterResults> future = futures.get(filter);
                if (!iter.hasNext()) {
                    future.completeExceptionally(new UnknownServerException("The broker reported no deletion result for the given filter."));
                } else {
                    AclFilterResponse deletion = iter.next();
                    if (deletion.error().isFailure()) {
                        future.completeExceptionally(deletion.error().exception());
                    } else {
                        List<FilterResult> filterResults = new ArrayList<>();
                        for (AclDeletionResult deletionResult : deletion.deletions()) {
                            filterResults.add(new FilterResult(deletionResult.acl(), deletionResult.error().exception()));
                        }
                        future.complete(new FilterResults(filterResults));
                    }
                }
            }
        }

        @Override
        void handleFailure(Throwable throwable) {
            completeAllExceptionally(futures.values(), throwable);
        }
    }, now);
    return new DeleteAclsResult(new HashMap<AclBindingFilter, KafkaFuture<FilterResults>>(futures));
}
Also used : HashMap(java.util.HashMap) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) ArrayList(java.util.ArrayList) DeleteAclsResponse(org.apache.kafka.common.requests.DeleteAclsResponse) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) FilterResults(org.apache.kafka.clients.admin.DeleteAclsResult.FilterResults) AclBindingFilter(org.apache.kafka.common.acl.AclBindingFilter) KafkaFuture(org.apache.kafka.common.KafkaFuture) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) AclDeletionResult(org.apache.kafka.common.requests.DeleteAclsResponse.AclDeletionResult) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) DeleteAclsRequest(org.apache.kafka.common.requests.DeleteAclsRequest) UnknownServerException(org.apache.kafka.common.errors.UnknownServerException) AclFilterResponse(org.apache.kafka.common.requests.DeleteAclsResponse.AclFilterResponse) FilterResult(org.apache.kafka.clients.admin.DeleteAclsResult.FilterResult)

Example 15 with KafkaFuture

use of org.apache.kafka.common.KafkaFuture in project apache-kafka-on-k8s by banzaicloud.

the class KafkaAdminClient method createTopics.

@Override
public CreateTopicsResult createTopics(final Collection<NewTopic> newTopics, final CreateTopicsOptions options) {
    final Map<String, KafkaFutureImpl<Void>> topicFutures = new HashMap<>(newTopics.size());
    final Map<String, CreateTopicsRequest.TopicDetails> topicsMap = new HashMap<>(newTopics.size());
    for (NewTopic newTopic : newTopics) {
        if (topicNameIsUnrepresentable(newTopic.name())) {
            KafkaFutureImpl<Void> future = new KafkaFutureImpl<>();
            future.completeExceptionally(new InvalidTopicException("The given topic name '" + newTopic.name() + "' cannot be represented in a request."));
            topicFutures.put(newTopic.name(), future);
        } else if (!topicFutures.containsKey(newTopic.name())) {
            topicFutures.put(newTopic.name(), new KafkaFutureImpl<Void>());
            topicsMap.put(newTopic.name(), newTopic.convertToTopicDetails());
        }
    }
    final long now = time.milliseconds();
    Call call = new Call("createTopics", calcDeadlineMs(now, options.timeoutMs()), new ControllerNodeProvider()) {

        @Override
        public AbstractRequest.Builder createRequest(int timeoutMs) {
            return new CreateTopicsRequest.Builder(topicsMap, timeoutMs, options.shouldValidateOnly());
        }

        @Override
        public void handleResponse(AbstractResponse abstractResponse) {
            CreateTopicsResponse response = (CreateTopicsResponse) abstractResponse;
            // Handle server responses for particular topics.
            for (Map.Entry<String, ApiError> entry : response.errors().entrySet()) {
                KafkaFutureImpl<Void> future = topicFutures.get(entry.getKey());
                if (future == null) {
                    log.warn("Server response mentioned unknown topic {}", entry.getKey());
                } else {
                    ApiException exception = entry.getValue().exception();
                    if (exception != null) {
                        future.completeExceptionally(exception);
                    } else {
                        future.complete(null);
                    }
                }
            }
            // The server should send back a response for every topic. But do a sanity check anyway.
            for (Map.Entry<String, KafkaFutureImpl<Void>> entry : topicFutures.entrySet()) {
                KafkaFutureImpl<Void> future = entry.getValue();
                if (!future.isDone()) {
                    future.completeExceptionally(new ApiException("The server response did not " + "contain a reference to node " + entry.getKey()));
                }
            }
        }

        @Override
        void handleFailure(Throwable throwable) {
            completeAllExceptionally(topicFutures.values(), throwable);
        }
    };
    if (!topicsMap.isEmpty()) {
        runnable.call(call, now);
    }
    return new CreateTopicsResult(new HashMap<String, KafkaFuture<Void>>(topicFutures));
}
Also used : HashMap(java.util.HashMap) AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) CreateTopicsResponse(org.apache.kafka.common.requests.CreateTopicsResponse) KafkaFuture(org.apache.kafka.common.KafkaFuture) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) ApiError(org.apache.kafka.common.requests.ApiError) Map(java.util.Map) HashMap(java.util.HashMap) ApiException(org.apache.kafka.common.errors.ApiException)

Aggregations

KafkaFuture (org.apache.kafka.common.KafkaFuture)70 HashMap (java.util.HashMap)51 Map (java.util.Map)37 KafkaFutureImpl (org.apache.kafka.common.internals.KafkaFutureImpl)31 ExecutionException (java.util.concurrent.ExecutionException)22 TimeoutException (org.apache.kafka.common.errors.TimeoutException)21 ArrayList (java.util.ArrayList)15 UnknownTopicOrPartitionException (org.apache.kafka.common.errors.UnknownTopicOrPartitionException)15 Test (org.junit.jupiter.api.Test)15 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)14 TopicPartition (org.apache.kafka.common.TopicPartition)13 ConfigResource (org.apache.kafka.common.config.ConfigResource)12 HashSet (java.util.HashSet)11 TopicExistsException (org.apache.kafka.common.errors.TopicExistsException)10 AbstractResponse (org.apache.kafka.common.requests.AbstractResponse)8 UnsupportedVersionException (org.apache.kafka.common.errors.UnsupportedVersionException)7 ChannelBuilder (org.apache.kafka.common.network.ChannelBuilder)7 DescribeTopicsResult (org.apache.kafka.clients.admin.DescribeTopicsResult)6 Node (org.apache.kafka.common.Node)6 TopicPartitionReplica (org.apache.kafka.common.TopicPartitionReplica)6