Search in sources :

Example 1 with InvalidTopicException

use of org.apache.kafka.common.errors.InvalidTopicException 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 2 with InvalidTopicException

use of org.apache.kafka.common.errors.InvalidTopicException 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 3 with InvalidTopicException

use of org.apache.kafka.common.errors.InvalidTopicException 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)

Example 4 with InvalidTopicException

use of org.apache.kafka.common.errors.InvalidTopicException in project kafka by apache.

the class MetadataTest method testMetadataTopicErrors.

@Test
public void testMetadataTopicErrors() {
    Time time = new MockTime();
    Map<String, Errors> topicErrors = new HashMap<>(3);
    topicErrors.put("invalidTopic", Errors.INVALID_TOPIC_EXCEPTION);
    topicErrors.put("sensitiveTopic1", Errors.TOPIC_AUTHORIZATION_FAILED);
    topicErrors.put("sensitiveTopic2", Errors.TOPIC_AUTHORIZATION_FAILED);
    MetadataResponse metadataResponse = RequestTestUtils.metadataUpdateWith("clusterId", 1, topicErrors, Collections.emptyMap());
    metadata.updateWithCurrentRequestVersion(metadataResponse, false, time.milliseconds());
    TopicAuthorizationException e1 = assertThrows(TopicAuthorizationException.class, () -> metadata.maybeThrowExceptionForTopic("sensitiveTopic1"));
    assertEquals(Collections.singleton("sensitiveTopic1"), e1.unauthorizedTopics());
    // We clear the exception once it has been raised to the user
    metadata.maybeThrowAnyException();
    metadata.updateWithCurrentRequestVersion(metadataResponse, false, time.milliseconds());
    TopicAuthorizationException e2 = assertThrows(TopicAuthorizationException.class, () -> metadata.maybeThrowExceptionForTopic("sensitiveTopic2"));
    assertEquals(Collections.singleton("sensitiveTopic2"), e2.unauthorizedTopics());
    metadata.maybeThrowAnyException();
    metadata.updateWithCurrentRequestVersion(metadataResponse, false, time.milliseconds());
    InvalidTopicException e3 = assertThrows(InvalidTopicException.class, () -> metadata.maybeThrowExceptionForTopic("invalidTopic"));
    assertEquals(Collections.singleton("invalidTopic"), e3.invalidTopics());
    metadata.maybeThrowAnyException();
    // Other topics should not throw exception, but they should clear existing exception
    metadata.updateWithCurrentRequestVersion(metadataResponse, false, time.milliseconds());
    metadata.maybeThrowExceptionForTopic("anotherTopic");
    metadata.maybeThrowAnyException();
}
Also used : Errors(org.apache.kafka.common.protocol.Errors) HashMap(java.util.HashMap) MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) MockTime(org.apache.kafka.common.utils.MockTime) Time(org.apache.kafka.common.utils.Time) MockTime(org.apache.kafka.common.utils.MockTime) TopicAuthorizationException(org.apache.kafka.common.errors.TopicAuthorizationException) Test(org.junit.jupiter.api.Test)

Example 5 with InvalidTopicException

use of org.apache.kafka.common.errors.InvalidTopicException in project kafka by apache.

the class KafkaAdminClient method createTopics.

@Override
public CreateTopicsResult createTopics(final Collection<NewTopic> newTopics, final CreateTopicsOptions options) {
    final Map<String, KafkaFutureImpl<TopicMetadataAndConfig>> topicFutures = new HashMap<>(newTopics.size());
    final CreatableTopicCollection topics = new CreatableTopicCollection();
    for (NewTopic newTopic : newTopics) {
        if (topicNameIsUnrepresentable(newTopic.name())) {
            KafkaFutureImpl<TopicMetadataAndConfig> 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<>());
            topics.add(newTopic.convertToCreatableTopic());
        }
    }
    if (!topics.isEmpty()) {
        final long now = time.milliseconds();
        final long deadline = calcDeadlineMs(now, options.timeoutMs());
        final Call call = getCreateTopicsCall(options, topicFutures, topics, Collections.emptyMap(), now, deadline);
        runnable.call(call, now);
    }
    return new CreateTopicsResult(new HashMap<>(topicFutures));
}
Also used : HashMap(java.util.HashMap) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) CreatableTopicCollection(org.apache.kafka.common.message.CreateTopicsRequestData.CreatableTopicCollection) TopicMetadataAndConfig(org.apache.kafka.clients.admin.CreateTopicsResult.TopicMetadataAndConfig) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException)

Aggregations

InvalidTopicException (org.apache.kafka.common.errors.InvalidTopicException)23 HashMap (java.util.HashMap)15 ArrayList (java.util.ArrayList)11 Map (java.util.Map)10 KafkaFutureImpl (org.apache.kafka.common.internals.KafkaFutureImpl)10 Errors (org.apache.kafka.common.protocol.Errors)10 MetadataResponse (org.apache.kafka.common.requests.MetadataResponse)8 Cluster (org.apache.kafka.common.Cluster)7 AbstractResponse (org.apache.kafka.common.requests.AbstractResponse)7 TopicAuthorizationException (org.apache.kafka.common.errors.TopicAuthorizationException)6 TopicPartition (org.apache.kafka.common.TopicPartition)5 ChannelBuilder (org.apache.kafka.common.network.ChannelBuilder)5 List (java.util.List)4 TreeMap (java.util.TreeMap)4 KafkaException (org.apache.kafka.common.KafkaException)4 KafkaFuture (org.apache.kafka.common.KafkaFuture)4 TimeoutException (org.apache.kafka.common.errors.TimeoutException)4 ApiError (org.apache.kafka.common.requests.ApiError)4 Test (org.junit.jupiter.api.Test)4 LinkedHashMap (java.util.LinkedHashMap)3