Search in sources :

Example 11 with KafkaTopic

use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.

the class TopicOperator method update2Way.

private Future<Void> update2Way(Reconciliation reconciliation, LogContext logContext, HasMetadata involvedObject, Topic k8sTopic, Topic kafkaTopic) {
    final Future<Void> reconciliationResultHandler;
    TopicDiff diff = TopicDiff.diff(kafkaTopic, k8sTopic);
    if (diff.isEmpty()) {
        // they're the same => do nothing, but still create the private copy
        LOGGER.debugCr(logContext.toReconciliation(), "KafkaTopic created in k8s and topic created in kafka, but they're identical => just creating in topicStore");
        LOGGER.debugCr(logContext.toReconciliation(), "k8s and kafka versions of topic '{}' are the same", kafkaTopic.getTopicName());
        Topic privateTopic = new Topic.Builder(kafkaTopic).withMapName(k8sTopic.getResourceName().toString()).build();
        reconciliationResultHandler = createInTopicStore(logContext, privateTopic, involvedObject);
    } else if (!diff.changesReplicationFactor() && !diff.changesNumPartitions() && diff.changesConfig() && disjoint(kafkaTopic.getConfig().keySet(), k8sTopic.getConfig().keySet())) {
        LOGGER.debugCr(logContext.toReconciliation(), "KafkaTopic created in k8s and topic created in kafka, they differ only in topic config, and those configs are disjoint: Updating k8s and kafka, and creating in topic store");
        Map<String, String> mergedConfigs = new HashMap<>(kafkaTopic.getConfig());
        mergedConfigs.putAll(k8sTopic.getConfig());
        Topic mergedTopic = new Topic.Builder(kafkaTopic).withConfig(mergedConfigs).withMapName(k8sTopic.getResourceName().toString()).build();
        reconciliationResultHandler = updateResource(logContext, mergedTopic).compose(updatedResource -> {
            reconciliation.observedTopicFuture(updatedResource);
            Promise<Void> x = Promise.promise();
            enqueue(logContext, new UpdateKafkaConfig(logContext, mergedTopic, involvedObject, x));
            return x.future().compose(ignore -> createInTopicStore(logContext, mergedTopic, involvedObject));
        });
    } else {
        // Just use kafka version, but also create a warning event
        LOGGER.debugCr(logContext.toReconciliation(), "KafkaTopic created in k8s and topic created in kafka, and they are irreconcilably different => kafka version wins");
        Promise<Void> eventPromise = Promise.promise();
        enqueue(logContext, new Event(logContext, involvedObject, "KafkaTopic is incompatible with the topic metadata. " + "The topic metadata will be treated as canonical.", EventType.INFO, eventPromise));
        reconciliationResultHandler = eventPromise.future().compose(ignored -> updateResource(logContext, kafkaTopic)).compose(updatedResource -> {
            reconciliation.observedTopicFuture(updatedResource);
            Topic privateTopic = new Topic.Builder(kafkaTopic).withMapName(k8sTopic.getResourceName().toString()).build();
            return createInTopicStore(logContext, privateTopic, involvedObject);
        });
    }
    return reconciliationResultHandler;
}
Also used : BackOff(io.strimzi.operator.common.BackOff) ZonedDateTime(java.time.ZonedDateTime) BiFunction(java.util.function.BiFunction) Collections.disjoint(java.util.Collections.disjoint) Watcher(io.fabric8.kubernetes.client.Watcher) Annotations(io.strimzi.operator.common.Annotations) InvalidReplicationFactorException(org.apache.kafka.common.errors.InvalidReplicationFactorException) HashMap(java.util.HashMap) MaxAttemptsExceededException(io.strimzi.operator.common.MaxAttemptsExceededException) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) Collections.singletonList(java.util.Collections.singletonList) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) Timer(io.micrometer.core.instrument.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) AsyncResult(io.vertx.core.AsyncResult) Counter(io.micrometer.core.instrument.Counter) StatusUtils(io.strimzi.operator.common.operator.resource.StatusUtils) Tag(io.micrometer.core.instrument.Tag) Tags(io.micrometer.core.instrument.Tags) KafkaTopicStatus(io.strimzi.api.kafka.model.status.KafkaTopicStatus) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) Collections.emptyList(java.util.Collections.emptyList) Promise(io.vertx.core.Promise) MetricsProvider(io.strimzi.operator.common.MetricsProvider) Vertx(io.vertx.core.Vertx) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Meter(io.micrometer.core.instrument.Meter) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) EventBuilder(io.fabric8.kubernetes.api.model.EventBuilder) TopicExistsException(org.apache.kafka.common.errors.TopicExistsException) List(java.util.List) KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic) StatusDiff(io.strimzi.operator.cluster.model.StatusDiff) Util(io.strimzi.operator.common.Util) Logger(org.apache.logging.log4j.Logger) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) KafkaTopicBuilder(io.strimzi.api.kafka.model.KafkaTopicBuilder) DateTimeFormatter(java.time.format.DateTimeFormatter) Optional(java.util.Optional) Handler(io.vertx.core.Handler) LogManager(org.apache.logging.log4j.LogManager) Promise(io.vertx.core.Promise) EventBuilder(io.fabric8.kubernetes.api.model.EventBuilder) KafkaTopicBuilder(io.strimzi.api.kafka.model.KafkaTopicBuilder) KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 12 with KafkaTopic

use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.

the class TopicOperatorBaseIT method teardown.

public void teardown(boolean deletionEnabled) throws InterruptedException, TimeoutException, ExecutionException {
    CountDownLatch latch = new CountDownLatch(1);
    try {
        LOGGER.info("Tearing down test");
        try {
            clearKafkaTopics(deletionEnabled);
        } finally {
            stopTopicOperator();
        }
        if (!deletionEnabled && kubeClient != null && operation().inNamespace(NAMESPACE).list().getItems() != null) {
            List<KafkaTopic> items = operation().inNamespace(NAMESPACE).list().getItems();
            // Wait for the operator to delete all the existing topics in Kafka
            for (KafkaTopic item : items) {
                operation().inNamespace(NAMESPACE).withName(item.getMetadata().getName()).withPropagationPolicy(DeletionPropagation.FOREGROUND).delete();
                waitForTopicInKube(item.getMetadata().getName(), false);
            }
        }
    } finally {
        LOGGER.info("Finished tearing down test");
        latch.countDown();
    }
    latch.await(30, TimeUnit.SECONDS);
}
Also used : KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 13 with KafkaTopic

use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.

the class TopicOperatorBaseIT method alterTopicConfigInKube.

protected String alterTopicConfigInKube(String resourceName, String key, Function<String, String> mutator) {
    // now change the topic resource
    Object retention = operation().inNamespace(NAMESPACE).withName(resourceName).get().getSpec().getConfig().getOrDefault(key, "12341233");
    String currentValue = retention instanceof Integer ? retention.toString() : (String) retention;
    String newValue = mutator.apply(currentValue);
    KafkaTopic changedTopic = new KafkaTopicBuilder(operation().inNamespace(NAMESPACE).withName(resourceName).get()).editOrNewSpec().addToConfig(key, newValue).endSpec().build();
    operation().inNamespace(NAMESPACE).withName(resourceName).replace(changedTopic);
    return newValue;
}
Also used : KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic) KafkaTopicBuilder(io.strimzi.api.kafka.model.KafkaTopicBuilder)

Example 14 with KafkaTopic

use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.

the class TopicOperatorBaseIT method clearKafkaTopics.

protected final void clearKafkaTopics(final boolean deletionEnabled) throws TimeoutException, InterruptedException {
    if (deletionEnabled && kubeClient != null && operation().inNamespace(NAMESPACE).list().getItems() != null) {
        List<KafkaTopic> items = operation().inNamespace(NAMESPACE).list().getItems();
        // Wait for the operator to delete all the existing topics in Kafka
        for (KafkaTopic item : items) {
            String mdName = item.getMetadata().getName();
            String topicName = new TopicName(item).toString();
            // TODO FIXME !!
            if (topicName.startsWith("__"))
                continue;
            LOGGER.info("Deleting {} from Kube", mdName);
            operation().inNamespace(NAMESPACE).withName(mdName).withPropagationPolicy(DeletionPropagation.FOREGROUND).delete();
            LOGGER.info("Awaiting deletion of {} in Kafka", mdName);
            waitForTopicInKafka(topicName, false);
            waitForTopicInKube(mdName, false);
        }
    }
}
Also used : KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic)

Example 15 with KafkaTopic

use of io.strimzi.api.kafka.model.KafkaTopic in project strimzi by strimzi.

the class TopicOperatorIT method testKafkaTopicAddedWithBadData.

@Test
public void testKafkaTopicAddedWithBadData() {
    String topicName = "test-resource-created-with-bad-data";
    Topic topic = new Topic.Builder(topicName, 1, (short) 1, emptyMap()).build();
    KafkaTopic kafkaTopic = TopicSerialization.toTopicResource(topic, labels);
    kafkaTopic.getSpec().setPartitions(-1);
    // Create a Topic Resource
    try {
        operation().inNamespace(NAMESPACE).create(kafkaTopic);
        fail();
    } catch (KubernetesClientException e) {
        assertThat(e.getMessage().contains("spec.partitions in body should be greater than or equal to 1"), is(true));
    }
}
Also used : KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic) NewTopic(org.apache.kafka.clients.admin.NewTopic) KafkaTopic(io.strimzi.api.kafka.model.KafkaTopic) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) Test(org.junit.jupiter.api.Test)

Aggregations

KafkaTopic (io.strimzi.api.kafka.model.KafkaTopic)187 Test (org.junit.jupiter.api.Test)92 KafkaTopicBuilder (io.strimzi.api.kafka.model.KafkaTopicBuilder)80 Checkpoint (io.vertx.junit5.Checkpoint)46 ObjectMetaBuilder (io.fabric8.kubernetes.api.model.ObjectMetaBuilder)38 HashMap (java.util.HashMap)32 ObjectMeta (io.fabric8.kubernetes.api.model.ObjectMeta)30 CountDownLatch (java.util.concurrent.CountDownLatch)28 NewTopic (org.apache.kafka.clients.admin.NewTopic)28 List (java.util.List)26 Map (java.util.Map)26 MeterRegistry (io.micrometer.core.instrument.MeterRegistry)22 KafkaTopicStatus (io.strimzi.api.kafka.model.status.KafkaTopicStatus)22 AsyncResult (io.vertx.core.AsyncResult)22 MaxAttemptsExceededException (io.strimzi.operator.common.MaxAttemptsExceededException)20 Vertx (io.vertx.core.Vertx)20 Matchers.containsString (org.hamcrest.Matchers.containsString)20 Watcher (io.fabric8.kubernetes.client.Watcher)18 KafkaClients (io.strimzi.systemtest.kafkaclients.internalClients.KafkaClients)18 KafkaClientsBuilder (io.strimzi.systemtest.kafkaclients.internalClients.KafkaClientsBuilder)18