All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.camunda.zeebe.dynamic.config.ExporterStateInitializer Maven / Gradle / Ivy

/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
package io.camunda.zeebe.dynamic.config;

import io.atomix.cluster.MemberId;
import io.camunda.zeebe.dynamic.config.state.ClusterConfiguration;
import io.camunda.zeebe.dynamic.config.state.DynamicPartitionConfig;
import io.camunda.zeebe.dynamic.config.state.MemberState;
import io.camunda.zeebe.dynamic.config.state.PartitionState;
import io.camunda.zeebe.scheduler.ConcurrencyControl;
import io.camunda.zeebe.scheduler.future.ActorFuture;
import java.util.Set;

/**
 * Updates the exporter state of the local member in the configuration. If a broker restarts with a
 * changes of exporters in the static configuration, this modifier updates the dynamic config to
 * reflect that. If new exporter are added to the static configuration, they are added to the
 * dynamic config with state ENABLED. If existing exporters are removed, they are marked as
 * disabled. Note that the exporters are not removed from the dynamic config.
 */
public class ExporterStateInitializer implements ClusterConfigurationModifier {

  private final Set configuredExporters;
  private final MemberId localMemberId;
  private final ConcurrencyControl executor;

  public ExporterStateInitializer(
      final Set configuredExporters,
      final MemberId localMemberId,
      final ConcurrencyControl executor) {
    this.configuredExporters = configuredExporters;
    this.localMemberId = localMemberId;
    this.executor = executor;
  }

  @Override
  public ActorFuture modify(final ClusterConfiguration configuration) {
    final ActorFuture result = executor.createFuture();
    if (!configuration.hasMember(localMemberId)) {
      result.complete(configuration);
    } else {
      result.complete(configuration.updateMember(localMemberId, this::updateExporterState));
    }
    return result;
  }

  private MemberState updateExporterState(final MemberState memberState) {
    MemberState updatedMemberState = memberState;
    for (final var p : memberState.partitions().keySet()) {
      final PartitionState currentPartitionState = memberState.partitions().get(p);
      final var updatedPartitionState = updateExporterStateInPartition(currentPartitionState);
      // Do not update the member state if the partition state is not changed, otherwise the
      // version will be updated during every restart and this could interfere with other
      // concurrent configuration changes.
      if (!updatedPartitionState.equals(currentPartitionState)) {
        updatedMemberState =
            updatedMemberState.updatePartition(p, partitionState -> updatedPartitionState);
      }
    }
    return updatedMemberState;
  }

  private PartitionState updateExporterStateInPartition(final PartitionState partitionState) {
    final var initializedPartitionState =
        partitionState.config().isInitialized()
            ? partitionState
            : new PartitionState(
                partitionState.state(), partitionState.priority(), DynamicPartitionConfig.init());
    final var exportersInConfig = initializedPartitionState.config().exporting().exporters();

    final var newlyAddedExporters =
        configuredExporters.stream().filter(id -> !exportersInConfig.containsKey(id)).toList();
    final var removedExporters =
        exportersInConfig.keySet().stream()
            .filter(id -> !configuredExporters.contains(id))
            .toList();

    return initializedPartitionState
        .updateConfig(c -> c.updateExporting(e -> e.disableExporters(removedExporters)))
        .updateConfig(c -> c.updateExporting(e -> e.addExporters(newlyAddedExporters)));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy