Search in sources :

Example 26 with Uuid

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

the class MockAdminClient method createTopics.

@Override
public synchronized CreateTopicsResult createTopics(Collection<NewTopic> newTopics, CreateTopicsOptions options) {
    Map<String, KafkaFuture<CreateTopicsResult.TopicMetadataAndConfig>> createTopicResult = new HashMap<>();
    if (timeoutNextRequests > 0) {
        for (final NewTopic newTopic : newTopics) {
            String topicName = newTopic.name();
            KafkaFutureImpl<CreateTopicsResult.TopicMetadataAndConfig> future = new KafkaFutureImpl<>();
            future.completeExceptionally(new TimeoutException());
            createTopicResult.put(topicName, future);
        }
        --timeoutNextRequests;
        return new CreateTopicsResult(createTopicResult);
    }
    for (final NewTopic newTopic : newTopics) {
        KafkaFutureImpl<CreateTopicsResult.TopicMetadataAndConfig> future = new KafkaFutureImpl<>();
        String topicName = newTopic.name();
        if (allTopics.containsKey(topicName)) {
            future.completeExceptionally(new TopicExistsException(String.format("Topic %s exists already.", topicName)));
            createTopicResult.put(topicName, future);
            continue;
        }
        int replicationFactor = newTopic.replicationFactor();
        if (replicationFactor == -1) {
            replicationFactor = defaultReplicationFactor;
        }
        if (replicationFactor > brokers.size()) {
            future.completeExceptionally(new InvalidReplicationFactorException(String.format("Replication factor: %d is larger than brokers: %d", newTopic.replicationFactor(), brokers.size())));
            createTopicResult.put(topicName, future);
            continue;
        }
        List<Node> replicas = new ArrayList<>(replicationFactor);
        for (int i = 0; i < replicationFactor; ++i) {
            replicas.add(brokers.get(i));
        }
        int numberOfPartitions = newTopic.numPartitions();
        if (numberOfPartitions == -1) {
            numberOfPartitions = defaultPartitions;
        }
        List<TopicPartitionInfo> partitions = new ArrayList<>(numberOfPartitions);
        // Partitions start off on the first log directory of each broker, for now.
        List<String> logDirs = new ArrayList<>(numberOfPartitions);
        for (int i = 0; i < numberOfPartitions; i++) {
            partitions.add(new TopicPartitionInfo(i, brokers.get(0), replicas, Collections.emptyList()));
            logDirs.add(brokerLogDirs.get(partitions.get(i).leader().id()).get(0));
        }
        Uuid topicId = Uuid.randomUuid();
        topicIds.put(topicName, topicId);
        topicNames.put(topicId, topicName);
        allTopics.put(topicName, new TopicMetadata(topicId, false, partitions, logDirs, newTopic.configs()));
        future.complete(null);
        createTopicResult.put(topicName, future);
    }
    return new CreateTopicsResult(createTopicResult);
}
Also used : KafkaFuture(org.apache.kafka.common.KafkaFuture) HashMap(java.util.HashMap) Node(org.apache.kafka.common.Node) ArrayList(java.util.ArrayList) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) TopicExistsException(org.apache.kafka.common.errors.TopicExistsException) Uuid(org.apache.kafka.common.Uuid) TopicPartitionInfo(org.apache.kafka.common.TopicPartitionInfo) InvalidReplicationFactorException(org.apache.kafka.common.errors.InvalidReplicationFactorException) TimeoutException(org.apache.kafka.common.errors.TimeoutException)

Example 27 with Uuid

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

the class KafkaAdminClientTest method testDeleteTopics.

@Test
public void testDeleteTopics() throws Exception {
    try (AdminClientUnitTestEnv env = mockClientEnv()) {
        env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
        env.kafkaClient().prepareResponse(expectDeleteTopicsRequestWithTopics("myTopic"), prepareDeleteTopicsResponse("myTopic", Errors.NONE));
        KafkaFuture<Void> future = env.adminClient().deleteTopics(singletonList("myTopic"), new DeleteTopicsOptions()).all();
        assertNull(future.get());
        env.kafkaClient().prepareResponse(expectDeleteTopicsRequestWithTopics("myTopic"), prepareDeleteTopicsResponse("myTopic", Errors.TOPIC_DELETION_DISABLED));
        future = env.adminClient().deleteTopics(singletonList("myTopic"), new DeleteTopicsOptions()).all();
        TestUtils.assertFutureError(future, TopicDeletionDisabledException.class);
        env.kafkaClient().prepareResponse(expectDeleteTopicsRequestWithTopics("myTopic"), prepareDeleteTopicsResponse("myTopic", Errors.UNKNOWN_TOPIC_OR_PARTITION));
        future = env.adminClient().deleteTopics(singletonList("myTopic"), new DeleteTopicsOptions()).all();
        TestUtils.assertFutureError(future, UnknownTopicOrPartitionException.class);
        // With topic IDs
        Uuid topicId = Uuid.randomUuid();
        env.kafkaClient().prepareResponse(expectDeleteTopicsRequestWithTopicIds(topicId), prepareDeleteTopicsResponseWithTopicId(topicId, Errors.NONE));
        future = env.adminClient().deleteTopics(TopicCollection.ofTopicIds(singletonList(topicId)), new DeleteTopicsOptions()).all();
        assertNull(future.get());
        env.kafkaClient().prepareResponse(expectDeleteTopicsRequestWithTopicIds(topicId), prepareDeleteTopicsResponseWithTopicId(topicId, Errors.TOPIC_DELETION_DISABLED));
        future = env.adminClient().deleteTopics(TopicCollection.ofTopicIds(singletonList(topicId)), new DeleteTopicsOptions()).all();
        TestUtils.assertFutureError(future, TopicDeletionDisabledException.class);
        env.kafkaClient().prepareResponse(expectDeleteTopicsRequestWithTopicIds(topicId), prepareDeleteTopicsResponseWithTopicId(topicId, Errors.UNKNOWN_TOPIC_ID));
        future = env.adminClient().deleteTopics(TopicCollection.ofTopicIds(singletonList(topicId)), new DeleteTopicsOptions()).all();
        TestUtils.assertFutureError(future, UnknownTopicIdException.class);
    }
}
Also used : Uuid(org.apache.kafka.common.Uuid) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Example 28 with Uuid

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

the class MockAdminClient method handleDescribeTopicsUsingIds.

public synchronized Map<Uuid, KafkaFuture<TopicDescription>> handleDescribeTopicsUsingIds(Collection<Uuid> topicIds, DescribeTopicsOptions options) {
    Map<Uuid, KafkaFuture<TopicDescription>> topicDescriptions = new HashMap<>();
    if (timeoutNextRequests > 0) {
        for (Uuid requestedTopicId : topicIds) {
            KafkaFutureImpl<TopicDescription> future = new KafkaFutureImpl<>();
            future.completeExceptionally(new TimeoutException());
            topicDescriptions.put(requestedTopicId, future);
        }
        --timeoutNextRequests;
        return topicDescriptions;
    }
    for (Uuid requestedTopicId : topicIds) {
        for (Map.Entry<String, TopicMetadata> topicDescription : allTopics.entrySet()) {
            String topicName = topicDescription.getKey();
            Uuid topicId = this.topicIds.get(topicName);
            if (topicId != null && topicId.equals(requestedTopicId) && !topicDescription.getValue().markedForDeletion) {
                if (topicDescription.getValue().fetchesRemainingUntilVisible > 0) {
                    topicDescription.getValue().fetchesRemainingUntilVisible--;
                } else {
                    TopicMetadata topicMetadata = topicDescription.getValue();
                    KafkaFutureImpl<TopicDescription> future = new KafkaFutureImpl<>();
                    future.complete(new TopicDescription(topicName, topicMetadata.isInternalTopic, topicMetadata.partitions, Collections.emptySet(), topicId));
                    topicDescriptions.put(requestedTopicId, future);
                    break;
                }
            }
        }
        if (!topicDescriptions.containsKey(requestedTopicId)) {
            KafkaFutureImpl<TopicDescription> future = new KafkaFutureImpl<>();
            future.completeExceptionally(new UnknownTopicIdException("Topic id" + requestedTopicId + " not found."));
            topicDescriptions.put(requestedTopicId, future);
        }
    }
    return topicDescriptions;
}
Also used : KafkaFuture(org.apache.kafka.common.KafkaFuture) HashMap(java.util.HashMap) KafkaFutureImpl(org.apache.kafka.common.internals.KafkaFutureImpl) Uuid(org.apache.kafka.common.Uuid) UnknownTopicIdException(org.apache.kafka.common.errors.UnknownTopicIdException) HashMap(java.util.HashMap) Map(java.util.Map) TimeoutException(org.apache.kafka.common.errors.TimeoutException)

Example 29 with Uuid

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

the class ReplicationControlManager method alterPartitionReassignment.

void alterPartitionReassignment(String topicName, ReassignablePartition target, List<ApiMessageAndVersion> records) {
    Uuid topicId = topicsByName.get(topicName);
    if (topicId == null) {
        throw new UnknownTopicOrPartitionException("Unable to find a topic " + "named " + topicName + ".");
    }
    TopicControlInfo topicInfo = topics.get(topicId);
    if (topicInfo == null) {
        throw new UnknownTopicOrPartitionException("Unable to find a topic " + "with ID " + topicId + ".");
    }
    TopicIdPartition tp = new TopicIdPartition(topicId, target.partitionIndex());
    PartitionRegistration part = topicInfo.parts.get(target.partitionIndex());
    if (part == null) {
        throw new UnknownTopicOrPartitionException("Unable to find partition " + topicName + ":" + target.partitionIndex() + ".");
    }
    Optional<ApiMessageAndVersion> record;
    if (target.replicas() == null) {
        record = cancelPartitionReassignment(topicName, tp, part);
    } else {
        record = changePartitionReassignment(tp, part, target);
    }
    record.ifPresent(records::add);
}
Also used : PartitionRegistration(org.apache.kafka.metadata.PartitionRegistration) Uuid(org.apache.kafka.common.Uuid) ApiMessageAndVersion(org.apache.kafka.server.common.ApiMessageAndVersion) UnknownTopicOrPartitionException(org.apache.kafka.common.errors.UnknownTopicOrPartitionException) TopicIdPartition(org.apache.kafka.controller.BrokersToIsrs.TopicIdPartition)

Example 30 with Uuid

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

the class ReplicationControlManager method alterIsr.

ControllerResult<AlterIsrResponseData> alterIsr(AlterIsrRequestData request) {
    clusterControl.checkBrokerEpoch(request.brokerId(), request.brokerEpoch());
    AlterIsrResponseData response = new AlterIsrResponseData();
    List<ApiMessageAndVersion> records = new ArrayList<>();
    for (AlterIsrRequestData.TopicData topicData : request.topics()) {
        AlterIsrResponseData.TopicData responseTopicData = new AlterIsrResponseData.TopicData().setName(topicData.name());
        response.topics().add(responseTopicData);
        Uuid topicId = topicsByName.get(topicData.name());
        if (topicId == null || !topics.containsKey(topicId)) {
            for (AlterIsrRequestData.PartitionData partitionData : topicData.partitions()) {
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionData.partitionIndex()).setErrorCode(UNKNOWN_TOPIC_OR_PARTITION.code()));
            }
            log.info("Rejecting alterIsr request for unknown topic ID {}.", topicId);
            continue;
        }
        TopicControlInfo topic = topics.get(topicId);
        for (AlterIsrRequestData.PartitionData partitionData : topicData.partitions()) {
            int partitionId = partitionData.partitionIndex();
            PartitionRegistration partition = topic.parts.get(partitionId);
            if (partition == null) {
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(UNKNOWN_TOPIC_OR_PARTITION.code()));
                log.info("Rejecting alterIsr request for unknown partition {}-{}.", topic.name, partitionId);
                continue;
            }
            if (partitionData.leaderEpoch() != partition.leaderEpoch) {
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(FENCED_LEADER_EPOCH.code()));
                log.debug("Rejecting alterIsr request from node {} for {}-{} because " + "the current leader epoch is {}, not {}.", request.brokerId(), topic.name, partitionId, partition.leaderEpoch, partitionData.leaderEpoch());
                continue;
            }
            if (request.brokerId() != partition.leader) {
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(INVALID_REQUEST.code()));
                log.info("Rejecting alterIsr request from node {} for {}-{} because " + "the current leader is {}.", request.brokerId(), topic.name, partitionId, partition.leader);
                continue;
            }
            if (partitionData.currentIsrVersion() != partition.partitionEpoch) {
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(INVALID_UPDATE_VERSION.code()));
                log.info("Rejecting alterIsr request from node {} for {}-{} because " + "the current partition epoch is {}, not {}.", request.brokerId(), topic.name, partitionId, partition.partitionEpoch, partitionData.currentIsrVersion());
                continue;
            }
            int[] newIsr = Replicas.toArray(partitionData.newIsr());
            if (!Replicas.validateIsr(partition.replicas, newIsr)) {
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(INVALID_REQUEST.code()));
                log.error("Rejecting alterIsr request from node {} for {}-{} because " + "it specified an invalid ISR {}.", request.brokerId(), topic.name, partitionId, partitionData.newIsr());
                continue;
            }
            if (!Replicas.contains(newIsr, partition.leader)) {
                // An alterIsr request can't ask for the current leader to be removed.
                responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(INVALID_REQUEST.code()));
                log.error("Rejecting alterIsr request from node {} for {}-{} because " + "it specified an invalid ISR {} that doesn't include itself.", request.brokerId(), topic.name, partitionId, partitionData.newIsr());
                continue;
            }
            // At this point, we have decided to perform the ISR change. We use
            // PartitionChangeBuilder to find out what its effect will be.
            PartitionChangeBuilder builder = new PartitionChangeBuilder(partition, topic.id, partitionId, r -> clusterControl.unfenced(r), () -> configurationControl.uncleanLeaderElectionEnabledForTopic(topicData.name()));
            builder.setTargetIsr(partitionData.newIsr());
            Optional<ApiMessageAndVersion> record = builder.build();
            Errors result = Errors.NONE;
            if (record.isPresent()) {
                records.add(record.get());
                PartitionChangeRecord change = (PartitionChangeRecord) record.get().message();
                partition = partition.merge(change);
                if (log.isDebugEnabled()) {
                    log.debug("Node {} has altered ISR for {}-{} to {}.", request.brokerId(), topic.name, partitionId, change.isr());
                }
                if (change.leader() != request.brokerId() && change.leader() != NO_LEADER_CHANGE) {
                    // Normally, an alterIsr request, which is made by the partition
                    // leader itself, is not allowed to modify the partition leader.
                    // However, if there is an ongoing partition reassignment and the
                    // ISR change completes it, then the leader may change as part of
                    // the changes made during reassignment cleanup.
                    // 
                    // In this case, we report back FENCED_LEADER_EPOCH to the leader
                    // which made the alterIsr request. This lets it know that it must
                    // fetch new metadata before trying again. This return code is
                    // unusual because we both return an error and generate a new
                    // metadata record. We usually only do one or the other.
                    log.info("AlterIsr request from node {} for {}-{} completed " + "the ongoing partition reassignment and triggered a " + "leadership change. Reutrning FENCED_LEADER_EPOCH.", request.brokerId(), topic.name, partitionId);
                    responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(FENCED_LEADER_EPOCH.code()));
                    continue;
                } else if (change.removingReplicas() != null || change.addingReplicas() != null) {
                    log.info("AlterIsr request from node {} for {}-{} completed " + "the ongoing partition reassignment.", request.brokerId(), topic.name, partitionId);
                }
            }
            responseTopicData.partitions().add(new AlterIsrResponseData.PartitionData().setPartitionIndex(partitionId).setErrorCode(result.code()).setLeaderId(partition.leader).setLeaderEpoch(partition.leaderEpoch).setCurrentIsrVersion(partition.partitionEpoch).setIsr(Replicas.toList(partition.isr)));
        }
    }
    return ControllerResult.of(records, response);
}
Also used : PartitionRegistration(org.apache.kafka.metadata.PartitionRegistration) PartitionChangeRecord(org.apache.kafka.common.metadata.PartitionChangeRecord) ArrayList(java.util.ArrayList) AlterIsrRequestData(org.apache.kafka.common.message.AlterIsrRequestData) Errors(org.apache.kafka.common.protocol.Errors) Uuid(org.apache.kafka.common.Uuid) ApiMessageAndVersion(org.apache.kafka.server.common.ApiMessageAndVersion) AlterIsrResponseData(org.apache.kafka.common.message.AlterIsrResponseData)

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