This is an automated email from the ASF dual-hosted git repository.

huijun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-heron.git


The following commit(s) were added to refs/heads/master by this push:
     new 93b2b3f  [healthmgr] Enable runtime toggle for 
AutoRestartBackpressureContainerPolicy (#2923)
93b2b3f is described below

commit 93b2b3fdc0d7dac1a9f06eb1b53f75204886e300
Author: bed debug <huiju...@users.noreply.github.com>
AuthorDate: Tue Jul 3 11:43:53 2018 -0700

    [healthmgr] Enable runtime toggle for 
AutoRestartBackpressureContainerPolicy (#2923)
    
    * enable runtime config for autobackpressure policy
    
    * update comment
    
    * clean comment
    
    * fix neng comment
    
    * fix compile
    
    * staging
    
    * toggle each policy
    
    * toggle per policy
    
    * fix neng comment
    
    * update condition check in toggle policy
    
    * update log fine
    
    * fix ning comment
---
 heron/config/src/yaml/conf/local/healthmgr.yaml    |  29 +++--
 heron/config/src/yaml/conf/sandbox/healthmgr.yaml  |  29 +++--
 heron/config/src/yaml/conf/yarn/healthmgr.yaml     |  24 +++-
 .../org/apache/heron/healthmgr/HealthManager.java  |   9 +-
 .../apache/heron/healthmgr/HealthPolicyConfig.java |  22 +++-
 .../heron/healthmgr/HealthPolicyConfigReader.java  |   3 +-
 .../healthmgr/common/PhysicalPlanProvider.java     |   6 +-
 .../AutoRestartBackpressureContainerPolicy.java    |  17 +--
 .../policy/DynamicResourceAllocationPolicy.java    |   4 +-
 .../heron/healthmgr/policy/ToggleablePolicy.java   | 135 +++++++++++++++++++++
 10 files changed, 236 insertions(+), 42 deletions(-)

diff --git a/heron/config/src/yaml/conf/local/healthmgr.yaml 
b/heron/config/src/yaml/conf/local/healthmgr.yaml
index aa49572..d5d93d9 100644
--- a/heron/config/src/yaml/conf/local/healthmgr.yaml
+++ b/heron/config/src/yaml/conf/local/healthmgr.yaml
@@ -18,27 +18,36 @@
 # Topology health manager mode:
 # disabled = do not launch the health manager
 # cluster = launch the health manager on container-0
-heron.topology.healthmgr.mode: disabled
+heron.topology.healthmgr.mode: cluster
 
 # Default class and url for providing metrics
-heron.healthmgr.metricsource.type: 
org.apache.heron.healthmgr.sensors.TrackerMetricsProvider
+heron.healthmgr.metricsource.type: 
org.apache.heron.healthmgr.sensors.MetricsCacheMetricsProvider
 heron.healthmgr.metricsource.url: http://localhost:8888
 
 # Enable MetricsCache if MetricsCache is chosen as metrics provider
-#heron.topology.metricscachemgr.mode: cluster
+# disabled = do not launch the metricscache manager
+# cluster = launch the metricscache manager on container-0
+heron.topology.metricscachemgr.mode: cluster
 
 ## list of policies to be executed for self regulation
-#heron.class.health.policies:
+heron.class.health.policies:
 #  - dynamic-resource-allocation
-#  - auto-restart-backpressure-container
-#
+  - auto-restart-backpressure-container
+
 ## configuration specific to individual policies listed above
+
 #dynamic-resource-allocation:
+#  health.policy.mode: deactivated
 #  health.policy.class: 
org.apache.heron.healthmgr.policy.DynamicResourceAllocationPolicy
 #  health.policy.interval.ms: 120000
 #  BackPressureDetector.noiseFilterMillis: 20
 #  GrowingWaitQueueDetector.limit: 5
-#auto-restart-backpressure-container:
-#  health.policy.class: 
org.apache.heron.healthmgr.policy.AutoRestartBackpressureContainerPolicy
-#  health.policy.interval.ms: 120000
-#  BackPressureDetector.noiseFilterMillis: 20
+
+auto-restart-backpressure-container:
+  # policy toggle value:
+  # deactivated = freeze this policy
+  # activated = turn on this policy
+  health.policy.mode: deactivated
+  health.policy.class: 
org.apache.heron.healthmgr.policy.AutoRestartBackpressureContainerPolicy
+  health.policy.interval.ms: 20000
+  BackPressureDetector.noiseFilterMillis: 20
diff --git a/heron/config/src/yaml/conf/sandbox/healthmgr.yaml 
b/heron/config/src/yaml/conf/sandbox/healthmgr.yaml
index aa49572..d5d93d9 100644
--- a/heron/config/src/yaml/conf/sandbox/healthmgr.yaml
+++ b/heron/config/src/yaml/conf/sandbox/healthmgr.yaml
@@ -18,27 +18,36 @@
 # Topology health manager mode:
 # disabled = do not launch the health manager
 # cluster = launch the health manager on container-0
-heron.topology.healthmgr.mode: disabled
+heron.topology.healthmgr.mode: cluster
 
 # Default class and url for providing metrics
-heron.healthmgr.metricsource.type: 
org.apache.heron.healthmgr.sensors.TrackerMetricsProvider
+heron.healthmgr.metricsource.type: 
org.apache.heron.healthmgr.sensors.MetricsCacheMetricsProvider
 heron.healthmgr.metricsource.url: http://localhost:8888
 
 # Enable MetricsCache if MetricsCache is chosen as metrics provider
-#heron.topology.metricscachemgr.mode: cluster
+# disabled = do not launch the metricscache manager
+# cluster = launch the metricscache manager on container-0
+heron.topology.metricscachemgr.mode: cluster
 
 ## list of policies to be executed for self regulation
-#heron.class.health.policies:
+heron.class.health.policies:
 #  - dynamic-resource-allocation
-#  - auto-restart-backpressure-container
-#
+  - auto-restart-backpressure-container
+
 ## configuration specific to individual policies listed above
+
 #dynamic-resource-allocation:
+#  health.policy.mode: deactivated
 #  health.policy.class: 
org.apache.heron.healthmgr.policy.DynamicResourceAllocationPolicy
 #  health.policy.interval.ms: 120000
 #  BackPressureDetector.noiseFilterMillis: 20
 #  GrowingWaitQueueDetector.limit: 5
-#auto-restart-backpressure-container:
-#  health.policy.class: 
org.apache.heron.healthmgr.policy.AutoRestartBackpressureContainerPolicy
-#  health.policy.interval.ms: 120000
-#  BackPressureDetector.noiseFilterMillis: 20
+
+auto-restart-backpressure-container:
+  # policy toggle value:
+  # deactivated = freeze this policy
+  # activated = turn on this policy
+  health.policy.mode: deactivated
+  health.policy.class: 
org.apache.heron.healthmgr.policy.AutoRestartBackpressureContainerPolicy
+  health.policy.interval.ms: 20000
+  BackPressureDetector.noiseFilterMillis: 20
diff --git a/heron/config/src/yaml/conf/yarn/healthmgr.yaml 
b/heron/config/src/yaml/conf/yarn/healthmgr.yaml
index c3cf2b2..d5d93d9 100644
--- a/heron/config/src/yaml/conf/yarn/healthmgr.yaml
+++ b/heron/config/src/yaml/conf/yarn/healthmgr.yaml
@@ -18,22 +18,36 @@
 # Topology health manager mode:
 # disabled = do not launch the health manager
 # cluster = launch the health manager on container-0
-heron.topology.healthmgr.mode: disabled
+heron.topology.healthmgr.mode: cluster
 
 # Default class and url for providing metrics
-heron.healthmgr.metricsource.type: 
org.apache.heron.healthmgr.sensors.TrackerMetricsProvider
+heron.healthmgr.metricsource.type: 
org.apache.heron.healthmgr.sensors.MetricsCacheMetricsProvider
 heron.healthmgr.metricsource.url: http://localhost:8888
 
 # Enable MetricsCache if MetricsCache is chosen as metrics provider
-#heron.topology.metricscachemgr.mode: cluster
+# disabled = do not launch the metricscache manager
+# cluster = launch the metricscache manager on container-0
+heron.topology.metricscachemgr.mode: cluster
 
 ## list of policies to be executed for self regulation
-#heron.class.health.policies:
+heron.class.health.policies:
 #  - dynamic-resource-allocation
-#
+  - auto-restart-backpressure-container
+
 ## configuration specific to individual policies listed above
+
 #dynamic-resource-allocation:
+#  health.policy.mode: deactivated
 #  health.policy.class: 
org.apache.heron.healthmgr.policy.DynamicResourceAllocationPolicy
 #  health.policy.interval.ms: 120000
 #  BackPressureDetector.noiseFilterMillis: 20
 #  GrowingWaitQueueDetector.limit: 5
+
+auto-restart-backpressure-container:
+  # policy toggle value:
+  # deactivated = freeze this policy
+  # activated = turn on this policy
+  health.policy.mode: deactivated
+  health.policy.class: 
org.apache.heron.healthmgr.policy.AutoRestartBackpressureContainerPolicy
+  health.policy.interval.ms: 20000
+  BackPressureDetector.noiseFilterMillis: 20
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthManager.java 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthManager.java
index ddc519e..f41d516 100644
--- a/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthManager.java
+++ b/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthManager.java
@@ -68,6 +68,7 @@ import org.apache.heron.spi.utils.ReflectionUtils;
 
 import static 
org.apache.heron.healthmgr.HealthPolicyConfig.CONF_METRICS_SOURCE_TYPE;
 import static 
org.apache.heron.healthmgr.HealthPolicyConfig.CONF_METRICS_SOURCE_URL;
+import static org.apache.heron.healthmgr.HealthPolicyConfig.CONF_POLICY_ID;
 import static org.apache.heron.healthmgr.HealthPolicyConfig.CONF_TOPOLOGY_NAME;
 
 /**
@@ -314,7 +315,7 @@ public class HealthManager {
       Class<IHealthPolicy> policyClass
           = (Class<IHealthPolicy>) 
this.getClass().getClassLoader().loadClass(policyClassName);
 
-      AbstractModule module = constructPolicySpecificModule(policyConfig);
+      AbstractModule module = constructPolicySpecificModule(policyId, 
policyConfig);
       IHealthPolicy policy = 
injector.createChildInjector(module).getInstance(policyClass);
 
       healthPolicies.add(policy);
@@ -378,10 +379,14 @@ public class HealthManager {
     };
   }
 
-  private AbstractModule constructPolicySpecificModule(final 
HealthPolicyConfig policyConfig) {
+  private AbstractModule constructPolicySpecificModule(
+      final String policyId, final HealthPolicyConfig policyConfig) {
     return new AbstractModule() {
       @Override
       protected void configure() {
+        bind(String.class)
+            .annotatedWith(Names.named(CONF_POLICY_ID))
+            .toInstance(policyId);
         bind(HealthPolicyConfig.class).toInstance(policyConfig);
       }
     };
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfig.java 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfig.java
index 1256eb2..0cba8cb 100644
--- 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfig.java
+++ 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfig.java
@@ -24,11 +24,16 @@ import java.util.Map;
 import java.util.logging.Logger;
 
 import org.apache.heron.healthmgr.HealthPolicyConfigReader.PolicyConfigKey;
+import org.apache.heron.healthmgr.policy.ToggleablePolicy;
 
 public class HealthPolicyConfig {
   public static final String CONF_TOPOLOGY_NAME = "TOPOLOGY_NAME";
   public static final String CONF_METRICS_SOURCE_URL = "METRICS_SOURCE_URL";
   public static final String CONF_METRICS_SOURCE_TYPE = "METRICS_SOURCE_TYPE";
+  public static final String CONF_POLICY_ID = "POLICY_ID";
+
+  public static final String CONF_POLICY_MODE_DEACTIVATED = "deactivated";
+  public static final String CONF_POLICY_MODE_ACTIVATED = "activated";
 
   private static final Logger LOG = 
Logger.getLogger(HealthPolicyConfig.class.getName());
   private final Map<String, Object> configs;
@@ -42,8 +47,23 @@ public class HealthPolicyConfig {
     return (String) configs.get(PolicyConfigKey.HEALTH_POLICY_CLASS.key());
   }
 
+  public ToggleablePolicy.PolicyMode getPolicyMode() {
+    String configKey = PolicyConfigKey.HEALTH_POLICY_MODE.key();
+    if (configs.containsKey(configKey)) {
+      String val = (String) 
configs.get(PolicyConfigKey.HEALTH_POLICY_MODE.key());
+      if (CONF_POLICY_MODE_DEACTIVATED.equals(val)) {
+        return ToggleablePolicy.PolicyMode.deactivated;
+      } else if (CONF_POLICY_MODE_ACTIVATED.equals(val)) {
+        return ToggleablePolicy.PolicyMode.activated;
+      } else {
+        LOG.warning("unknown policy mode config " + val);
+      }
+    }
+    return ToggleablePolicy.PolicyMode.activated;
+  }
+
   public Duration getInterval() {
-    return Duration.ofMillis((int) 
configs.get(PolicyConfigKey.HEALTH_POLICY_INTERVAL.key()));
+    return Duration.ofMillis((int) 
configs.get(PolicyConfigKey.HEALTH_POLICY_INTERVAL_MS.key()));
   }
 
   public Object getConfig(String configName) {
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfigReader.java
 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfigReader.java
index ba45209..f421961 100644
--- 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfigReader.java
+++ 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/HealthPolicyConfigReader.java
@@ -49,8 +49,9 @@ public class HealthPolicyConfigReader {
   public enum PolicyConfigKey {
     CONF_FILE_NAME("healthmgr.yaml"),
     HEALTH_POLICIES("heron.class.health.policies"),
+    HEALTH_POLICY_MODE("health.policy.mode"),
     HEALTH_POLICY_CLASS("health.policy.class"),
-    HEALTH_POLICY_INTERVAL("health.policy.interval.ms"),
+    HEALTH_POLICY_INTERVAL_MS("health.policy.interval.ms"),
     CONF_SENSOR_DURATION_SUFFIX(".duration"),
     METRIC_SOURCE_TYPE("heron.healthmgr.metricsource.type"),
     METRIC_SOURCE_URL("heron.healthmgr.metricsource.url");
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/common/PhysicalPlanProvider.java
 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/common/PhysicalPlanProvider.java
index 79990e8..eca7dfb 100644
--- 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/common/PhysicalPlanProvider.java
+++ 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/common/PhysicalPlanProvider.java
@@ -78,11 +78,9 @@ public class PhysicalPlanProvider implements 
Provider<PhysicalPlan> {
 
   @Override
   public synchronized PhysicalPlan get() {
+    physicalPlan = stateManagerAdaptor.getPhysicalPlan(topologyName);
     if (physicalPlan == null) {
-      physicalPlan = stateManagerAdaptor.getPhysicalPlan(topologyName);
-      if (physicalPlan == null) {
-        throw new InvalidStateException(topologyName, "Failed to fetch the 
physical plan");
-      }
+      throw new InvalidStateException(topologyName, "Failed to fetch the 
physical plan");
     }
     return physicalPlan;
   }
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/AutoRestartBackpressureContainerPolicy.java
 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/AutoRestartBackpressureContainerPolicy.java
index f143246..82b7e69 100644
--- 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/AutoRestartBackpressureContainerPolicy.java
+++ 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/AutoRestartBackpressureContainerPolicy.java
@@ -23,18 +23,20 @@ import java.time.Duration;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import com.microsoft.dhalion.events.EventHandler;
 import com.microsoft.dhalion.events.EventManager;
-import com.microsoft.dhalion.policy.HealthPolicyImpl;
 
 import org.apache.heron.healthmgr.HealthPolicyConfig;
 import org.apache.heron.healthmgr.common.HealthManagerEvents.ContainerRestart;
+import org.apache.heron.healthmgr.common.PhysicalPlanProvider;
 import org.apache.heron.healthmgr.detectors.BackPressureDetector;
 import org.apache.heron.healthmgr.resolvers.RestartContainerResolver;
 import org.apache.heron.healthmgr.sensors.BackPressureSensor;
 
-import static 
org.apache.heron.healthmgr.HealthPolicyConfigReader.PolicyConfigKey.HEALTH_POLICY_INTERVAL;
+import static org.apache.heron.healthmgr.HealthPolicyConfig.CONF_POLICY_ID;
+import static 
org.apache.heron.healthmgr.HealthPolicyConfigReader.PolicyConfigKey.HEALTH_POLICY_INTERVAL_MS;
 
 /**
  * This Policy class
@@ -42,7 +44,7 @@ import static 
org.apache.heron.healthmgr.HealthPolicyConfigReader.PolicyConfigKe
  * state for long time, which we believe the container cannot recover.
  * 2. resolver: try to restart the backpressure container so as to be 
rescheduled.
  */
-public class AutoRestartBackpressureContainerPolicy extends HealthPolicyImpl
+public class AutoRestartBackpressureContainerPolicy extends ToggleablePolicy
     implements EventHandler<ContainerRestart> {
 
   private static final String CONF_WAIT_INTERVAL_MILLIS =
@@ -50,22 +52,23 @@ public class AutoRestartBackpressureContainerPolicy extends 
HealthPolicyImpl
   private static final Logger LOG =
       Logger.getLogger(AutoRestartBackpressureContainerPolicy.class.getName());
 
-  private final HealthPolicyConfig policyConfig;
 
   @Inject
-  AutoRestartBackpressureContainerPolicy(HealthPolicyConfig policyConfig,
+  AutoRestartBackpressureContainerPolicy(@Named(CONF_POLICY_ID) String 
policyId,
+                                         HealthPolicyConfig policyConfig,
+                                         PhysicalPlanProvider 
physicalPlanProvider,
                                          EventManager eventManager,
                                          BackPressureSensor backPressureSensor,
                                          BackPressureDetector 
backPressureDetector,
                                          RestartContainerResolver 
restartContainerResolver) {
-    this.policyConfig = policyConfig;
+    super(policyId, policyConfig, physicalPlanProvider);
 
     registerSensors(backPressureSensor);
     registerDetectors(backPressureDetector);
     registerResolvers(restartContainerResolver);
 
     setPolicyExecutionInterval(
-        Duration.ofMillis((int) 
policyConfig.getConfig(HEALTH_POLICY_INTERVAL.key(), 60000)));
+        Duration.ofMillis((int) 
policyConfig.getConfig(HEALTH_POLICY_INTERVAL_MS.key(), 60000)));
 
     eventManager.addEventListener(ContainerRestart.class, this);
   }
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/DynamicResourceAllocationPolicy.java
 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/DynamicResourceAllocationPolicy.java
index f314330..45293f0 100644
--- 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/DynamicResourceAllocationPolicy.java
+++ 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/DynamicResourceAllocationPolicy.java
@@ -46,7 +46,7 @@ import org.apache.heron.healthmgr.sensors.BackPressureSensor;
 import org.apache.heron.healthmgr.sensors.BufferSizeSensor;
 import org.apache.heron.healthmgr.sensors.ExecuteCountSensor;
 
-import static 
org.apache.heron.healthmgr.HealthPolicyConfigReader.PolicyConfigKey.HEALTH_POLICY_INTERVAL;
+import static 
org.apache.heron.healthmgr.HealthPolicyConfigReader.PolicyConfigKey.HEALTH_POLICY_INTERVAL_MS;
 import static 
org.apache.heron.healthmgr.diagnosers.BaseDiagnoser.DiagnosisType.DIAGNOSIS_DATA_SKEW;
 import static 
org.apache.heron.healthmgr.diagnosers.BaseDiagnoser.DiagnosisType.DIAGNOSIS_SLOW_INSTANCE;
 import static 
org.apache.heron.healthmgr.diagnosers.BaseDiagnoser.DiagnosisType.DIAGNOSIS_UNDER_PROVISIONING;
@@ -86,7 +86,7 @@ public class DynamicResourceAllocationPolicy extends 
HealthPolicyImpl
     registerResolvers(scaleUpResolver);
 
     setPolicyExecutionInterval(
-        Duration.ofMillis((int) 
policyConfig.getConfig(HEALTH_POLICY_INTERVAL.key(), 60000)));
+        Duration.ofMillis((int) 
policyConfig.getConfig(HEALTH_POLICY_INTERVAL_MS.key(), 60000)));
 
     eventManager.addEventListener(TopologyUpdate.class, this);
   }
diff --git 
a/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/ToggleablePolicy.java
 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/ToggleablePolicy.java
new file mode 100644
index 0000000..a55764e
--- /dev/null
+++ 
b/heron/healthmgr/src/java/org/apache/heron/healthmgr/policy/ToggleablePolicy.java
@@ -0,0 +1,135 @@
+/**
+ * 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.heron.healthmgr.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import com.microsoft.dhalion.core.Action;
+import com.microsoft.dhalion.core.Diagnosis;
+import com.microsoft.dhalion.core.Measurement;
+import com.microsoft.dhalion.core.Symptom;
+import com.microsoft.dhalion.policy.HealthPolicyImpl;
+
+import org.apache.heron.api.generated.TopologyAPI;
+import org.apache.heron.healthmgr.HealthPolicyConfig;
+import org.apache.heron.healthmgr.common.PhysicalPlanProvider;
+
+import static org.apache.heron.healthmgr.HealthPolicyConfig.CONF_POLICY_ID;
+
+/**
+ * This Policy class
+ * 1. has a toggle switch
+ * 2. works with runtime config
+ */
+public class ToggleablePolicy extends HealthPolicyImpl {
+  private static final Logger LOG =
+      Logger.getLogger(ToggleablePolicy.class.getName());
+
+  protected PhysicalPlanProvider physicalPlanProvider;
+  protected String policyId;
+  private String policyIdRuntime;
+  protected HealthPolicyConfig policyConfig;
+
+  protected PolicyMode policyMode;
+
+  public enum PolicyMode {
+    activated,
+    deactivated
+  }
+
+  @Inject
+  public ToggleablePolicy(
+      @Named(CONF_POLICY_ID) String policyId,
+      HealthPolicyConfig policyConfig,
+      PhysicalPlanProvider physicalPlanProvider) {
+    this.physicalPlanProvider = physicalPlanProvider;
+    this.policyId = policyId;
+    this.policyConfig = policyConfig;
+
+    policyMode = policyConfig.getPolicyMode();
+    policyIdRuntime = policyId + ":runtime";
+  }
+
+  @Override
+  public Collection<Measurement> executeSensors() {
+    for (TopologyAPI.Config.KeyValue kv
+        : 
physicalPlanProvider.get().getTopology().getTopologyConfig().getKvsList()) {
+      LOG.fine("kv " + kv.getKey() + ":" + kv.getValue());
+      if (kv.getKey().equals(policyIdRuntime)) {
+        try {
+          PolicyMode val = PolicyMode.valueOf(kv.getValue());
+          if (!policyMode.equals(val)) {
+            policyMode = val;
+            LOG.info("policy " + policyId + " status changed to " + 
policyMode);
+          } else {
+            LOG.fine("policy " + policyId + " status remains same " + 
policyMode);
+          }
+          break;
+        } catch (IllegalArgumentException e) {
+          LOG.warning("policy " + policyId + " status does not change " + 
policyMode
+              + "; unknown input " + kv.getValue());
+        }
+      }
+    }
+
+    if (policyMode.equals(PolicyMode.activated)) {
+      return super.executeSensors();
+    } else {
+      return new ArrayList<Measurement>();
+    }
+  }
+
+  @Override
+  public Collection<Symptom> executeDetectors(Collection<Measurement> 
measurements) {
+    if (policyMode.equals(PolicyMode.activated)) {
+      return super.executeDetectors(measurements);
+    } else {
+      return new ArrayList<Symptom>();
+    }
+  }
+
+  @Override
+  public Collection<Diagnosis> executeDiagnosers(Collection<Symptom> symptoms) 
{
+    if (policyMode.equals(PolicyMode.activated)) {
+      return super.executeDiagnosers(symptoms);
+    } else {
+      return new ArrayList<Diagnosis>();
+    }
+  }
+
+  @Override
+  public Collection<Action> executeResolvers(Collection<Diagnosis> diagnosis) {
+    if (policyMode.equals(PolicyMode.activated)) {
+      return super.executeResolvers(diagnosis);
+    } else {
+      /*
+       * TODO(dhalion):
+       * If sub-class could access the `lastExecutionTimestamp`
+       * and `oneTimeDelay`, avoid super method invocation.
+       */
+      return super.executeResolvers(new ArrayList<Diagnosis>());
+    }
+  }
+}

Reply via email to