Search in sources :

Example 46 with AbstractResponse

use of org.apache.kafka.common.requests.AbstractResponse in project kafka by apache.

the class KafkaAdminClient method listPartitionReassignments.

@Override
public ListPartitionReassignmentsResult listPartitionReassignments(Optional<Set<TopicPartition>> partitions, ListPartitionReassignmentsOptions options) {
    final KafkaFutureImpl<Map<TopicPartition, PartitionReassignment>> partitionReassignmentsFuture = new KafkaFutureImpl<>();
    if (partitions.isPresent()) {
        for (TopicPartition tp : partitions.get()) {
            String topic = tp.topic();
            int partition = tp.partition();
            if (topicNameIsUnrepresentable(topic)) {
                partitionReassignmentsFuture.completeExceptionally(new InvalidTopicException("The given topic name '" + topic + "' cannot be represented in a request."));
            } else if (partition < 0) {
                partitionReassignmentsFuture.completeExceptionally(new InvalidTopicException("The given partition index " + partition + " is not valid."));
            }
            if (partitionReassignmentsFuture.isCompletedExceptionally())
                return new ListPartitionReassignmentsResult(partitionReassignmentsFuture);
        }
    }
    final long now = time.milliseconds();
    runnable.call(new Call("listPartitionReassignments", calcDeadlineMs(now, options.timeoutMs()), new ControllerNodeProvider()) {

        @Override
        ListPartitionReassignmentsRequest.Builder createRequest(int timeoutMs) {
            ListPartitionReassignmentsRequestData listData = new ListPartitionReassignmentsRequestData();
            listData.setTimeoutMs(timeoutMs);
            if (partitions.isPresent()) {
                Map<String, ListPartitionReassignmentsTopics> reassignmentTopicByTopicName = new HashMap<>();
                for (TopicPartition tp : partitions.get()) {
                    if (!reassignmentTopicByTopicName.containsKey(tp.topic()))
                        reassignmentTopicByTopicName.put(tp.topic(), new ListPartitionReassignmentsTopics().setName(tp.topic()));
                    reassignmentTopicByTopicName.get(tp.topic()).partitionIndexes().add(tp.partition());
                }
                listData.setTopics(new ArrayList<>(reassignmentTopicByTopicName.values()));
            }
            return new ListPartitionReassignmentsRequest.Builder(listData);
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            ListPartitionReassignmentsResponse response = (ListPartitionReassignmentsResponse) abstractResponse;
            Errors error = Errors.forCode(response.data().errorCode());
            switch(error) {
                case NONE:
                    break;
                case NOT_CONTROLLER:
                    handleNotControllerError(error);
                    break;
                default:
                    partitionReassignmentsFuture.completeExceptionally(new ApiError(error, response.data().errorMessage()).exception());
                    break;
            }
            Map<TopicPartition, PartitionReassignment> reassignmentMap = new HashMap<>();
            for (OngoingTopicReassignment topicReassignment : response.data().topics()) {
                String topicName = topicReassignment.name();
                for (OngoingPartitionReassignment partitionReassignment : topicReassignment.partitions()) {
                    reassignmentMap.put(new TopicPartition(topicName, partitionReassignment.partitionIndex()), new PartitionReassignment(partitionReassignment.replicas(), partitionReassignment.addingReplicas(), partitionReassignment.removingReplicas()));
                }
            }
            partitionReassignmentsFuture.complete(reassignmentMap);
        }

        @Override
        void handleFailure(Throwable throwable) {
            partitionReassignmentsFuture.completeExceptionally(throwable);
        }
    }, now);
    return new ListPartitionReassignmentsResult(partitionReassignmentsFuture);
}
Also used : ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) ArrayList(java.util.ArrayList) ListPartitionReassignmentsResponse(org.apache.kafka.common.requests.ListPartitionReassignmentsResponse) OngoingPartitionReassignment(org.apache.kafka.common.message.ListPartitionReassignmentsResponseData.OngoingPartitionReassignment) ListPartitionReassignmentsRequest(org.apache.kafka.common.requests.ListPartitionReassignmentsRequest) ListPartitionReassignmentsTopics(org.apache.kafka.common.message.ListPartitionReassignmentsRequestData.ListPartitionReassignmentsTopics) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) OngoingTopicReassignment(org.apache.kafka.common.message.ListPartitionReassignmentsResponseData.OngoingTopicReassignment) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) ListPartitionReassignmentsRequestData(org.apache.kafka.common.message.ListPartitionReassignmentsRequestData) Errors(org.apache.kafka.common.protocol.Errors) OngoingPartitionReassignment(org.apache.kafka.common.message.ListPartitionReassignmentsResponseData.OngoingPartitionReassignment) TopicPartition(org.apache.kafka.common.TopicPartition) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) ApiError(org.apache.kafka.common.requests.ApiError) Map(java.util.Map) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap)

Example 47 with AbstractResponse

use of org.apache.kafka.common.requests.AbstractResponse in project kafka by apache.

the class KafkaAdminClient method getMetadataCall.

/**
 * Returns a {@code Call} object to fetch the cluster metadata. Takes a List of Calls
 * parameter to schedule actions that need to be taken using the metadata. The param is a Supplier
 * so that it can be lazily created, so that it can use the results of the metadata call in its
 * construction.
 *
 * @param <T> The type of return value of the KafkaFuture, like ListOffsetsResultInfo, etc.
 * @param <O> The type of configuration option, like ListOffsetsOptions, etc
 */
private <T, O extends AbstractOptions<O>> Call getMetadataCall(MetadataOperationContext<T, O> context, Supplier<List<Call>> nextCalls) {
    return new Call("metadata", context.deadline(), new LeastLoadedNodeProvider()) {

        @Override
        MetadataRequest.Builder createRequest(int timeoutMs) {
            return new MetadataRequest.Builder(new MetadataRequestData().setTopics(convertToMetadataRequestTopic(context.topics())).setAllowAutoTopicCreation(false));
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            MetadataResponse response = (MetadataResponse) abstractResponse;
            MetadataOperationContext.handleMetadataErrors(response);
            context.setResponse(Optional.of(response));
            for (Call call : nextCalls.get()) {
                runnable.call(call, time.milliseconds());
            }
        }

        @Override
        void handleFailure(Throwable throwable) {
            for (KafkaFutureImpl<T> future : context.futures().values()) {
                future.completeExceptionally(throwable);
            }
        }
    };
}
Also used : MetadataRequest(org.apache.kafka.common.requests.MetadataRequest) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) MetadataRequestData(org.apache.kafka.common.message.MetadataRequestData)

Example 48 with AbstractResponse

use of org.apache.kafka.common.requests.AbstractResponse in project kafka by apache.

the class KafkaAdminClient method getCreatePartitionsCall.

private Call getCreatePartitionsCall(final CreatePartitionsOptions options, final Map<String, KafkaFutureImpl<Void>> futures, final CreatePartitionsTopicCollection topics, final Map<String, ThrottlingQuotaExceededException> quotaExceededExceptions, final long now, final long deadline) {
    return new Call("createPartitions", deadline, new ControllerNodeProvider()) {

        @Override
        public CreatePartitionsRequest.Builder createRequest(int timeoutMs) {
            return new CreatePartitionsRequest.Builder(new CreatePartitionsRequestData().setTopics(topics).setValidateOnly(options.validateOnly()).setTimeoutMs(timeoutMs));
        }

        @Override
        public void handleResponse(AbstractResponse abstractResponse) {
            // Check for controller change
            handleNotControllerError(abstractResponse);
            // Handle server responses for particular topics.
            final CreatePartitionsResponse response = (CreatePartitionsResponse) abstractResponse;
            final CreatePartitionsTopicCollection retryTopics = new CreatePartitionsTopicCollection();
            final Map<String, ThrottlingQuotaExceededException> retryTopicQuotaExceededExceptions = new HashMap<>();
            for (CreatePartitionsTopicResult result : response.data().results()) {
                KafkaFutureImpl<Void> future = futures.get(result.name());
                if (future == null) {
                    log.warn("Server response mentioned unknown topic {}", result.name());
                } else {
                    ApiError error = new ApiError(result.errorCode(), result.errorMessage());
                    if (error.isFailure()) {
                        if (error.is(Errors.THROTTLING_QUOTA_EXCEEDED)) {
                            ThrottlingQuotaExceededException quotaExceededException = new ThrottlingQuotaExceededException(response.throttleTimeMs(), error.messageWithFallback());
                            if (options.shouldRetryOnQuotaViolation()) {
                                retryTopics.add(topics.find(result.name()).duplicate());
                                retryTopicQuotaExceededExceptions.put(result.name(), quotaExceededException);
                            } else {
                                future.completeExceptionally(quotaExceededException);
                            }
                        } else {
                            future.completeExceptionally(error.exception());
                        }
                    } else {
                        future.complete(null);
                    }
                }
            }
            // If there are topics to retry, retry them; complete unrealized futures otherwise.
            if (retryTopics.isEmpty()) {
                // The server should send back a response for every topic. But do a sanity check anyway.
                completeUnrealizedFutures(futures.entrySet().stream(), topic -> "The controller response did not contain a result for topic " + topic);
            } else {
                final long now = time.milliseconds();
                final Call call = getCreatePartitionsCall(options, futures, retryTopics, retryTopicQuotaExceededExceptions, now, deadline);
                runnable.call(call, now);
            }
        }

        @Override
        void handleFailure(Throwable throwable) {
            // If there were any topics retries due to a quota exceeded exception, we propagate
            // the initial error back to the caller if the request timed out.
            maybeCompleteQuotaExceededException(options.shouldRetryOnQuotaViolation(), throwable, futures, quotaExceededExceptions, (int) (time.milliseconds() - now));
            // Fail all the other remaining futures
            completeAllExceptionally(futures.values(), throwable);
        }
    };
}
Also used : CreatePartitionsTopicCollection(org.apache.kafka.common.message.CreatePartitionsRequestData.CreatePartitionsTopicCollection) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) HashMap(java.util.HashMap) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) CreatePartitionsTopicResult(org.apache.kafka.common.message.CreatePartitionsResponseData.CreatePartitionsTopicResult) ThrottlingQuotaExceededException(org.apache.kafka.common.errors.ThrottlingQuotaExceededException) CreatePartitionsResponse(org.apache.kafka.common.requests.CreatePartitionsResponse) CreatePartitionsRequest(org.apache.kafka.common.requests.CreatePartitionsRequest) CreatePartitionsRequestData(org.apache.kafka.common.message.CreatePartitionsRequestData) ApiError(org.apache.kafka.common.requests.ApiError)

Example 49 with AbstractResponse

use of org.apache.kafka.common.requests.AbstractResponse in project kafka by apache.

the class KafkaAdminClient method updateFeatures.

@Override
public UpdateFeaturesResult updateFeatures(final Map<String, FeatureUpdate> featureUpdates, final UpdateFeaturesOptions options) {
    if (featureUpdates.isEmpty()) {
        throw new IllegalArgumentException("Feature updates can not be null or empty.");
    }
    final Map<String, KafkaFutureImpl<Void>> updateFutures = new HashMap<>();
    for (final Map.Entry<String, FeatureUpdate> entry : featureUpdates.entrySet()) {
        final String feature = entry.getKey();
        if (Utils.isBlank(feature)) {
            throw new IllegalArgumentException("Provided feature can not be empty.");
        }
        updateFutures.put(entry.getKey(), new KafkaFutureImpl<>());
    }
    final long now = time.milliseconds();
    final Call call = new Call("updateFeatures", calcDeadlineMs(now, options.timeoutMs()), new ControllerNodeProvider()) {

        @Override
        UpdateFeaturesRequest.Builder createRequest(int timeoutMs) {
            final UpdateFeaturesRequestData.FeatureUpdateKeyCollection featureUpdatesRequestData = new UpdateFeaturesRequestData.FeatureUpdateKeyCollection();
            for (Map.Entry<String, FeatureUpdate> entry : featureUpdates.entrySet()) {
                final String feature = entry.getKey();
                final FeatureUpdate update = entry.getValue();
                final UpdateFeaturesRequestData.FeatureUpdateKey requestItem = new UpdateFeaturesRequestData.FeatureUpdateKey();
                requestItem.setFeature(feature);
                requestItem.setMaxVersionLevel(update.maxVersionLevel());
                requestItem.setAllowDowngrade(update.allowDowngrade());
                featureUpdatesRequestData.add(requestItem);
            }
            return new UpdateFeaturesRequest.Builder(new UpdateFeaturesRequestData().setTimeoutMs(timeoutMs).setFeatureUpdates(featureUpdatesRequestData));
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            final UpdateFeaturesResponse response = (UpdateFeaturesResponse) abstractResponse;
            ApiError topLevelError = response.topLevelError();
            switch(topLevelError.error()) {
                case NONE:
                    for (final UpdatableFeatureResult result : response.data().results()) {
                        final KafkaFutureImpl<Void> future = updateFutures.get(result.feature());
                        if (future == null) {
                            log.warn("Server response mentioned unknown feature {}", result.feature());
                        } else {
                            final Errors error = Errors.forCode(result.errorCode());
                            if (error == Errors.NONE) {
                                future.complete(null);
                            } else {
                                future.completeExceptionally(error.exception(result.errorMessage()));
                            }
                        }
                    }
                    // The server should send back a response for every feature, but we do a sanity check anyway.
                    completeUnrealizedFutures(updateFutures.entrySet().stream(), feature -> "The controller response did not contain a result for feature " + feature);
                    break;
                case NOT_CONTROLLER:
                    handleNotControllerError(topLevelError.error());
                    break;
                default:
                    for (final Map.Entry<String, KafkaFutureImpl<Void>> entry : updateFutures.entrySet()) {
                        entry.getValue().completeExceptionally(topLevelError.exception());
                    }
                    break;
            }
        }

        @Override
        void handleFailure(Throwable throwable) {
            completeAllExceptionally(updateFutures.values(), throwable);
        }
    };
    runnable.call(call, now);
    return new UpdateFeaturesResult(new HashMap<>(updateFutures));
}
Also used : UpdateFeaturesResponse(org.apache.kafka.common.requests.UpdateFeaturesResponse) HashMap(java.util.HashMap) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) UpdateFeaturesRequest(org.apache.kafka.common.requests.UpdateFeaturesRequest) UpdatableFeatureResult(org.apache.kafka.common.message.UpdateFeaturesResponseData.UpdatableFeatureResult) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) Errors(org.apache.kafka.common.protocol.Errors) UpdateFeaturesRequestData(org.apache.kafka.common.message.UpdateFeaturesRequestData) ApiError(org.apache.kafka.common.requests.ApiError) Map(java.util.Map) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap)

Aggregations

AbstractResponse (org.apache.kafka.common.requests.AbstractResponse)49 HashMap (java.util.HashMap)38 ChannelBuilder (org.apache.kafka.common.network.ChannelBuilder)38 KafkaFutureImpl (org.apache.kafka.common.internals.KafkaFutureImpl)36 ArrayList (java.util.ArrayList)28 Map (java.util.Map)26 Errors (org.apache.kafka.common.protocol.Errors)21 ApiError (org.apache.kafka.common.requests.ApiError)18 KafkaFuture (org.apache.kafka.common.KafkaFuture)16 List (java.util.List)15 TreeMap (java.util.TreeMap)15 MetadataResponse (org.apache.kafka.common.requests.MetadataResponse)15 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)14 TopicPartition (org.apache.kafka.common.TopicPartition)14 InvalidTopicException (org.apache.kafka.common.errors.InvalidTopicException)14 LinkedList (java.util.LinkedList)13 MetadataRequest (org.apache.kafka.common.requests.MetadataRequest)13 Set (java.util.Set)12 ApiException (org.apache.kafka.common.errors.ApiException)12 HashSet (java.util.HashSet)11