Search in sources :

Example 1 with InvalidReplicationFactorException

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

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

the class EmbeddedKafkaCluster method createTopic.

/**
 * Create a Kafka topic with the given parameters.
 *
 * @param topic             The name of the topic.
 * @param partitions        The number of partitions for this topic.
 * @param replication       The replication factor for (partitions of) this topic.
 * @param topicConfig       Additional topic-level configuration settings.
 * @param adminClientConfig Additional admin client configuration settings.
 */
public void createTopic(String topic, int partitions, int replication, Map<String, String> topicConfig, Properties adminClientConfig) {
    if (replication > brokers.length) {
        throw new InvalidReplicationFactorException("Insufficient brokers (" + brokers.length + ") for desired replication (" + replication + ")");
    }
    log.info("Creating topic { name: {}, partitions: {}, replication: {}, config: {} }", topic, partitions, replication, topicConfig);
    final NewTopic newTopic = new NewTopic(topic, partitions, (short) replication);
    newTopic.configs(topicConfig);
    try (final Admin adminClient = createAdminClient(adminClientConfig)) {
        adminClient.createTopics(Collections.singletonList(newTopic)).all().get();
    } catch (final InterruptedException | ExecutionException e) {
        throw new RuntimeException(e);
    }
}
Also used : InvalidReplicationFactorException(org.apache.kafka.common.errors.InvalidReplicationFactorException) NewTopic(org.apache.kafka.clients.admin.NewTopic) Admin(org.apache.kafka.clients.admin.Admin) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with InvalidReplicationFactorException

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

the class ReplicationControlManager method createTopic.

private ApiError createTopic(CreatableTopic topic, List<ApiMessageAndVersion> records, Map<String, CreatableTopicResult> successes) {
    Map<Integer, PartitionRegistration> newParts = new HashMap<>();
    if (!topic.assignments().isEmpty()) {
        if (topic.replicationFactor() != -1) {
            return new ApiError(INVALID_REQUEST, "A manual partition assignment was specified, but replication " + "factor was not set to -1.");
        }
        if (topic.numPartitions() != -1) {
            return new ApiError(INVALID_REQUEST, "A manual partition assignment was specified, but numPartitions " + "was not set to -1.");
        }
        OptionalInt replicationFactor = OptionalInt.empty();
        for (CreatableReplicaAssignment assignment : topic.assignments()) {
            if (newParts.containsKey(assignment.partitionIndex())) {
                return new ApiError(Errors.INVALID_REPLICA_ASSIGNMENT, "Found multiple manual partition assignments for partition " + assignment.partitionIndex());
            }
            validateManualPartitionAssignment(assignment.brokerIds(), replicationFactor);
            replicationFactor = OptionalInt.of(assignment.brokerIds().size());
            List<Integer> isr = assignment.brokerIds().stream().filter(clusterControl::unfenced).collect(Collectors.toList());
            if (isr.isEmpty()) {
                return new ApiError(Errors.INVALID_REPLICA_ASSIGNMENT, "All brokers specified in the manual partition assignment for " + "partition " + assignment.partitionIndex() + " are fenced.");
            }
            newParts.put(assignment.partitionIndex(), new PartitionRegistration(Replicas.toArray(assignment.brokerIds()), Replicas.toArray(isr), Replicas.NONE, Replicas.NONE, isr.get(0), 0, 0));
        }
        ApiError error = maybeCheckCreateTopicPolicy(() -> {
            Map<Integer, List<Integer>> assignments = new HashMap<>();
            newParts.entrySet().forEach(e -> assignments.put(e.getKey(), Replicas.toList(e.getValue().replicas)));
            Map<String, String> configs = new HashMap<>();
            topic.configs().forEach(config -> configs.put(config.name(), config.value()));
            return new CreateTopicPolicy.RequestMetadata(topic.name(), null, null, assignments, configs);
        });
        if (error.isFailure())
            return error;
    } else if (topic.replicationFactor() < -1 || topic.replicationFactor() == 0) {
        return new ApiError(Errors.INVALID_REPLICATION_FACTOR, "Replication factor must be larger than 0, or -1 to use the default value.");
    } else if (topic.numPartitions() < -1 || topic.numPartitions() == 0) {
        return new ApiError(Errors.INVALID_PARTITIONS, "Number of partitions was set to an invalid non-positive value.");
    } else {
        int numPartitions = topic.numPartitions() == -1 ? defaultNumPartitions : topic.numPartitions();
        short replicationFactor = topic.replicationFactor() == -1 ? defaultReplicationFactor : topic.replicationFactor();
        try {
            List<List<Integer>> replicas = clusterControl.placeReplicas(0, numPartitions, replicationFactor);
            for (int partitionId = 0; partitionId < replicas.size(); partitionId++) {
                int[] r = Replicas.toArray(replicas.get(partitionId));
                newParts.put(partitionId, new PartitionRegistration(r, r, Replicas.NONE, Replicas.NONE, r[0], 0, 0));
            }
        } catch (InvalidReplicationFactorException e) {
            return new ApiError(Errors.INVALID_REPLICATION_FACTOR, "Unable to replicate the partition " + replicationFactor + " time(s): " + e.getMessage());
        }
        ApiError error = maybeCheckCreateTopicPolicy(() -> {
            Map<String, String> configs = new HashMap<>();
            topic.configs().forEach(config -> configs.put(config.name(), config.value()));
            return new CreateTopicPolicy.RequestMetadata(topic.name(), numPartitions, replicationFactor, null, configs);
        });
        if (error.isFailure())
            return error;
    }
    Uuid topicId = Uuid.randomUuid();
    successes.put(topic.name(), new CreatableTopicResult().setName(topic.name()).setTopicId(topicId).setErrorCode((short) 0).setErrorMessage(null).setNumPartitions(newParts.size()).setReplicationFactor((short) newParts.get(0).replicas.length));
    records.add(new ApiMessageAndVersion(new TopicRecord().setName(topic.name()).setTopicId(topicId), TOPIC_RECORD.highestSupportedVersion()));
    for (Entry<Integer, PartitionRegistration> partEntry : newParts.entrySet()) {
        int partitionIndex = partEntry.getKey();
        PartitionRegistration info = partEntry.getValue();
        records.add(info.toRecord(topicId, partitionIndex));
    }
    return ApiError.NONE;
}
Also used : PartitionRegistration(org.apache.kafka.metadata.PartitionRegistration) RemoveTopicRecord(org.apache.kafka.common.metadata.RemoveTopicRecord) TopicRecord(org.apache.kafka.common.metadata.TopicRecord) TimelineHashMap(org.apache.kafka.timeline.TimelineHashMap) HashMap(java.util.HashMap) OptionalInt(java.util.OptionalInt) TimelineInteger(org.apache.kafka.timeline.TimelineInteger) Uuid(org.apache.kafka.common.Uuid) CreatableReplicaAssignment(org.apache.kafka.common.message.CreateTopicsRequestData.CreatableReplicaAssignment) InvalidReplicationFactorException(org.apache.kafka.common.errors.InvalidReplicationFactorException) ApiMessageAndVersion(org.apache.kafka.server.common.ApiMessageAndVersion) CreatableTopicResult(org.apache.kafka.common.message.CreateTopicsResponseData.CreatableTopicResult) ArrayList(java.util.ArrayList) List(java.util.List) ApiError(org.apache.kafka.common.requests.ApiError)

Aggregations

InvalidReplicationFactorException (org.apache.kafka.common.errors.InvalidReplicationFactorException)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Uuid (org.apache.kafka.common.Uuid)2 List (java.util.List)1 OptionalInt (java.util.OptionalInt)1 ExecutionException (java.util.concurrent.ExecutionException)1 Admin (org.apache.kafka.clients.admin.Admin)1 NewTopic (org.apache.kafka.clients.admin.NewTopic)1 KafkaFuture (org.apache.kafka.common.KafkaFuture)1 Node (org.apache.kafka.common.Node)1 TopicPartitionInfo (org.apache.kafka.common.TopicPartitionInfo)1 TimeoutException (org.apache.kafka.common.errors.TimeoutException)1 TopicExistsException (org.apache.kafka.common.errors.TopicExistsException)1 KafkaFutureImpl (org.apache.kafka.common.internals.KafkaFutureImpl)1 CreatableReplicaAssignment (org.apache.kafka.common.message.CreateTopicsRequestData.CreatableReplicaAssignment)1 CreatableTopicResult (org.apache.kafka.common.message.CreateTopicsResponseData.CreatableTopicResult)1 RemoveTopicRecord (org.apache.kafka.common.metadata.RemoveTopicRecord)1 TopicRecord (org.apache.kafka.common.metadata.TopicRecord)1 ApiError (org.apache.kafka.common.requests.ApiError)1