Search in sources :

Example 1 with ConditionBuilder

use of io.strimzi.api.kafka.model.status.ConditionBuilder in project strimzi by strimzi.

the class StatusDiffTest method testStatusDiff.

@ParallelTest
public void testStatusDiff() {
    ListenerStatus ls1 = new ListenerStatusBuilder().withName("plain").withAddresses(new ListenerAddressBuilder().withHost("my-service.my-namespace.svc").withPort(9092).build()).build();
    ListenerStatus ls2 = new ListenerStatusBuilder().withName("tls").withAddresses(new ListenerAddressBuilder().withHost("my-service.my-namespace.svc").withPort(9093).build()).build();
    ListenerStatus ls3 = new ListenerStatusBuilder().withName("tls").withAddresses(new ListenerAddressBuilder().withHost("my-service.my-namespace.svc").withPort(9094).build()).build();
    Condition condition1 = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601(new Date())).withType("Ready").withStatus("True").build();
    Condition condition2 = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601(new Date())).withType("Ready2").withStatus("True").build();
    KafkaStatus status1 = new KafkaStatusBuilder().withConditions(condition1).withListeners(ls1).build();
    KafkaStatus status2 = new KafkaStatusBuilder().withConditions(condition1).withListeners(ls1).build();
    KafkaStatus status3 = new KafkaStatusBuilder().withConditions(condition1).withListeners(ls1, ls2).build();
    KafkaStatus status4 = new KafkaStatusBuilder().withConditions(condition1, condition2).withListeners(ls1).build();
    KafkaStatus status5 = new KafkaStatusBuilder().withConditions(condition1).withListeners(ls1, ls3).build();
    KafkaStatus status6 = new KafkaStatusBuilder().withConditions(condition1).withListeners(ls3, ls1).build();
    StatusDiff diff = new StatusDiff(status1, status2);
    assertThat(diff.isEmpty(), is(true));
    diff = new StatusDiff(status1, status3);
    assertThat(diff.isEmpty(), is(false));
    diff = new StatusDiff(status1, status4);
    assertThat(diff.isEmpty(), is(false));
    diff = new StatusDiff(status3, status4);
    assertThat(diff.isEmpty(), is(false));
    diff = new StatusDiff(status3, status5);
    assertThat(diff.isEmpty(), is(false));
    diff = new StatusDiff(status5, status6);
    assertThat(diff.isEmpty(), is(false));
}
Also used : ListenerAddressBuilder(io.strimzi.api.kafka.model.status.ListenerAddressBuilder) Condition(io.strimzi.api.kafka.model.status.Condition) ListenerStatus(io.strimzi.api.kafka.model.status.ListenerStatus) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) KafkaStatusBuilder(io.strimzi.api.kafka.model.status.KafkaStatusBuilder) ListenerStatusBuilder(io.strimzi.api.kafka.model.status.ListenerStatusBuilder) KafkaStatus(io.strimzi.api.kafka.model.status.KafkaStatus) Date(java.util.Date) ParallelTest(io.strimzi.test.annotations.ParallelTest)

Example 2 with ConditionBuilder

use of io.strimzi.api.kafka.model.status.ConditionBuilder in project strimzi by strimzi.

the class AbstractOperator method reconcile.

/**
 * Reconcile assembly resources in the given namespace having the given {@code name}.
 * Reconciliation works by getting the assembly resource (e.g. {@code KafkaUser})
 * in the given namespace with the given name and
 * comparing with the corresponding resource.
 * @param reconciliation The reconciliation.
 * @return A Future which is completed with the result of the reconciliation.
 */
@Override
@SuppressWarnings("unchecked")
public final Future<Void> reconcile(Reconciliation reconciliation) {
    String namespace = reconciliation.namespace();
    String name = reconciliation.name();
    reconciliationsCounter(reconciliation.namespace()).increment();
    Timer.Sample reconciliationTimerSample = Timer.start(metrics.meterRegistry());
    Future<Void> handler = withLock(reconciliation, LOCK_TIMEOUT_MS, () -> {
        T cr = resourceOperator.get(namespace, name);
        if (cr != null) {
            if (!Util.matchesSelector(selector(), cr)) {
                // When the labels matching the selector are removed from the custom resource, a DELETE event is
                // triggered by the watch even through the custom resource might not match the watch labels anymore
                // and might not be really deleted. We have to filter these situations out and ignore the
                // reconciliation because such resource might be already operated by another instance (where the
                // same change triggered ADDED event).
                LOGGER.debugCr(reconciliation, "{} {} in namespace {} does not match label selector {} and will be ignored", kind(), name, namespace, selector().get().getMatchLabels());
                return Future.succeededFuture();
            }
            Promise<Void> createOrUpdate = Promise.promise();
            if (Annotations.isReconciliationPausedWithAnnotation(cr)) {
                S status = createStatus();
                Set<Condition> conditions = validate(reconciliation, cr);
                conditions.add(StatusUtils.getPausedCondition());
                status.setConditions(new ArrayList<>(conditions));
                status.setObservedGeneration(cr.getStatus() != null ? cr.getStatus().getObservedGeneration() : 0);
                updateStatus(reconciliation, status).onComplete(statusResult -> {
                    if (statusResult.succeeded()) {
                        createOrUpdate.complete();
                    } else {
                        createOrUpdate.fail(statusResult.cause());
                    }
                });
                pausedResourceCounter(namespace).getAndIncrement();
                LOGGER.debugCr(reconciliation, "Reconciliation of {} {} is paused", kind, name);
                return createOrUpdate.future();
            } else if (cr.getSpec() == null) {
                InvalidResourceException exception = new InvalidResourceException("Spec cannot be null");
                S status = createStatus();
                Condition errorCondition = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601Now()).withType("NotReady").withStatus("True").withReason(exception.getClass().getSimpleName()).withMessage(exception.getMessage()).build();
                status.setObservedGeneration(cr.getMetadata().getGeneration());
                status.addCondition(errorCondition);
                LOGGER.errorCr(reconciliation, "{} spec cannot be null", cr.getMetadata().getName());
                updateStatus(reconciliation, status).onComplete(notUsed -> {
                    createOrUpdate.fail(exception);
                });
                return createOrUpdate.future();
            }
            Set<Condition> unknownAndDeprecatedConditions = validate(reconciliation, cr);
            LOGGER.infoCr(reconciliation, "{} {} will be checked for creation or modification", kind, name);
            createOrUpdate(reconciliation, cr).onComplete(res -> {
                if (res.succeeded()) {
                    S status = res.result();
                    addWarningsToStatus(status, unknownAndDeprecatedConditions);
                    updateStatus(reconciliation, status).onComplete(statusResult -> {
                        if (statusResult.succeeded()) {
                            createOrUpdate.complete();
                        } else {
                            createOrUpdate.fail(statusResult.cause());
                        }
                    });
                } else {
                    if (res.cause() instanceof ReconciliationException) {
                        ReconciliationException e = (ReconciliationException) res.cause();
                        Status status = e.getStatus();
                        addWarningsToStatus(status, unknownAndDeprecatedConditions);
                        LOGGER.errorCr(reconciliation, "createOrUpdate failed", e.getCause());
                        updateStatus(reconciliation, (S) status).onComplete(statusResult -> {
                            createOrUpdate.fail(e.getCause());
                        });
                    } else {
                        LOGGER.errorCr(reconciliation, "createOrUpdate failed", res.cause());
                        createOrUpdate.fail(res.cause());
                    }
                }
            });
            return createOrUpdate.future();
        } else {
            LOGGER.infoCr(reconciliation, "{} {} should be deleted", kind, name);
            return delete(reconciliation).map(deleteResult -> {
                if (deleteResult) {
                    LOGGER.infoCr(reconciliation, "{} {} deleted", kind, name);
                } else {
                    LOGGER.infoCr(reconciliation, "Assembly {} or some parts of it will be deleted by garbage collection", name);
                }
                return (Void) null;
            }).recover(deleteResult -> {
                LOGGER.errorCr(reconciliation, "Deletion of {} {} failed", kind, name, deleteResult);
                return Future.failedFuture(deleteResult);
            });
        }
    });
    Promise<Void> result = Promise.promise();
    handler.onComplete(reconcileResult -> {
        try {
            handleResult(reconciliation, reconcileResult, reconciliationTimerSample);
        } finally {
            result.handle(reconcileResult);
        }
    });
    return result.future();
}
Also used : Condition(io.strimzi.api.kafka.model.status.Condition) ClusterRoleBinding(io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding) LabelSelector(io.fabric8.kubernetes.api.model.LabelSelector) Watch(io.fabric8.kubernetes.client.Watch) Callable(java.util.concurrent.Callable) ResourceVisitor(io.strimzi.operator.common.model.ResourceVisitor) ArrayList(java.util.ArrayList) WatcherException(io.fabric8.kubernetes.client.WatcherException) Timer(io.micrometer.core.instrument.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Status(io.strimzi.api.kafka.model.status.Status) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) AsyncResult(io.vertx.core.AsyncResult) LinkedHashSet(java.util.LinkedHashSet) 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) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ValidationVisitor(io.strimzi.operator.common.model.ValidationVisitor) Set(java.util.Set) Meter(io.micrometer.core.instrument.Meter) Spec(io.strimzi.api.kafka.model.Spec) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) Util.async(io.strimzi.operator.common.Util.async) Consumer(java.util.function.Consumer) NamespaceAndName(io.strimzi.operator.common.model.NamespaceAndName) StatusDiff(io.strimzi.operator.cluster.model.StatusDiff) Labels(io.strimzi.operator.common.model.Labels) Lock(io.vertx.core.shareddata.Lock) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) AbstractWatchableStatusedResourceOperator(io.strimzi.operator.common.operator.resource.AbstractWatchableStatusedResourceOperator) Optional(java.util.Optional) Condition(io.strimzi.api.kafka.model.status.Condition) Handler(io.vertx.core.Handler) Collections(java.util.Collections) CustomResource(io.fabric8.kubernetes.client.CustomResource) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException) Status(io.strimzi.api.kafka.model.status.Status) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) Timer(io.micrometer.core.instrument.Timer)

Example 3 with ConditionBuilder

use of io.strimzi.api.kafka.model.status.ConditionBuilder in project strimzi-kafka-operator by strimzi.

the class KafkaTest method testListenerTypeAndNameInStatus.

@Test
public void testListenerTypeAndNameInStatus() throws ParseException, URISyntaxException {
    Kafka kafka = new KafkaBuilder().withNewMetadata().withName("my-cluster").withNamespace("my-namespace").withGeneration(2L).endMetadata().withNewSpec().withNewKafka().withReplicas(3).withListeners(new GenericKafkaListenerBuilder().withName("plain").withPort(9092).withType(KafkaListenerType.INTERNAL).withTls(false).build()).withNewEphemeralStorage().endEphemeralStorage().endKafka().withNewZookeeper().withReplicas(3).withNewEphemeralStorage().endEphemeralStorage().endZookeeper().endSpec().withNewStatus().withObservedGeneration(1L).withConditions(new ConditionBuilder().withType("Ready").withStatus("True").build()).withListeners(new ListenerStatusBuilder().withName("plain").withAddresses(new ListenerAddressBuilder().withHost("my-service.my-namespace.svc").withPort(9092).build()).build(), new ListenerStatusBuilder().withName("external").withAddresses(new ListenerAddressBuilder().withHost("my-route-address.domain.tld").withPort(443).build()).build()).endStatus().build();
    String path = Objects.requireNonNull(this.getClass().getResource("Kafka-listener-name-and-status.yaml")).toURI().getPath();
    assertThat(TestUtils.toYamlString(kafka), is(TestUtils.getFileAsString(path)));
}
Also used : ListenerAddressBuilder(io.strimzi.api.kafka.model.status.ListenerAddressBuilder) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) GenericKafkaListenerBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder) ListenerStatusBuilder(io.strimzi.api.kafka.model.status.ListenerStatusBuilder) Test(org.junit.jupiter.api.Test)

Example 4 with ConditionBuilder

use of io.strimzi.api.kafka.model.status.ConditionBuilder in project strimzi-kafka-operator by strimzi.

the class KafkaAssemblyOperator method createOrUpdate.

@Override
public Future<KafkaStatus> createOrUpdate(Reconciliation reconciliation, Kafka kafkaAssembly) {
    Promise<KafkaStatus> createOrUpdatePromise = Promise.promise();
    ReconciliationState reconcileState = createReconciliationState(reconciliation, kafkaAssembly);
    reconcile(reconcileState).onComplete(reconcileResult -> {
        KafkaStatus status = reconcileState.kafkaStatus;
        Condition condition;
        if (kafkaAssembly.getMetadata().getGeneration() != null) {
            status.setObservedGeneration(kafkaAssembly.getMetadata().getGeneration());
        }
        if (reconcileResult.succeeded()) {
            condition = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601(dateSupplier())).withType("Ready").withStatus("True").build();
            status.addCondition(condition);
            createOrUpdatePromise.complete(status);
        } else {
            condition = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601(dateSupplier())).withType("NotReady").withStatus("True").withReason(reconcileResult.cause().getClass().getSimpleName()).withMessage(reconcileResult.cause().getMessage()).build();
            status.addCondition(condition);
            createOrUpdatePromise.fail(new ReconciliationException(status, reconcileResult.cause()));
        }
    });
    return createOrUpdatePromise.future();
}
Also used : Condition(io.strimzi.api.kafka.model.status.Condition) ReconciliationException(io.strimzi.operator.common.ReconciliationException) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) KafkaStatus(io.strimzi.api.kafka.model.status.KafkaStatus)

Example 5 with ConditionBuilder

use of io.strimzi.api.kafka.model.status.ConditionBuilder in project cos-fleetshard by bf2fc6cc711aee1a0c2a.

the class DebeziumOperandControllerTest method computeStatus.

@ParameterizedTest
@MethodSource
void computeStatus(String connectorState, String conditionType, String conditionReason, String expectedConnectorState) {
    ConnectorStatusSpec status = new ConnectorStatusSpec();
    DebeziumOperandSupport.computeStatus(status, new KafkaConnectorBuilder().withStatus(new KafkaConnectorStatusBuilder().addToConditions(new ConditionBuilder().withType(conditionType).withReason(conditionReason).build()).addToConnectorStatus("connector", new org.bf2.cos.fleetshard.operator.debezium.model.KafkaConnectorStatusBuilder().withState(connectorState).build()).build()).build());
    assertThat(status.getPhase()).isEqualTo(expectedConnectorState);
    assertThat(status.getConditions()).anySatisfy(condition -> {
        assertThat(condition).hasFieldOrPropertyWithValue("type", conditionType).hasFieldOrPropertyWithValue("reason", conditionReason);
    });
}
Also used : ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) KafkaConnectorBuilder(io.strimzi.api.kafka.model.KafkaConnectorBuilder) ConnectorStatusSpec(org.bf2.cos.fleetshard.api.ConnectorStatusSpec) KafkaConnectorStatusBuilder(io.strimzi.api.kafka.model.status.KafkaConnectorStatusBuilder) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

ConditionBuilder (io.strimzi.api.kafka.model.status.ConditionBuilder)12 Condition (io.strimzi.api.kafka.model.status.Condition)9 KafkaStatus (io.strimzi.api.kafka.model.status.KafkaStatus)6 ListenerAddressBuilder (io.strimzi.api.kafka.model.status.ListenerAddressBuilder)6 ListenerStatusBuilder (io.strimzi.api.kafka.model.status.ListenerStatusBuilder)6 KafkaStatusBuilder (io.strimzi.api.kafka.model.status.KafkaStatusBuilder)4 ListenerStatus (io.strimzi.api.kafka.model.status.ListenerStatus)4 ParallelTest (io.strimzi.test.annotations.ParallelTest)4 Date (java.util.Date)3 LabelSelector (io.fabric8.kubernetes.api.model.LabelSelector)2 ClusterRoleBinding (io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding)2 CustomResource (io.fabric8.kubernetes.client.CustomResource)2 Watch (io.fabric8.kubernetes.client.Watch)2 WatcherException (io.fabric8.kubernetes.client.WatcherException)2 Counter (io.micrometer.core.instrument.Counter)2 Meter (io.micrometer.core.instrument.Meter)2 Tag (io.micrometer.core.instrument.Tag)2 Tags (io.micrometer.core.instrument.Tags)2 Timer (io.micrometer.core.instrument.Timer)2 Spec (io.strimzi.api.kafka.model.Spec)2