content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied.  See the License for the
   * specific language governing permissions and limitations
   * under the License.
   */
  
  package org.apache.cloudstack.cluster;
  
  import com.cloud.exception.InvalidParameterValueException;
  import com.cloud.utils.component.Manager;
  import com.cloud.utils.concurrency.Scheduler;
  import org.apache.cloudstack.api.command.admin.cluster.ExecuteClusterDrsPlanCmd;
  import org.apache.cloudstack.api.command.admin.cluster.GenerateClusterDrsPlanCmd;
  import org.apache.cloudstack.api.command.admin.cluster.ListClusterDrsPlanCmd;
  import org.apache.cloudstack.api.response.ClusterDrsPlanResponse;
  import org.apache.cloudstack.api.response.ListResponse;
  import org.apache.cloudstack.framework.config.ConfigKey;
  import org.apache.cloudstack.framework.config.Configurable;
  
  public interface ClusterDrsService extends Manager, Configurable, Scheduler {
  
      ConfigKey<Integer> ClusterDrsPlanExpireInterval = new ConfigKey<>(Integer.class, "drs.plan.expire.interval",
              ConfigKey.CATEGORY_ADVANCED, "30", "The interval in days after which the DRS events will be cleaned up.",
              false, ConfigKey.Scope.Global, null, "Expire interval for old DRS plans", null, null, null);
  
      ConfigKey<Boolean> ClusterDrsEnabled = new ConfigKey<>(Boolean.class, "drs.automatic.enable",
              ConfigKey.CATEGORY_ADVANCED, "false", "Enable/disable automatic DRS on a cluster.", true,
              ConfigKey.Scope.Cluster, null, "Enable automatic DRS", null, null, null);
  
      ConfigKey<Integer> ClusterDrsInterval = new ConfigKey<>(Integer.class, "drs.automatic.interval",
              ConfigKey.CATEGORY_ADVANCED, "60",
              "The interval in minutes after which a periodic background thread will schedule DRS for a cluster.", true,
              ConfigKey.Scope.Cluster, null, "Interval for Automatic DRS ", null, null, null);
  
      ConfigKey<Integer> ClusterDrsMaxMigrations = new ConfigKey<>(Integer.class, "drs.max.migrations",
              ConfigKey.CATEGORY_ADVANCED, "50",
              "Maximum number of live migrations in a DRS execution.",
              true, ConfigKey.Scope.Cluster, null, "Maximum number of migrations for DRS", null, null, null);
  
      ConfigKey<String> ClusterDrsAlgorithm = new ConfigKey<>(String.class, "drs.algorithm",
              ConfigKey.CATEGORY_ADVANCED, "balanced", "The DRS algorithm to be executed on the cluster. Possible values are condensed, balanced.",
              true, ConfigKey.Scope.Cluster, null, "DRS algorithm", null, null,
              null, ConfigKey.Kind.Select, "condensed,balanced");
  
      ConfigKey<Float> ClusterDrsImbalanceThreshold = new ConfigKey<>(Float.class, "drs.imbalance",
              ConfigKey.CATEGORY_ADVANCED, "0.4",
              "Value of imbalance allowed in the cluster. 1.0 means no imbalance is allowed and 0.0 means full imbalance is allowed",
              true, ConfigKey.Scope.Cluster, null, "DRS imbalance", null, null, null);
  
      ConfigKey<String> ClusterDrsMetric = new ConfigKey<>(String.class, "drs.metric", ConfigKey.CATEGORY_ADVANCED,
              "memory",
              "The allocated resource metric used to measure imbalance in a cluster. Possible values are memory, cpu.",
              true, ConfigKey.Scope.Cluster, null, "DRS metric", null, null, null, ConfigKey.Kind.Select,
              "memory,cpu");
  
      ConfigKey<String> ClusterDrsMetricType = new ConfigKey<>(String.class, "drs.metric.type", ConfigKey.CATEGORY_ADVANCED,
              "used",
              "The metric type used to measure imbalance in a cluster. This can completely change the imbalance value. Possible values are free, used.",
              true, ConfigKey.Scope.Cluster, null, "DRS metric type", null, null, null, ConfigKey.Kind.Select,
              "free,used");
  
      ConfigKey<Boolean> ClusterDrsMetricUseRatio = new ConfigKey<>(Boolean.class, "drs.metric.use.ratio", ConfigKey.CATEGORY_ADVANCED,
              "true",
              "Whether to use ratio of selected metric & total. Useful when the cluster has hosts with different capacities",
              true, ConfigKey.Scope.Cluster, null, "DRS metric use ratio", null, null, null, ConfigKey.Kind.Select,
              "true,false");
  
      ConfigKey<Float> ClusterDrsImbalanceSkipThreshold = new ConfigKey<>(Float.class,
              "drs.imbalance.condensed.skip.threshold", ConfigKey.CATEGORY_ADVANCED, "0.95",
              "Threshold to ignore the metric for a host while calculating the imbalance to decide " +
                      "whether DRS is required for a cluster.This is to avoid cases when the calculated imbalance" +
                      " gets skewed due to a single host having a very high/low metric  value resulting in imbalance" +
                      " being higher than 1. If " + ClusterDrsMetricType.key() + " is 'free', set a lower value and if it is 'used' " +
                      "set a higher value. The value should be between 0.0 and 1.0",
              true, ConfigKey.Scope.Cluster, null, "DRS imbalance skip threshold for Condensed algorithm",
              null, null, null);
  
  
      /**
       * Generate a DRS plan for a cluster and save it as per the parameters
       *
       * @param cmd
       *         the GenerateClusterDrsPlanCmd object containing the command parameters
       *
       * @return a ClusterDrsPlanResponse object containing information regarding the migrations
       */
      ClusterDrsPlanResponse generateDrsPlan(GenerateClusterDrsPlanCmd cmd);
  
      /**
       * Executes a DRS plan for a cluster.
       *
       * @param cmd
       *         the ExecuteClusterDrsPlanCmd object containing the ID of the cluster and the map of virtual
       *         machines to hosts
       *
       * @return ClusterDrsPlanResponse response object
       *
       * @throws InvalidParameterValueException
       *         if there is already a plan in READY or IN_PROGRESS state for the
       *         cluster or if the
       *         cluster cannot be found by ID
       */
      ClusterDrsPlanResponse executeDrsPlan(ExecuteClusterDrsPlanCmd cmd);
  
      /**
       * Lists DRS plans for a cluster or a specific plan.
       *
       * @param cmd
       *         the ListClusterDrsPlanCmd object containing the ID of the cluster or the ID of the plan
       *
       * @return a ListResponse object containing a list of ClusterDrsPlanResponse objects and the total number of plans
       *
       * @throws InvalidParameterValueException
       *         if both clusterId and planId are specified or if the cluster cannot be
       *         found by ID
       */
      ListResponse<ClusterDrsPlanResponse> listDrsPlan(ListClusterDrsPlanCmd cmd);
  }
  