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

io.camunda.application.commons.configuration.GatewayBasedConfiguration Maven / Gradle / Ivy

There is a newer version: 8.7.0-alpha1
Show newest version
/*
 * 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.application.commons.configuration;

import io.atomix.cluster.ClusterConfig;
import io.atomix.cluster.MemberConfig;
import io.atomix.cluster.NodeConfig;
import io.atomix.cluster.discovery.BootstrapDiscoveryConfig;
import io.atomix.cluster.messaging.MessagingConfig;
import io.atomix.cluster.protocol.SwimMembershipProtocolConfig;
import io.atomix.utils.net.Address;
import io.camunda.application.commons.actor.ActorSchedulerConfiguration.SchedulerConfiguration;
import io.camunda.application.commons.broker.client.BrokerClientConfiguration.BrokerClientTimeoutConfiguration;
import io.camunda.application.commons.configuration.GatewayBasedConfiguration.GatewayBasedProperties;
import io.camunda.application.commons.job.JobHandlerConfiguration.ActivateJobHandlerConfiguration;
import io.camunda.zeebe.gateway.RestApiCompositeFilter;
import io.camunda.zeebe.gateway.impl.configuration.ClusterCfg;
import io.camunda.zeebe.gateway.impl.configuration.FilterCfg;
import io.camunda.zeebe.gateway.impl.configuration.GatewayCfg;
import io.camunda.zeebe.gateway.impl.configuration.MembershipCfg;
import io.camunda.zeebe.gateway.impl.configuration.MultiTenancyCfg;
import io.camunda.zeebe.gateway.rest.ConditionalOnRestGatewayEnabled;
import io.camunda.zeebe.gateway.rest.impl.filters.FilterRepository;
import jakarta.servlet.Filter;
import java.time.Duration;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.LifecycleProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.filter.CompositeFilter;

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(GatewayBasedProperties.class)
@Profile("!broker")
public final class GatewayBasedConfiguration {

  private final GatewayBasedProperties properties;
  private final LifecycleProperties lifecycleProperties;

  @Autowired
  public GatewayBasedConfiguration(
      final GatewayBasedProperties properties, final LifecycleProperties lifecycleProperties) {
    this.properties = properties;
    this.lifecycleProperties = lifecycleProperties;
    properties.init();
  }

  public GatewayBasedProperties config() {
    return properties;
  }

  public Duration shutdownTimeout() {
    return lifecycleProperties.getTimeoutPerShutdownPhase();
  }

  @ConditionalOnRestGatewayEnabled
  @Bean
  public CompositeFilter restApiCompositeFilter() {
    final List filterCfgs = properties.getFilters();
    final List filters = new FilterRepository().load(filterCfgs).instantiate().toList();

    return new RestApiCompositeFilter(filters);
  }

  @Bean
  public ActivateJobHandlerConfiguration activateJobHandlerConfiguration() {
    return new ActivateJobHandlerConfiguration(
        "ActivateJobsHandlerRest-Gateway",
        properties.getLongPolling(),
        properties.getNetwork().getMaxMessageSize());
  }

  @Bean
  public BrokerClientTimeoutConfiguration brokerClientConfig() {
    return new BrokerClientTimeoutConfiguration(properties.getCluster().getRequestTimeout());
  }

  @Bean
  public MultiTenancyCfg multiTenancyCfg() {
    return properties.getMultiTenancy();
  }

  @Bean
  public SchedulerConfiguration schedulerConfiguration() {
    final var cpuThreads = properties.getThreads().getManagementThreads();
    // We set ioThreads to zero as the Gateway isn't using any IO threads.
    final var ioThreads = 0;
    final var metricsEnabled = false;
    final var nodeId = properties.getCluster().getMemberId();
    return new SchedulerConfiguration(cpuThreads, ioThreads, metricsEnabled, "Gateway", nodeId);
  }

  @Bean
  public ClusterConfig clusterConfig() {
    final var cluster = properties.getCluster();
    final var name = cluster.getClusterName();
    final var messaging = messagingConfig(properties);
    final var discovery = discoveryConfig(cluster.getInitialContactPoints());
    final var membership = membershipConfig(cluster.getMembership());
    final var member = memberConfig(cluster);

    return new ClusterConfig()
        .setClusterId(name)
        .setNodeConfig(member)
        .setDiscoveryConfig(discovery)
        .setMessagingConfig(messaging)
        .setProtocolConfig(membership);
  }

  private MemberConfig memberConfig(final ClusterCfg cluster) {
    final var advertisedAddress =
        Address.from(cluster.getAdvertisedHost(), cluster.getAdvertisedPort());

    return new MemberConfig().setId(cluster.getMemberId()).setAddress(advertisedAddress);
  }

  private SwimMembershipProtocolConfig membershipConfig(final MembershipCfg config) {
    return new SwimMembershipProtocolConfig()
        .setBroadcastDisputes(config.isBroadcastDisputes())
        .setBroadcastUpdates(config.isBroadcastUpdates())
        .setFailureTimeout(config.getFailureTimeout())
        .setGossipFanout(config.getGossipFanout())
        .setGossipInterval(config.getGossipInterval())
        .setNotifySuspect(config.isNotifySuspect())
        .setProbeInterval(config.getProbeInterval())
        .setProbeTimeout(config.getProbeTimeout())
        .setSuspectProbes(config.getSuspectProbes())
        .setSyncInterval(config.getSyncInterval());
  }

  private BootstrapDiscoveryConfig discoveryConfig(final Collection contactPoints) {
    final var nodes =
        contactPoints.stream()
            .map(Address::from)
            .map(address -> new NodeConfig().setAddress(address))
            .collect(Collectors.toSet());
    return new BootstrapDiscoveryConfig().setNodes(nodes);
  }

  private MessagingConfig messagingConfig(final GatewayCfg config) {
    final var cluster = config.getCluster();

    final var messaging =
        new MessagingConfig()
            .setCompressionAlgorithm(cluster.getMessageCompression())
            .setInterfaces(Collections.singletonList(cluster.getHost()))
            .setPort(cluster.getPort());

    final var security = cluster.getSecurity();
    if (security.isEnabled()) {
      messaging
          .setTlsEnabled(true)
          .configureTls(
              security.getKeyStore().getFilePath(),
              security.getKeyStore().getPassword(),
              security.getPrivateKeyPath(),
              security.getCertificateChainPath());
    }
    return messaging;
  }

  @ConfigurationProperties("zeebe.gateway")
  public static final class GatewayBasedProperties extends GatewayCfg {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy