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

com.arextest.storage.service.config.impl.ServiceCollectConfigurableHandler Maven / Gradle / Ivy

There is a newer version: 2.0.2
Show newest version
package com.arextest.storage.service.config.impl;

import com.arextest.config.model.dto.application.InstancesConfiguration;
import com.arextest.config.model.dto.record.ServiceCollectConfiguration;
import com.arextest.config.repository.ConfigRepositoryProvider;
import com.arextest.storage.service.config.AbstractConfigurableHandler;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * @author jmo
 * @since 2022/1/22
 */
@Slf4j
@Component
public final class ServiceCollectConfigurableHandler extends
    AbstractConfigurableHandler {

  @Resource
  private ServiceCollectConfiguration globalDefaultConfiguration;

  private ServiceCollectConfigurableHandler(
      @Autowired ConfigRepositoryProvider repositoryProvider) {
    super(repositoryProvider);
  }

  @Override
  public List createFromGlobalDefault(String appId) {
    ServiceCollectConfiguration serviceCollectConfiguration = new ServiceCollectConfiguration();
    serviceCollectConfiguration.setAppId(appId);
    serviceCollectConfiguration.setSampleRate(globalDefaultConfiguration.getSampleRate());
    serviceCollectConfiguration.setAllowDayOfWeeks(globalDefaultConfiguration.getAllowDayOfWeeks());
    serviceCollectConfiguration.setTimeMock(globalDefaultConfiguration.isTimeMock());
    serviceCollectConfiguration.setAllowTimeOfDayFrom(
        globalDefaultConfiguration.getAllowTimeOfDayFrom());
    serviceCollectConfiguration.setAllowTimeOfDayTo(
        globalDefaultConfiguration.getAllowTimeOfDayTo());
    serviceCollectConfiguration.setRecordMachineCountLimit(
        globalDefaultConfiguration.getRecordMachineCountLimit() == null ? 1
            : globalDefaultConfiguration.getRecordMachineCountLimit());
    update(serviceCollectConfiguration);
    return Collections.singletonList(serviceCollectConfiguration);
  }

  @Override
  public boolean update(ServiceCollectConfiguration configuration) {
    return super.update(configuration) || super.insert(configuration);
  }

  @Override
  protected void mergeGlobalDefaultSettings(ServiceCollectConfiguration source) {
  }

  @Override
  protected boolean shouldMergeGlobalDefault() {
    return true;
  }

  /**
   * Allocate service collect config for instances.
   * @param appId appid
   * @param instances all instances of the app
   * @param requestInstance the instance that is requesting service collect config
   * @return pair of service collect config and instances that will use this config
   */
  public Pair> allocateServiceCollectConfig(
      String appId, List instances, InstancesConfiguration requestInstance) {

    ServiceCollectConfiguration rootConfig = super.useResult(appId);

    List multiEnvConfigs = Optional.ofNullable(
        rootConfig.getMultiEnvConfigs()).orElse(Collections.emptyList());
    // no multi env config, all instance use root config
    if (CollectionUtils.isEmpty(multiEnvConfigs)) {
      return Pair.of(rootConfig, instances);
    }

    // index of config -> instances that will use the config
    Map> configAllocation = instances.stream()
        .collect(Collectors.groupingBy(instance -> findConfigIndex(instance, multiEnvConfigs)));

    // selected config index of the incoming request instance
    Integer requestInstanceConfigIndex = findConfigIndex(requestInstance, multiEnvConfigs);
    // meaning using multi env config
    if (requestInstanceConfigIndex != -1) {
      ServiceCollectConfiguration envConfig = multiEnvConfigs.get(requestInstanceConfigIndex);
      rootConfig.setSampleRate(envConfig.getSampleRate());
      rootConfig.setAllowDayOfWeeks(envConfig.getAllowDayOfWeeks());
      rootConfig.setAllowTimeOfDayFrom(envConfig.getAllowTimeOfDayFrom());
      rootConfig.setAllowTimeOfDayTo(envConfig.getAllowTimeOfDayTo());
      rootConfig.setRecordMachineCountLimit(envConfig.getRecordMachineCountLimit());
    }

    List instancesOfEnv = configAllocation.get(requestInstanceConfigIndex);

    // clear multi env config to avoid confusion
    rootConfig.setMultiEnvConfigs(Collections.emptyList());
    return Pair.of(rootConfig, instancesOfEnv);
  }

  /**
   * Find the index of the config that matches the tags of the instance.
   * @param instance instance
   * @param multiEnvConfigs multi env configs
   * @return index of the config, -1 if not found
   */
  private Integer findConfigIndex(InstancesConfiguration instance,
      List multiEnvConfigs) {
    for (int i = 0; i < multiEnvConfigs.size(); i++) {
      ServiceCollectConfiguration envConfig = multiEnvConfigs.get(i);
      Map> configEnv = envConfig.getEnvTags();
      if (configEnv == null || configEnv.isEmpty()) {
        // this should not happen, data is validated before saving
        LOGGER.error("Invalid multi env config, appid: {}", instance.getAppId());
        continue;
      }

      Map serverTags = Optional.ofNullable(instance.getTags()).orElse(Collections.emptyMap());
      if (configEnv.keySet().stream().allMatch(tagKey -> {
        List tagVals = configEnv.get(tagKey);
        return tagVals.contains(serverTags.get(tagKey));
      })) {
        return i;
      }
    }
    return -1;
  }

  public void updateServiceCollectTime(String appId) {
    ServiceCollectConfiguration serviceCollectConfiguration = this.useResult(appId);
    this.update(serviceCollectConfiguration);
  }

  @Configuration
  @ConfigurationProperties(prefix = "arex.config.default.service.collect")
  static class GlobalServiceCollectConfiguration extends ServiceCollectConfiguration {

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy