Search in sources :

Example 16 with InvalidTopicException

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

the class MetadataTest method testInvalidTopicError.

@Test
public void testInvalidTopicError() {
    Time time = new MockTime();
    String invalidTopic = "topic dfsa";
    MetadataResponse invalidTopicResponse = RequestTestUtils.metadataUpdateWith("clusterId", 1, Collections.singletonMap(invalidTopic, Errors.INVALID_TOPIC_EXCEPTION), Collections.emptyMap());
    metadata.updateWithCurrentRequestVersion(invalidTopicResponse, false, time.milliseconds());
    InvalidTopicException e = assertThrows(InvalidTopicException.class, () -> metadata.maybeThrowAnyException());
    assertEquals(Collections.singleton(invalidTopic), e.invalidTopics());
    // We clear the exception once it has been raised to the user
    metadata.maybeThrowAnyException();
    // Reset the invalid topic error
    metadata.updateWithCurrentRequestVersion(invalidTopicResponse, false, time.milliseconds());
    // If we get a good update, the error should clear even if we haven't had a chance to raise it to the user
    metadata.updateWithCurrentRequestVersion(emptyMetadataResponse(), false, time.milliseconds());
    metadata.maybeThrowAnyException();
}
Also used : 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) Test(org.junit.jupiter.api.Test)

Example 17 with InvalidTopicException

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

the class Fetcher method getTopicMetadata.

/**
 * Get metadata for all topics present in Kafka cluster
 *
 * @param request The MetadataRequest to send
 * @param timer Timer bounding how long this method can block
 * @return The map of topics with their partition information
 */
public Map<String, List<PartitionInfo>> getTopicMetadata(MetadataRequest.Builder request, Timer timer) {
    // Save the round trip if no topics are requested.
    if (!request.isAllTopics() && request.emptyTopicList())
        return Collections.emptyMap();
    do {
        RequestFuture<ClientResponse> future = sendMetadataRequest(request);
        client.poll(future, timer);
        if (future.failed() && !future.isRetriable())
            throw future.exception();
        if (future.succeeded()) {
            MetadataResponse response = (MetadataResponse) future.value().responseBody();
            Cluster cluster = response.buildCluster();
            Set<String> unauthorizedTopics = cluster.unauthorizedTopics();
            if (!unauthorizedTopics.isEmpty())
                throw new TopicAuthorizationException(unauthorizedTopics);
            boolean shouldRetry = false;
            Map<String, Errors> errors = response.errors();
            if (!errors.isEmpty()) {
                // if there were errors, we need to check whether they were fatal or whether
                // we should just retry
                log.debug("Topic metadata fetch included errors: {}", errors);
                for (Map.Entry<String, Errors> errorEntry : errors.entrySet()) {
                    String topic = errorEntry.getKey();
                    Errors error = errorEntry.getValue();
                    if (error == Errors.INVALID_TOPIC_EXCEPTION)
                        throw new InvalidTopicException("Topic '" + topic + "' is invalid");
                    else if (error == Errors.UNKNOWN_TOPIC_OR_PARTITION)
                        // in the returned map
                        continue;
                    else if (error.exception() instanceof RetriableException)
                        shouldRetry = true;
                    else
                        throw new KafkaException("Unexpected error fetching metadata for topic " + topic, error.exception());
                }
            }
            if (!shouldRetry) {
                HashMap<String, List<PartitionInfo>> topicsPartitionInfos = new HashMap<>();
                for (String topic : cluster.topics()) topicsPartitionInfos.put(topic, cluster.partitionsForTopic(topic));
                return topicsPartitionInfos;
            }
        }
        timer.sleep(retryBackoffMs);
    } while (timer.notExpired());
    throw new TimeoutException("Timeout expired while fetching topic metadata");
}
Also used : ClientResponse(org.apache.kafka.clients.ClientResponse) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Cluster(org.apache.kafka.common.Cluster) Errors(org.apache.kafka.common.protocol.Errors) MetadataResponse(org.apache.kafka.common.requests.MetadataResponse) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) KafkaException(org.apache.kafka.common.KafkaException) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TopicAuthorizationException(org.apache.kafka.common.errors.TopicAuthorizationException) RetriableException(org.apache.kafka.common.errors.RetriableException) TimeoutException(org.apache.kafka.common.errors.TimeoutException)

Example 18 with InvalidTopicException

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

the class DescribeProducersHandlerTest method testInvalidTopic.

@Test
public void testInvalidTopic() {
    TopicPartition topicPartition = new TopicPartition("foo", 5);
    Throwable exception = assertFatalError(topicPartition, Errors.INVALID_TOPIC_EXCEPTION);
    assertTrue(exception instanceof InvalidTopicException);
    InvalidTopicException invalidTopicException = (InvalidTopicException) exception;
    assertEquals(mkSet("foo"), invalidTopicException.invalidTopics());
}
Also used : TopicPartition(org.apache.kafka.common.TopicPartition) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) Test(org.junit.jupiter.api.Test)

Example 19 with InvalidTopicException

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

the class WorkerSourceTaskTest method testSendRecordsProducerSendFailsImmediately.

@Test
public void testSendRecordsProducerSendFailsImmediately() {
    if (!enableTopicCreation)
        // should only test with topic creation enabled
        return;
    createWorkerTask();
    SourceRecord record1 = new SourceRecord(PARTITION, OFFSET, TOPIC, 1, KEY_SCHEMA, KEY, RECORD_SCHEMA, RECORD);
    SourceRecord record2 = new SourceRecord(PARTITION, OFFSET, TOPIC, 2, KEY_SCHEMA, KEY, RECORD_SCHEMA, RECORD);
    expectPreliminaryCalls();
    expectTopicCreation(TOPIC);
    EasyMock.expect(producer.send(EasyMock.anyObject(), EasyMock.anyObject())).andThrow(new KafkaException("Producer closed while send in progress", new InvalidTopicException(TOPIC)));
    PowerMock.replayAll();
    Whitebox.setInternalState(workerTask, "toSend", Arrays.asList(record1, record2));
    assertThrows(ConnectException.class, () -> Whitebox.invokeMethod(workerTask, "sendRecords"));
}
Also used : InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) KafkaException(org.apache.kafka.common.KafkaException) SourceRecord(org.apache.kafka.connect.source.SourceRecord) ThreadedTest(org.apache.kafka.connect.util.ThreadedTest) RetryWithToleranceOperatorTest(org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperatorTest) ParameterizedTest(org.apache.kafka.connect.util.ParameterizedTest) Test(org.junit.Test)

Example 20 with InvalidTopicException

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

the class KafkaAdminClient method alterPartitionReassignments.

@Override
public AlterPartitionReassignmentsResult alterPartitionReassignments(Map<TopicPartition, Optional<NewPartitionReassignment>> reassignments, AlterPartitionReassignmentsOptions options) {
    final Map<TopicPartition, KafkaFutureImpl<Void>> futures = new HashMap<>();
    final Map<String, Map<Integer, Optional<NewPartitionReassignment>>> topicsToReassignments = new TreeMap<>();
    for (Map.Entry<TopicPartition, Optional<NewPartitionReassignment>> entry : reassignments.entrySet()) {
        String topic = entry.getKey().topic();
        int partition = entry.getKey().partition();
        TopicPartition topicPartition = new TopicPartition(topic, partition);
        Optional<NewPartitionReassignment> reassignment = entry.getValue();
        KafkaFutureImpl<Void> future = new KafkaFutureImpl<>();
        futures.put(topicPartition, future);
        if (topicNameIsUnrepresentable(topic)) {
            future.completeExceptionally(new InvalidTopicException("The given topic name '" + topic + "' cannot be represented in a request."));
        } else if (topicPartition.partition() < 0) {
            future.completeExceptionally(new InvalidTopicException("The given partition index " + topicPartition.partition() + " is not valid."));
        } else {
            Map<Integer, Optional<NewPartitionReassignment>> partitionReassignments = topicsToReassignments.get(topicPartition.topic());
            if (partitionReassignments == null) {
                partitionReassignments = new TreeMap<>();
                topicsToReassignments.put(topic, partitionReassignments);
            }
            partitionReassignments.put(partition, reassignment);
        }
    }
    final long now = time.milliseconds();
    Call call = new Call("alterPartitionReassignments", calcDeadlineMs(now, options.timeoutMs()), new ControllerNodeProvider()) {

        @Override
        public AlterPartitionReassignmentsRequest.Builder createRequest(int timeoutMs) {
            AlterPartitionReassignmentsRequestData data = new AlterPartitionReassignmentsRequestData();
            for (Map.Entry<String, Map<Integer, Optional<NewPartitionReassignment>>> entry : topicsToReassignments.entrySet()) {
                String topicName = entry.getKey();
                Map<Integer, Optional<NewPartitionReassignment>> partitionsToReassignments = entry.getValue();
                List<ReassignablePartition> reassignablePartitions = new ArrayList<>();
                for (Map.Entry<Integer, Optional<NewPartitionReassignment>> partitionEntry : partitionsToReassignments.entrySet()) {
                    int partitionIndex = partitionEntry.getKey();
                    Optional<NewPartitionReassignment> reassignment = partitionEntry.getValue();
                    ReassignablePartition reassignablePartition = new ReassignablePartition().setPartitionIndex(partitionIndex).setReplicas(reassignment.map(NewPartitionReassignment::targetReplicas).orElse(null));
                    reassignablePartitions.add(reassignablePartition);
                }
                ReassignableTopic reassignableTopic = new ReassignableTopic().setName(topicName).setPartitions(reassignablePartitions);
                data.topics().add(reassignableTopic);
            }
            data.setTimeoutMs(timeoutMs);
            return new AlterPartitionReassignmentsRequest.Builder(data);
        }

        @Override
        public void handleResponse(AbstractResponse abstractResponse) {
            AlterPartitionReassignmentsResponse response = (AlterPartitionReassignmentsResponse) abstractResponse;
            Map<TopicPartition, ApiException> errors = new HashMap<>();
            int receivedResponsesCount = 0;
            Errors topLevelError = Errors.forCode(response.data().errorCode());
            switch(topLevelError) {
                case NONE:
                    receivedResponsesCount += validateTopicResponses(response.data().responses(), errors);
                    break;
                case NOT_CONTROLLER:
                    handleNotControllerError(topLevelError);
                    break;
                default:
                    for (ReassignableTopicResponse topicResponse : response.data().responses()) {
                        String topicName = topicResponse.name();
                        for (ReassignablePartitionResponse partition : topicResponse.partitions()) {
                            errors.put(new TopicPartition(topicName, partition.partitionIndex()), new ApiError(topLevelError, response.data().errorMessage()).exception());
                            receivedResponsesCount += 1;
                        }
                    }
                    break;
            }
            assertResponseCountMatch(errors, receivedResponsesCount);
            for (Map.Entry<TopicPartition, ApiException> entry : errors.entrySet()) {
                ApiException exception = entry.getValue();
                if (exception == null)
                    futures.get(entry.getKey()).complete(null);
                else
                    futures.get(entry.getKey()).completeExceptionally(exception);
            }
        }

        private void assertResponseCountMatch(Map<TopicPartition, ApiException> errors, int receivedResponsesCount) {
            int expectedResponsesCount = topicsToReassignments.values().stream().mapToInt(Map::size).sum();
            if (errors.values().stream().noneMatch(Objects::nonNull) && receivedResponsesCount != expectedResponsesCount) {
                String quantifier = receivedResponsesCount > expectedResponsesCount ? "many" : "less";
                throw new UnknownServerException("The server returned too " + quantifier + " results." + "Expected " + expectedResponsesCount + " but received " + receivedResponsesCount);
            }
        }

        private int validateTopicResponses(List<ReassignableTopicResponse> topicResponses, Map<TopicPartition, ApiException> errors) {
            int receivedResponsesCount = 0;
            for (ReassignableTopicResponse topicResponse : topicResponses) {
                String topicName = topicResponse.name();
                for (ReassignablePartitionResponse partResponse : topicResponse.partitions()) {
                    Errors partitionError = Errors.forCode(partResponse.errorCode());
                    TopicPartition tp = new TopicPartition(topicName, partResponse.partitionIndex());
                    if (partitionError == Errors.NONE) {
                        errors.put(tp, null);
                    } else {
                        errors.put(tp, new ApiError(partitionError, partResponse.errorMessage()).exception());
                    }
                    receivedResponsesCount += 1;
                }
            }
            return receivedResponsesCount;
        }

        @Override
        void handleFailure(Throwable throwable) {
            for (KafkaFutureImpl<Void> future : futures.values()) {
                future.completeExceptionally(throwable);
            }
        }
    };
    if (!topicsToReassignments.isEmpty()) {
        runnable.call(call, now);
    }
    return new AlterPartitionReassignmentsResult(new HashMap<>(futures));
}
Also used : ReassignablePartition(org.apache.kafka.common.message.AlterPartitionReassignmentsRequestData.ReassignablePartition) HashMap(java.util.HashMap) ReassignableTopic(org.apache.kafka.common.message.AlterPartitionReassignmentsRequestData.ReassignableTopic) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) ArrayList(java.util.ArrayList) AlterPartitionReassignmentsResponse(org.apache.kafka.common.requests.AlterPartitionReassignmentsResponse) ReassignableTopicResponse(org.apache.kafka.common.message.AlterPartitionReassignmentsResponseData.ReassignableTopicResponse) LinkedList(java.util.LinkedList) ArrayList(java.util.ArrayList) List(java.util.List) AlterPartitionReassignmentsRequest(org.apache.kafka.common.requests.AlterPartitionReassignmentsRequest) Optional(java.util.Optional) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) ReassignablePartitionResponse(org.apache.kafka.common.message.AlterPartitionReassignmentsResponseData.ReassignablePartitionResponse) AlterPartitionReassignmentsRequestData(org.apache.kafka.common.message.AlterPartitionReassignmentsRequestData) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) TreeMap(java.util.TreeMap) UnknownServerException(org.apache.kafka.common.errors.UnknownServerException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Errors(org.apache.kafka.common.protocol.Errors) 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) ApiException(org.apache.kafka.common.errors.ApiException)

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