Search in sources :

Example 91 with Uuid

use of org.apache.kafka.common.Uuid in project kafka by apache.

the class FetchSessionHandlerTest method testVerifyFullFetchResponsePartitionsWithTopicIds.

@Test
public void testVerifyFullFetchResponsePartitionsWithTopicIds() {
    Map<String, Uuid> topicIds = new HashMap<>();
    Map<Uuid, String> topicNames = new HashMap<>();
    FetchSessionHandler handler = new FetchSessionHandler(LOG_CONTEXT, 1);
    addTopicId(topicIds, topicNames, "foo", ApiKeys.FETCH.latestVersion());
    addTopicId(topicIds, topicNames, "bar", ApiKeys.FETCH.latestVersion());
    addTopicId(topicIds, topicNames, "extra2", ApiKeys.FETCH.latestVersion());
    FetchResponse resp1 = FetchResponse.of(Errors.NONE, 0, INVALID_SESSION_ID, respMap(new RespEntry("foo", 0, topicIds.get("foo"), 10, 20), new RespEntry("extra2", 1, topicIds.get("extra2"), 10, 20), new RespEntry("bar", 0, topicIds.get("bar"), 10, 20)));
    String issue = handler.verifyFullFetchResponsePartitions(resp1.responseData(topicNames, ApiKeys.FETCH.latestVersion()).keySet(), resp1.topicIds(), ApiKeys.FETCH.latestVersion());
    assertTrue(issue.contains("extraPartitions="));
    assertFalse(issue.contains("omittedPartitions="));
    FetchSessionHandler.Builder builder = handler.newBuilder();
    builder.add(new TopicPartition("foo", 0), new FetchRequest.PartitionData(topicIds.get("foo"), 0, 100, 200, Optional.empty()));
    builder.add(new TopicPartition("bar", 0), new FetchRequest.PartitionData(topicIds.get("bar"), 20, 120, 220, Optional.empty()));
    builder.build();
    FetchResponse resp2 = FetchResponse.of(Errors.NONE, 0, INVALID_SESSION_ID, respMap(new RespEntry("foo", 0, topicIds.get("foo"), 10, 20), new RespEntry("extra2", 1, topicIds.get("extra2"), 10, 20), new RespEntry("bar", 0, topicIds.get("bar"), 10, 20)));
    String issue2 = handler.verifyFullFetchResponsePartitions(resp2.responseData(topicNames, ApiKeys.FETCH.latestVersion()).keySet(), resp2.topicIds(), ApiKeys.FETCH.latestVersion());
    assertTrue(issue2.contains("extraPartitions="));
    assertFalse(issue2.contains("omittedPartitions="));
    FetchResponse resp3 = FetchResponse.of(Errors.NONE, 0, INVALID_SESSION_ID, respMap(new RespEntry("foo", 0, topicIds.get("foo"), 10, 20), new RespEntry("bar", 0, topicIds.get("bar"), 10, 20)));
    String issue3 = handler.verifyFullFetchResponsePartitions(resp3.responseData(topicNames, ApiKeys.FETCH.latestVersion()).keySet(), resp3.topicIds(), ApiKeys.FETCH.latestVersion());
    assertNull(issue3);
}
Also used : Uuid(org.apache.kafka.common.Uuid) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TopicPartition(org.apache.kafka.common.TopicPartition) FetchRequest(org.apache.kafka.common.requests.FetchRequest) FetchResponse(org.apache.kafka.common.requests.FetchResponse) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 92 with Uuid

use of org.apache.kafka.common.Uuid in project kafka by apache.

the class FetchSessionHandlerTest method testVerifyFullFetchResponsePartitions.

@Test
public void testVerifyFullFetchResponsePartitions() {
    Map<String, Uuid> topicIds = new HashMap<>();
    Map<Uuid, String> topicNames = new HashMap<>();
    // We want to test both on older versions that do not use topic IDs and on newer versions that do.
    List<Short> versions = Arrays.asList((short) 12, ApiKeys.FETCH.latestVersion());
    versions.forEach(version -> {
        FetchSessionHandler handler = new FetchSessionHandler(LOG_CONTEXT, 1);
        addTopicId(topicIds, topicNames, "foo", version);
        addTopicId(topicIds, topicNames, "bar", version);
        Uuid fooId = topicIds.getOrDefault("foo", Uuid.ZERO_UUID);
        Uuid barId = topicIds.getOrDefault("bar", Uuid.ZERO_UUID);
        TopicPartition foo0 = new TopicPartition("foo", 0);
        TopicPartition foo1 = new TopicPartition("foo", 1);
        TopicPartition bar0 = new TopicPartition("bar", 0);
        FetchResponse resp1 = FetchResponse.of(Errors.NONE, 0, INVALID_SESSION_ID, respMap(new RespEntry("foo", 0, fooId, 10, 20), new RespEntry("foo", 1, fooId, 10, 20), new RespEntry("bar", 0, barId, 10, 20)));
        String issue = handler.verifyFullFetchResponsePartitions(resp1.responseData(topicNames, version).keySet(), resp1.topicIds(), version);
        assertTrue(issue.contains("extraPartitions="));
        assertFalse(issue.contains("omittedPartitions="));
        FetchSessionHandler.Builder builder = handler.newBuilder();
        builder.add(foo0, new FetchRequest.PartitionData(fooId, 0, 100, 200, Optional.empty()));
        builder.add(foo1, new FetchRequest.PartitionData(fooId, 10, 110, 210, Optional.empty()));
        builder.add(bar0, new FetchRequest.PartitionData(barId, 20, 120, 220, Optional.empty()));
        builder.build();
        FetchResponse resp2 = FetchResponse.of(Errors.NONE, 0, INVALID_SESSION_ID, respMap(new RespEntry("foo", 0, fooId, 10, 20), new RespEntry("foo", 1, fooId, 10, 20), new RespEntry("bar", 0, barId, 10, 20)));
        String issue2 = handler.verifyFullFetchResponsePartitions(resp2.responseData(topicNames, version).keySet(), resp2.topicIds(), version);
        assertNull(issue2);
        FetchResponse resp3 = FetchResponse.of(Errors.NONE, 0, INVALID_SESSION_ID, respMap(new RespEntry("foo", 0, fooId, 10, 20), new RespEntry("foo", 1, fooId, 10, 20)));
        String issue3 = handler.verifyFullFetchResponsePartitions(resp3.responseData(topicNames, version).keySet(), resp3.topicIds(), version);
        assertFalse(issue3.contains("extraPartitions="));
        assertTrue(issue3.contains("omittedPartitions="));
    });
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) FetchResponse(org.apache.kafka.common.requests.FetchResponse) Uuid(org.apache.kafka.common.Uuid) TopicPartition(org.apache.kafka.common.TopicPartition) FetchRequest(org.apache.kafka.common.requests.FetchRequest) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 93 with Uuid

use of org.apache.kafka.common.Uuid in project kafka by apache.

the class FetchSessionHandlerTest method testOkToAddNewIdAfterTopicRemovedFromSession.

@Test
public void testOkToAddNewIdAfterTopicRemovedFromSession() {
    Uuid topicId = Uuid.randomUuid();
    FetchSessionHandler handler = new FetchSessionHandler(LOG_CONTEXT, 1);
    FetchSessionHandler.Builder builder = handler.newBuilder();
    builder.add(new TopicPartition("foo", 0), new FetchRequest.PartitionData(topicId, 0, 100, 200, Optional.empty()));
    FetchSessionHandler.FetchRequestData data = builder.build();
    assertMapsEqual(reqMap(new ReqEntry("foo", topicId, 0, 0, 100, 200)), data.toSend(), data.sessionPartitions());
    assertTrue(data.metadata().isFull());
    assertTrue(data.canUseTopicIds());
    FetchResponse resp = FetchResponse.of(Errors.NONE, 0, 123, respMap(new RespEntry("foo", 0, topicId, 10, 20)));
    handler.handleResponse(resp, ApiKeys.FETCH.latestVersion());
    // Remove the partition from the session. Return a session ID as though the session is still open.
    FetchSessionHandler.Builder builder2 = handler.newBuilder();
    FetchSessionHandler.FetchRequestData data2 = builder2.build();
    assertMapsEqual(new LinkedHashMap<>(), data2.toSend(), data2.sessionPartitions());
    FetchResponse resp2 = FetchResponse.of(Errors.NONE, 0, 123, new LinkedHashMap<>());
    handler.handleResponse(resp2, ApiKeys.FETCH.latestVersion());
    // After the topic is removed, add a recreated topic with a new ID.
    FetchSessionHandler.Builder builder3 = handler.newBuilder();
    builder3.add(new TopicPartition("foo", 0), new FetchRequest.PartitionData(Uuid.randomUuid(), 0, 100, 200, Optional.empty()));
    FetchSessionHandler.FetchRequestData data3 = builder3.build();
    // Should have the same session ID and epoch 2.
    assertEquals(123, data3.metadata().sessionId(), "Did not use same session");
    assertEquals(2, data3.metadata().epoch(), "Did not have the correct session epoch");
    assertTrue(data.canUseTopicIds());
}
Also used : Uuid(org.apache.kafka.common.Uuid) TopicPartition(org.apache.kafka.common.TopicPartition) FetchRequest(org.apache.kafka.common.requests.FetchRequest) FetchResponse(org.apache.kafka.common.requests.FetchResponse) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 94 with Uuid

use of org.apache.kafka.common.Uuid in project kafka by apache.

the class KafkaAdminClient method handleDeleteTopicsUsingIds.

private Map<Uuid, KafkaFuture<Void>> handleDeleteTopicsUsingIds(final Collection<Uuid> topicIds, final DeleteTopicsOptions options) {
    final Map<Uuid, KafkaFutureImpl<Void>> topicFutures = new HashMap<>(topicIds.size());
    final List<Uuid> validTopicIds = new ArrayList<>(topicIds.size());
    for (Uuid topicId : topicIds) {
        if (topicId.equals(Uuid.ZERO_UUID)) {
            KafkaFutureImpl<Void> future = new KafkaFutureImpl<>();
            future.completeExceptionally(new InvalidTopicException("The given topic ID '" + topicId + "' cannot be represented in a request."));
            topicFutures.put(topicId, future);
        } else if (!topicFutures.containsKey(topicId)) {
            topicFutures.put(topicId, new KafkaFutureImpl<>());
            validTopicIds.add(topicId);
        }
    }
    if (!validTopicIds.isEmpty()) {
        final long now = time.milliseconds();
        final long deadline = calcDeadlineMs(now, options.timeoutMs());
        final Call call = getDeleteTopicsWithIdsCall(options, topicFutures, validTopicIds, Collections.emptyMap(), now, deadline);
        runnable.call(call, now);
    }
    return new HashMap<>(topicFutures);
}
Also used : Uuid(org.apache.kafka.common.Uuid) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) InvalidTopicException(org.apache.kafka.common.errors.InvalidTopicException) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl)

Example 95 with Uuid

use of org.apache.kafka.common.Uuid in project kafka by apache.

the class KafkaAdminClient method getDeleteTopicsWithIdsCall.

private Call getDeleteTopicsWithIdsCall(final DeleteTopicsOptions options, final Map<Uuid, KafkaFutureImpl<Void>> futures, final List<Uuid> topicIds, final Map<Uuid, ThrottlingQuotaExceededException> quotaExceededExceptions, final long now, final long deadline) {
    return new Call("deleteTopics", deadline, new ControllerNodeProvider()) {

        @Override
        DeleteTopicsRequest.Builder createRequest(int timeoutMs) {
            return new DeleteTopicsRequest.Builder(new DeleteTopicsRequestData().setTopics(topicIds.stream().map(topic -> new DeleteTopicState().setTopicId(topic)).collect(Collectors.toList())).setTimeoutMs(timeoutMs));
        }

        @Override
        void handleResponse(AbstractResponse abstractResponse) {
            // Check for controller change
            handleNotControllerError(abstractResponse);
            // Handle server responses for particular topics.
            final DeleteTopicsResponse response = (DeleteTopicsResponse) abstractResponse;
            final List<Uuid> retryTopics = new ArrayList<>();
            final Map<Uuid, ThrottlingQuotaExceededException> retryTopicQuotaExceededExceptions = new HashMap<>();
            for (DeletableTopicResult result : response.data().responses()) {
                KafkaFutureImpl<Void> future = futures.get(result.topicId());
                if (future == null) {
                    log.warn("Server response mentioned unknown topic ID {}", result.topicId());
                } 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(result.topicId());
                                retryTopicQuotaExceededExceptions.put(result.topicId(), 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 = getDeleteTopicsWithIdsCall(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 : AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) HashMap(java.util.HashMap) ChannelBuilder(org.apache.kafka.common.network.ChannelBuilder) DeleteTopicsRequestData(org.apache.kafka.common.message.DeleteTopicsRequestData) ArrayList(java.util.ArrayList) DeleteTopicsRequest(org.apache.kafka.common.requests.DeleteTopicsRequest) ThrottlingQuotaExceededException(org.apache.kafka.common.errors.ThrottlingQuotaExceededException) DeleteTopicsResponse(org.apache.kafka.common.requests.DeleteTopicsResponse) Uuid(org.apache.kafka.common.Uuid) DeleteTopicState(org.apache.kafka.common.message.DeleteTopicsRequestData.DeleteTopicState) DeletableTopicResult(org.apache.kafka.common.message.DeleteTopicsResponseData.DeletableTopicResult) ApiError(org.apache.kafka.common.requests.ApiError)

Aggregations

Uuid (org.apache.kafka.common.Uuid)95 Test (org.junit.jupiter.api.Test)55 HashMap (java.util.HashMap)42 TopicPartition (org.apache.kafka.common.TopicPartition)40 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)30 ArrayList (java.util.ArrayList)29 Map (java.util.Map)21 ApiMessageAndVersion (org.apache.kafka.server.common.ApiMessageAndVersion)21 LinkedHashMap (java.util.LinkedHashMap)18 List (java.util.List)15 FetchRequest (org.apache.kafka.common.requests.FetchRequest)14 TopicIdPartition (org.apache.kafka.common.TopicIdPartition)13 Errors (org.apache.kafka.common.protocol.Errors)12 FetchResponse (org.apache.kafka.common.requests.FetchResponse)12 Collections (java.util.Collections)11 ByteBuffer (java.nio.ByteBuffer)10 Node (org.apache.kafka.common.Node)10 CreateTopicsResponseData (org.apache.kafka.common.message.CreateTopicsResponseData)10 MetadataResponse (org.apache.kafka.common.requests.MetadataResponse)10 PartitionRegistration (org.apache.kafka.metadata.PartitionRegistration)10