ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From smn...@apache.org
Subject ambari git commit: AMBARI-15230: Move default recovery properties from ambari.properties to cluster-env.xml
Date Tue, 15 Mar 2016 21:10:34 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk afb69f02f -> 3e75bb3a6


AMBARI-15230: Move default recovery properties from ambari.properties to cluster-env.xml


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3e75bb3a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3e75bb3a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3e75bb3a

Branch: refs/heads/trunk
Commit: 3e75bb3a645a01502af4c0b6e456a2c7d6e31a90
Parents: afb69f0
Author: Nahappan Somasundaram <nsomasundaram@hortonworks.com>
Authored: Tue Mar 15 12:49:50 2016 -0700
Committer: Nahappan Somasundaram <nsomasundaram@hortonworks.com>
Committed: Tue Mar 15 14:10:11 2016 -0700

----------------------------------------------------------------------
 ambari-server/conf/unix/ambari.properties       |   7 +-
 .../ambari/server/agent/HeartBeatHandler.java   |  43 ++--
 .../ambari/server/agent/RecoveryConfig.java     |  12 --
 .../server/agent/RecoveryConfigHelper.java      | 196 +++++++++++++++++++
 .../server/configuration/Configuration.java     |  74 -------
 .../server/state/ServiceComponentHost.java      |   7 +
 .../svccomphost/ServiceComponentHostImpl.java   |   5 +
 .../HDP/2.0.6/configuration/cluster-env.xml     |  30 +++
 .../server/agent/HeartbeatTestHelper.java       |  48 +++--
 .../server/agent/TestHeartbeatHandler.java      |  57 +++---
 .../configuration/RecoveryConfigHelperTest.java | 122 ++++++++++++
 11 files changed, 431 insertions(+), 170 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index 842a5cb..449ac2a 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -112,9 +112,4 @@ http.x-frame-options=DENY
 # HTTP Header settings for Ambari Views
 views.http.strict-transport-security=max-age=31536000
 views.http.x-xss-protection=1; mode=block
-views.http.x-frame-options=SAMEORIGIN
-
-# Enable Metrics Collector auto-restart
-recovery.type=AUTO_START
-recovery.enabled_components=METRICS_COLLECTOR
-recovery.lifetime_max_count=1024
\ No newline at end of file
+views.http.x-frame-options=SAMEORIGIN
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index a13b421..3a80803 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -143,6 +143,8 @@ public class HeartBeatHandler {
   @Inject
   private AlertDefinitionHash alertDefinitionHash;
 
+  @Inject
+  private RecoveryConfigHelper recoveryConfigHelper;
 
   /**
    * KerberosIdentityDataFileReaderFactory used to create KerberosIdentityDataFileReader
instances
@@ -462,41 +464,18 @@ public class HeartBeatHandler {
       LOG.debug("Agent configuration map set to " + response.getAgentConfig());
     }
 
-    //
-    // Filter the enabled components by maintenance mode
-    //
-
-    // Build a map of component name => Service component host
-    // for easy look up of maintenance state by component name.
-    // As of now, a host can belong to only one cluster.
-    // Clusters::getClustersForHost(hostname) returns one item.
-    Map<String, ServiceComponentHost> schFromComponentName = new HashMap<>();
-
-    for (Cluster cl : clusterFsm.getClustersForHost(hostname)) {
-      List<ServiceComponentHost> scHosts = cl.getServiceComponentHosts(hostname);
-      for (ServiceComponentHost sch : scHosts) {
-        schFromComponentName.put(sch.getServiceComponentName(), sch);
-      }
-    }
-
-    // Keep only the components that have maintenance state set to OFF
-    List<String> enabledComponents = new ArrayList<>();
-    String[] confEnabledComponents = config.getEnabledComponents().split(",");
+    /**
+     * A host can belong to only one cluster. Though getClustersForHost(hostname)
+     * returns a set of clusters, it will have only one entry.
+     */
+    String clusterName = null;
+    Set<Cluster> clusters = clusterFsm.getClustersForHost(hostname);
 
-    for (String componentName : confEnabledComponents) {
-      ServiceComponentHost sch = schFromComponentName.get(componentName);
-
-      // Append the component name only if it is
-      // in the host and  not in maintenance mode.
-      if (sch != null && sch.getMaintenanceState() == MaintenanceState.OFF) {
-        enabledComponents.add(componentName);
-      }
+    if (clusters.size() > 0) {
+      clusterName = clusters.iterator().next().getClusterName();
     }
 
-    // Overwrite the pre-constructed RecoveryConfig's list of
-    // enabled components with the filtered list
-    RecoveryConfig rc = RecoveryConfig.getRecoveryConfig(config);
-    rc.setEnabledComponents(StringUtils.join(enabledComponents, ','));
+    RecoveryConfig rc = recoveryConfigHelper.getRecoveryConfig(clusterName, hostname);
     response.setRecoveryConfig(rc);
 
     if(response.getRecoveryConfig() != null) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
b/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
index 3da8609..c2c1846 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
@@ -19,7 +19,6 @@
 package org.apache.ambari.server.agent;
 
 import com.google.gson.annotations.SerializedName;
-import org.apache.ambari.server.configuration.Configuration;
 
 
 /**
@@ -99,17 +98,6 @@ public class RecoveryConfig {
     this.maxLifetimeCount = maxLifetimeCount;
   }
 
-  public static RecoveryConfig getRecoveryConfig(Configuration conf) {
-    RecoveryConfig rc = new RecoveryConfig();
-    rc.setMaxCount(conf.getNodeRecoveryMaxCount());
-    rc.setMaxLifetimeCount(conf.getNodeRecoveryLifetimeMaxCount());
-    rc.setRetryGap(conf.getNodeRecoveryRetryGap());
-    rc.setType(conf.getNodeRecoveryType());
-    rc.setWindowInMinutes(conf.getNodeRecoveryWindowInMin());
-    rc.setEnabledComponents(conf.getEnabledComponents());
-    return rc;
-  }
-
   @Override
   public String toString() {
     StringBuilder buffer = new StringBuilder("RecoveryConfig{");

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfigHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfigHelper.java
b/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfigHelper.java
new file mode 100644
index 0000000..92a6221
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfigHelper.java
@@ -0,0 +1,196 @@
+/**
+ * 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.ambari.server.agent;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Singleton
+public class RecoveryConfigHelper {
+
+  /**
+   * Recovery related configuration
+   */
+  public static final String RECOVERY_ENABLED_KEY = "recovery_enabled";
+  public static final String RECOVERY_TYPE_KEY = "recovery_type";
+  public static final String RECOVERY_TYPE_DEFAULT = "AUTO_START";
+  public static final String RECOVERY_LIFETIME_MAX_COUNT_KEY = "recovery_lifetime_max_count";
+  public static final String RECOVERY_LIFETIME_MAX_COUNT_DEFAULT = "12";
+  public static final String RECOVERY_MAX_COUNT_KEY = "recovery_max_count";
+  public static final String RECOVERY_MAX_COUNT_DEFAULT = "6";
+  public static final String RECOVERY_WINDOW_IN_MIN_KEY = "recovery_window_in_minutes";
+  public static final String RECOVERY_WINDOW_IN_MIN_DEFAULT = "60";
+  public static final String RECOVERY_RETRY_GAP_KEY = "recovery_retry_interval";
+  public static final String RECOVERY_RETRY_GAP_DEFAULT = "5";
+
+  @Inject
+  private Clusters clusters;
+
+  private Cluster cluster;
+  private Map<String, String> configProperties;
+
+  public RecoveryConfigHelper() {
+  }
+
+  public RecoveryConfig getDefaultRecoveryConfig()
+      throws AmbariException {
+      return getRecoveryConfig(null, null);
+  }
+
+  public RecoveryConfig getRecoveryConfig(String clusterName, String hostname)
+      throws AmbariException {
+
+    if (StringUtils.isNotEmpty(clusterName)) {
+      cluster = clusters.getCluster(clusterName);
+    }
+
+    configProperties = null;
+
+    if (cluster != null) {
+      Config config = cluster.getDesiredConfigByType(getConfigType());
+      if (config != null) {
+        configProperties = config.getProperties();
+      }
+    }
+
+    if (configProperties == null) {
+      configProperties = new HashMap<>();
+    }
+
+    RecoveryConfig recoveryConfig = new RecoveryConfig();
+    recoveryConfig.setMaxCount(getNodeRecoveryMaxCount());
+    recoveryConfig.setMaxLifetimeCount(getNodeRecoveryLifetimeMaxCount());
+    recoveryConfig.setRetryGap(getNodeRecoveryRetryGap());
+    recoveryConfig.setType(getNodeRecoveryType());
+    recoveryConfig.setWindowInMinutes(getNodeRecoveryWindowInMin());
+    if (isRecoveryEnabled()) {
+      recoveryConfig.setEnabledComponents(StringUtils.join(getEnabledComponents(hostname),
','));
+    }
+
+    return recoveryConfig;
+  }
+
+  /**
+   * Get a list of enabled components for the specified host and cluster. Filter by
+   * Maintenance Mode OFF, so that agent does not auto start components that are in
+   * maintenance mode.
+   * @return
+   */
+  private List<String> getEnabledComponents(String hostname) {
+    List<String> enabledComponents = new ArrayList<>();
+    List<ServiceComponentHost> scHosts = cluster.getServiceComponentHosts(hostname);
+
+    for (ServiceComponentHost sch : scHosts) {
+      if (sch.isRecoveryEnabled()) {
+        // Keep the components that are not in maintenance mode.
+        if (sch.getMaintenanceState() == MaintenanceState.OFF) {
+          enabledComponents.add(sch.getServiceComponentName());
+        }
+      }
+    }
+
+    return enabledComponents;
+  }
+
+  /**
+   * The configuration type name.
+   * @return
+   */
+  private String getConfigType() {
+    return "cluster-env";
+  }
+
+  /**
+   * Get a value indicating whether the cluster supports recovery.
+   *
+   * @return True or false.
+   */
+  private boolean isRecoveryEnabled() {
+    return Boolean.parseBoolean(getProperty(RECOVERY_ENABLED_KEY, "false"));
+  }
+
+  /**
+   * Get the node recovery type. The only supported value is AUTO_START.
+   * @return
+   */
+  private String getNodeRecoveryType() {
+    return getProperty(RECOVERY_TYPE_KEY, RECOVERY_TYPE_DEFAULT);
+  }
+
+  /**
+   * Get configured max count of recovery attempt allowed per host component in a window
+   * This is reset when agent is restarted.
+   * @return
+   */
+  private String getNodeRecoveryMaxCount() {
+    return getProperty(RECOVERY_MAX_COUNT_KEY, RECOVERY_MAX_COUNT_DEFAULT);
+  }
+
+  /**
+   * Get configured max lifetime count of recovery attempt allowed per host component.
+   * This is reset when agent is restarted.
+   * @return
+   */
+  private String getNodeRecoveryLifetimeMaxCount() {
+    return getProperty(RECOVERY_LIFETIME_MAX_COUNT_KEY, RECOVERY_LIFETIME_MAX_COUNT_DEFAULT);
+  }
+
+  /**
+   * Get configured window size in minutes
+   * @return
+   */
+  private String getNodeRecoveryWindowInMin() {
+    return getProperty(RECOVERY_WINDOW_IN_MIN_KEY, RECOVERY_WINDOW_IN_MIN_DEFAULT);
+  }
+
+  /**
+   * Get the configured retry gap between tries per host component
+   * @return
+   */
+  private String getNodeRecoveryRetryGap() {
+    return getProperty(RECOVERY_RETRY_GAP_KEY, RECOVERY_RETRY_GAP_DEFAULT);
+  }
+
+  /**
+   * Get the property value for the specified key. If not present, return default value.
+   * @param key The key for which property value is required.
+   * @param defaultValue Default value to return if key is not found.
+   * @return
+   */
+  private String getProperty(String key, String defaultValue) {
+    if (configProperties.containsKey(key)) {
+      return configProperties.get(key);
+    }
+
+    return defaultValue;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index a4af9b9..9404506 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -339,22 +339,6 @@ public class Configuration {
   public static final String KERBEROS_CHECK_JAAS_CONFIGURATION_DEFAULT = "false";
 
   /**
-   * Recovery related configuration
-   */
-  public static final String RECOVERY_TYPE_KEY = "recovery.type";
-  public static final String RECOVERY_TYPE_DEFAULT = "DEFAULT";
-  public static final String RECOVERY_LIFETIME_MAX_COUNT_KEY = "recovery.lifetime_max_count";
-  public static final String RECOVERY_LIFETIME_MAX_COUNT_DEFAULT = "12";
-  public static final String RECOVERY_MAX_COUNT_KEY = "recovery.max_count";
-  public static final String RECOVERY_MAX_COUNT_DEFAULT = "6";
-  public static final String RECOVERY_WINDOW_IN_MIN_KEY = "recovery.window_in_minutes";
-  public static final String RECOVERY_WINDOW_IN_MIN_DEFAULT = "60";
-  public static final String RECOVERY_RETRY_GAP_KEY = "recovery.retry_interval";
-  public static final String RECOVERY_RETRY_GAP_DEFAULT = "5";
-  public static final String RECOVERY_DISABLED_COMPONENTS_KEY = "recovery.disabled_components";
-  public static final String RECOVERY_ENABLED_COMPONENTS_KEY = "recovery.enabled_components";
-
-  /**
    * Allow proxy calls to these hosts and ports only
    */
   public static final String PROXY_ALLOWED_HOST_PORTS = "proxy.allowed.hostports";
@@ -2208,64 +2192,6 @@ public class Configuration {
   }
 
   /**
-   * Get the node recovery type DEFAULT|AUTO_START|FULL
-   * @return
-   */
-  public String getNodeRecoveryType() {
-    return properties.getProperty(RECOVERY_TYPE_KEY, RECOVERY_TYPE_DEFAULT);
-  }
-
-  /**
-   * Get configured max count of recovery attempt allowed per host component in a window
-   * This is reset when agent is restarted.
-   * @return
-   */
-  public String getNodeRecoveryMaxCount() {
-    return properties.getProperty(RECOVERY_MAX_COUNT_KEY, RECOVERY_MAX_COUNT_DEFAULT);
-  }
-
-  /**
-   * Get configured max lifetime count of recovery attempt allowed per host component.
-   * This is reset when agent is restarted.
-   * @return
-   */
-  public String getNodeRecoveryLifetimeMaxCount() {
-    return properties.getProperty(RECOVERY_LIFETIME_MAX_COUNT_KEY, RECOVERY_LIFETIME_MAX_COUNT_DEFAULT);
-  }
-
-  /**
-   * Get configured window size in minutes
-   * @return
-   */
-  public String getNodeRecoveryWindowInMin() {
-    return properties.getProperty(RECOVERY_WINDOW_IN_MIN_KEY, RECOVERY_WINDOW_IN_MIN_DEFAULT);
-  }
-
-  /**
-   * Get the components for which recovery is disabled
-   * @return
-   */
-  public String getDisabledComponents() {
-    return properties.getProperty(RECOVERY_DISABLED_COMPONENTS_KEY, "");
-  }
-
-  /**
-   * Get the components for which recovery is enabled
-   * @return
-   */
-  public String getEnabledComponents() {
-    return properties.getProperty(RECOVERY_ENABLED_COMPONENTS_KEY, "");
-  }
-
-  /**
-   * Get the configured retry gap between tries per host component
-   * @return
-   */
-  public String getNodeRecoveryRetryGap() {
-    return properties.getProperty(RECOVERY_RETRY_GAP_KEY, RECOVERY_RETRY_GAP_DEFAULT);
-  }
-
-  /**
    * Gets the default KDC port to use when no port is specified in KDC hostname
    *
    * @return the default KDC port to use.

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
index 2a062a7..4866148 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
@@ -64,6 +64,13 @@ public interface ServiceComponentHost {
   Host getHost();
 
   /**
+   * Get whether recovery is enabled for
+   * this component or not.
+   * @return True or false.
+   */
+  boolean isRecoveryEnabled();
+
+  /**
    * Send a ServiceComponentHostState event to the StateMachine
    * @param event Event to handle
    * @throws InvalidStateTransitionException

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 98dc1b7..3a0075e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1683,6 +1683,11 @@ public class ServiceComponentHostImpl implements ServiceComponentHost
{
   }
 
   @Override
+  public boolean isRecoveryEnabled() {
+    return serviceComponent.isRecoveryEnabled();
+  }
+
+  @Override
   public void setMaintenanceState(MaintenanceState state) {
     writeLock.lock();
     try {

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
b/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
index 3fb82e9..6197d87 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
@@ -22,6 +22,36 @@
 
 <configuration>
     <property>
+        <name>recovery_enabled</name>
+        <value>true</value>
+        <description>Auto start enabled or not for this cluster.</description>
+    </property>
+    <property>
+        <name>recovery_type</name>
+        <value>AUTO_START</value>
+        <description>Auto start type.</description>
+    </property>
+    <property>
+        <name>recovery_lifetime_max_count</name>
+        <value>1024</value>
+        <description>Auto start lifetime maximum count of recovery attempt allowed
per host component. This is reset when agent is restarted.</description>
+    </property>
+    <property>
+        <name>recovery_max_count</name>
+        <value>6</value>
+        <description>Auto start maximum count of recovery attempt allowed per host
component in a window. This is reset when agent is restarted.</description>
+    </property>
+    <property>
+        <name>recovery_window_in_minutes</name>
+        <value>60</value>
+        <description>Auto start recovery window size in minutes.</description>
+    </property>
+    <property>
+        <name>recovery_retry_interval</name>
+        <value>5</value>
+        <description>Auto start recovery retry gap between tries per host component.</description>
+    </property>
+    <property>
         <name>security_enabled</name>
         <value>false</value>
         <description>Hadoop Security</description>

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartbeatTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartbeatTestHelper.java
b/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartbeatTestHelper.java
index a5a3cb5..697663b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartbeatTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartbeatTestHelper.java
@@ -27,6 +27,7 @@ import static org.easymock.EasyMock.createMockBuilder;
 import static org.easymock.EasyMock.createNiceMock;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -60,6 +61,8 @@ import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.security.authorization.ResourceType;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigFactory;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.StackId;
@@ -116,11 +119,6 @@ public class HeartbeatTestHelper {
 
       @Override
       protected void configure() {
-        getProperties().put("recovery.type", "FULL");
-        getProperties().put("recovery.lifetime_max_count", "10");
-        getProperties().put("recovery.max_count", "4");
-        getProperties().put("recovery.window_in_minutes", "23");
-        getProperties().put("recovery.retry_interval", "2");
         super.configure();
       }
     };
@@ -158,6 +156,25 @@ public class HeartbeatTestHelper {
 
   public Cluster getDummyCluster()
       throws AmbariException {
+    Map<String, String> configProperties = new HashMap<String, String>() {{
+      put(RecoveryConfigHelper.RECOVERY_ENABLED_KEY, "true");
+      put(RecoveryConfigHelper.RECOVERY_TYPE_KEY, "AUTO_START");
+      put(RecoveryConfigHelper.RECOVERY_MAX_COUNT_KEY, "4");
+      put(RecoveryConfigHelper.RECOVERY_LIFETIME_MAX_COUNT_KEY, "10");
+      put(RecoveryConfigHelper.RECOVERY_WINDOW_IN_MIN_KEY, "23");
+      put(RecoveryConfigHelper.RECOVERY_RETRY_GAP_KEY, "2");
+    }};
+
+    Set<String> hostNames = new HashSet<String>(){{
+      add(DummyHostname1);
+    }};
+
+    return getDummyCluster(DummyCluster, DummyStackId, configProperties, hostNames);
+  }
+
+  public Cluster getDummyCluster(String clusterName, String desiredStackId,
+                                 Map<String, String> configProperties, Set<String>
hostNames)
+      throws AmbariException {
     StackEntity stackEntity = stackDAO.find(HDP_22_STACK.getStackName(), HDP_22_STACK.getStackVersion());
     org.junit.Assert.assertNotNull(stackEntity);
 
@@ -171,27 +188,32 @@ public class HeartbeatTestHelper {
     resourceEntity.setResourceType(resourceTypeEntity);
 
     ClusterEntity clusterEntity = new ClusterEntity();
-    clusterEntity.setClusterName(DummyCluster);
+    clusterEntity.setClusterName(clusterName);
     clusterEntity.setClusterInfo("test_cluster_info1");
     clusterEntity.setResource(resourceEntity);
     clusterEntity.setDesiredStack(stackEntity);
 
     clusterDAO.create(clusterEntity);
 
-    StackId stackId = new StackId(DummyStackId);
+    StackId stackId = new StackId(desiredStackId);
 
-    Cluster cluster = clusters.getCluster(DummyCluster);
+    Cluster cluster = clusters.getCluster(clusterName);
 
     cluster.setDesiredStackVersion(stackId);
     cluster.setCurrentStackVersion(stackId);
+
+    ConfigFactory cf = injector.getInstance(ConfigFactory.class);
+    Config config = cf.createNew(cluster, "cluster-env", configProperties, new HashMap<String,
Map<String, String>>());
+    config.setTag("version1");
+    config.persist();
+
+    cluster.addConfig(config);
+    cluster.addDesiredConfig("user", Collections.singleton(config));
+
     helper.getOrCreateRepositoryVersion(stackId, stackId.getStackVersion());
     cluster.createClusterVersion(stackId, stackId.getStackVersion(), "admin",
         RepositoryVersionState.INSTALLING);
 
-    Set<String> hostNames = new HashSet<String>(){{
-      add(DummyHostname1);
-    }};
-
     Map<String, String> hostAttributes = new HashMap<String, String>();
     hostAttributes.put("os_family", "redhat");
     hostAttributes.put("os_release_version", "6.3");
@@ -208,7 +230,7 @@ public class HeartbeatTestHelper {
       hostEntities.add(hostEntity);
     }
     clusterEntity.setHostEntities(hostEntities);
-    clusters.mapHostsToCluster(hostNames, DummyCluster);
+    clusters.mapHostsToCluster(hostNames, clusterName);
 
     return cluster;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
index e29e23e..b1f94e3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
@@ -26,15 +26,11 @@ import static org.apache.ambari.server.agent.DummyHeartbeatConstants.DummyOSRele
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.DummyOs;
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.DummyOsType;
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.DummyStackId;
-import static org.apache.ambari.server.agent.DummyHeartbeatConstants.HBASE;
-import static org.apache.ambari.server.agent.DummyHeartbeatConstants.HBASE_MASTER;
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.HDFS;
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.HDFS_CLIENT;
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.NAMENODE;
 import static org.apache.ambari.server.agent.DummyHeartbeatConstants.SECONDARY_NAMENODE;
 import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMockBuilder;
-import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.reset;
@@ -383,10 +379,15 @@ public class TestHeartbeatHandler {
     Cluster cluster = heartbeatTestHelper.getDummyCluster();
     Service hdfs = cluster.addService(HDFS);
     hdfs.persist();
-    hdfs.addServiceComponent(DATANODE).persist();
+
+    hdfs.addServiceComponent(DATANODE).setRecoveryEnabled(true);
+    hdfs.getServiceComponent(DATANODE).persist();
     hdfs.getServiceComponent(DATANODE).addServiceComponentHost(DummyHostname1).persist();
-    hdfs.addServiceComponent(NAMENODE).persist();
+
+    hdfs.addServiceComponent(NAMENODE).setRecoveryEnabled(true);
+    hdfs.getServiceComponent(NAMENODE).persist();
     hdfs.getServiceComponent(NAMENODE).addServiceComponentHost(DummyHostname1).persist();
+
     hdfs.addServiceComponent(HDFS_CLIENT).persist();
     hdfs.getServiceComponent(HDFS_CLIENT).addServiceComponentHost(DummyHostname1).persist();
 
@@ -394,9 +395,6 @@ public class TestHeartbeatHandler {
     hostObject.setIPv4("ipv4");
     hostObject.setIPv6("ipv6");
 
-    // add recovery.enabled_components to ambari configuration
-    module.getProperties().put("recovery.enabled_components", "NAMENODE,DATANODE");
-
     Register reg = new Register();
     HostInfo hi = new HostInfo();
     hi.setHostName(DummyHostname1);
@@ -409,22 +407,11 @@ public class TestHeartbeatHandler {
     RegistrationResponse rr = handler.handleRegistration(reg);
     RecoveryConfig rc = rr.getRecoveryConfig();
     assertEquals(rc.getMaxCount(), "4");
-    assertEquals(rc.getType(), "FULL");
+    assertEquals(rc.getType(), "AUTO_START");
     assertEquals(rc.getMaxLifetimeCount(), "10");
     assertEquals(rc.getRetryGap(), "2");
     assertEquals(rc.getWindowInMinutes(), "23");
-    assertEquals(rc.getEnabledComponents(), "NAMENODE,DATANODE");
-
-    rc = RecoveryConfig.getRecoveryConfig(new Configuration());
-    assertEquals(rc.getMaxCount(), "6");
-    assertEquals(rc.getType(), "DEFAULT");
-    assertEquals(rc.getMaxLifetimeCount(), "12");
-    assertEquals(rc.getRetryGap(), "5");
-    assertEquals(rc.getWindowInMinutes(), "60");
-    assertEquals(rc.getEnabledComponents(), "");
-
-    // clean up
-    module.getProperties().remove("recovery.enabled_components");
+    assertEquals(rc.getEnabledComponents(), "DATANODE,NAMENODE");
   }
 
   //
@@ -442,24 +429,31 @@ public class TestHeartbeatHandler {
     Cluster cluster = heartbeatTestHelper.getDummyCluster();
     Service hdfs = cluster.addService(HDFS);
     hdfs.persist();
-    hdfs.addServiceComponent(DATANODE).persist();
+
+    /**
+     * Add three service components enabled for auto start.
+     */
+    hdfs.addServiceComponent(DATANODE).setRecoveryEnabled(true);
+    hdfs.getServiceComponent(DATANODE).persist();
     hdfs.getServiceComponent(DATANODE).addServiceComponentHost(DummyHostname1).persist();
-    hdfs.addServiceComponent(NAMENODE).persist();
+
+    hdfs.addServiceComponent(NAMENODE).setRecoveryEnabled(true);
+    hdfs.getServiceComponent(NAMENODE).persist();
     hdfs.getServiceComponent(NAMENODE).addServiceComponentHost(DummyHostname1).persist();
-    hdfs.addServiceComponent(HDFS_CLIENT).persist();
+
+    hdfs.addServiceComponent(HDFS_CLIENT).setRecoveryEnabled(true);
+    hdfs.getServiceComponent(HDFS_CLIENT).persist();
     hdfs.getServiceComponent(HDFS_CLIENT).addServiceComponentHost(DummyHostname1).persist();
 
     Host hostObject = clusters.getHost(DummyHostname1);
     hostObject.setIPv4("ipv4");
     hostObject.setIPv6("ipv6");
 
-    // add recovery.enabled_components to ambari configuration
-    module.getProperties().put("recovery.enabled_components", "NAMENODE,DATANODE,HDFS_CLIENT");
-
     // set maintenance mode on HDFS_CLIENT on host1 to true
     ServiceComponentHost schHdfsClient = hdfs.getServiceComponent(HDFS_CLIENT).getServiceComponentHost(DummyHostname1);
     schHdfsClient.setMaintenanceState(MaintenanceState.ON);
 
+
     Register reg = new Register();
     HostInfo hi = new HostInfo();
     hi.setHostName(DummyHostname1);
@@ -472,14 +466,11 @@ public class TestHeartbeatHandler {
     RegistrationResponse rr = handler.handleRegistration(reg);
     RecoveryConfig rc = rr.getRecoveryConfig();
     assertEquals(rc.getMaxCount(), "4");
-    assertEquals(rc.getType(), "FULL");
+    assertEquals(rc.getType(), "AUTO_START");
     assertEquals(rc.getMaxLifetimeCount(), "10");
     assertEquals(rc.getRetryGap(), "2");
     assertEquals(rc.getWindowInMinutes(), "23");
-    assertEquals(rc.getEnabledComponents(), "NAMENODE,DATANODE"); // HDFS_CLIENT is in maintenance
mode
-
-    // clean up
-    module.getProperties().remove("recovery.enabled_components");
+    assertEquals(rc.getEnabledComponents(), "DATANODE,NAMENODE"); // HDFS_CLIENT is in maintenance
mode
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/3e75bb3a/ambari-server/src/test/java/org/apache/ambari/server/configuration/RecoveryConfigHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/configuration/RecoveryConfigHelperTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/configuration/RecoveryConfigHelperTest.java
new file mode 100644
index 0000000..c86b95a
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/configuration/RecoveryConfigHelperTest.java
@@ -0,0 +1,122 @@
+/**
+ * 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.ambari.server.configuration;
+
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.agent.HeartbeatTestHelper;
+import org.apache.ambari.server.agent.RecoveryConfig;
+import org.apache.ambari.server.agent.RecoveryConfigHelper;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.state.Cluster;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Test RecoveryConfigHelper class
+ */
+public class RecoveryConfigHelperTest {
+  private Injector injector;
+
+  private InMemoryDefaultTestModule module;
+
+  @Inject
+  private HeartbeatTestHelper heartbeatTestHelper;
+
+  @Inject
+  private RecoveryConfigHelper recoveryConfigHelper;
+
+  @Before
+  public void setup() throws Exception {
+    module = HeartbeatTestHelper.getTestModule();
+    injector = Guice.createInjector(module);
+    injector.getInstance(GuiceJpaInitializer.class);
+    injector.injectMembers(this);
+  }
+
+  @After
+  public void teardown() throws AmbariException {
+    injector.getInstance(PersistService.class).stop();
+  }
+
+  /**
+   * Test default cluster-env properties for recovery.
+   */
+  @Test
+  public void testRecoveryConfigDefaultValues()
+      throws NoSuchFieldException, IllegalAccessException, AmbariException {
+    RecoveryConfig recoveryConfig = recoveryConfigHelper.getDefaultRecoveryConfig();
+    assertEquals(recoveryConfig.getMaxLifetimeCount(), RecoveryConfigHelper.RECOVERY_LIFETIME_MAX_COUNT_DEFAULT);
+    assertEquals(recoveryConfig.getMaxCount(), RecoveryConfigHelper.RECOVERY_MAX_COUNT_DEFAULT);
+    assertEquals(recoveryConfig.getRetryGap(), RecoveryConfigHelper.RECOVERY_RETRY_GAP_DEFAULT);
+    assertEquals(recoveryConfig.getWindowInMinutes(), RecoveryConfigHelper.RECOVERY_WINDOW_IN_MIN_DEFAULT);
+    assertEquals(recoveryConfig.getType(), RecoveryConfigHelper.RECOVERY_TYPE_DEFAULT);
+    assertNull(recoveryConfig.getEnabledComponents());
+  }
+
+  /**
+   * Test cluster-env properties from a dummy cluster
+   * @throws AmbariException
+   */
+  @Test
+  public void testRecoveryConfigValues()
+      throws NoSuchFieldException, IllegalAccessException, AmbariException {
+    String hostname = "hostname1";
+    Cluster cluster = getDummyCluster(hostname);
+    RecoveryConfig recoveryConfig = recoveryConfigHelper.getRecoveryConfig(cluster.getClusterName(),
hostname);
+    assertEquals(recoveryConfig.getMaxLifetimeCount(), "10");
+    assertEquals(recoveryConfig.getMaxCount(), "4");
+    assertEquals(recoveryConfig.getRetryGap(), "2");
+    assertEquals(recoveryConfig.getWindowInMinutes(), "23");
+    assertEquals(recoveryConfig.getType(), "AUTO_START");
+    assertNotNull(recoveryConfig.getEnabledComponents());
+  }
+
+  private Cluster getDummyCluster(final String hostname)
+          throws AmbariException {
+    Map<String, String> configProperties = new HashMap<String, String>() {{
+      put(RecoveryConfigHelper.RECOVERY_ENABLED_KEY, "true");
+      put(RecoveryConfigHelper.RECOVERY_TYPE_KEY, "AUTO_START");
+      put(RecoveryConfigHelper.RECOVERY_MAX_COUNT_KEY, "4");
+      put(RecoveryConfigHelper.RECOVERY_LIFETIME_MAX_COUNT_KEY, "10");
+      put(RecoveryConfigHelper.RECOVERY_WINDOW_IN_MIN_KEY, "23");
+      put(RecoveryConfigHelper.RECOVERY_RETRY_GAP_KEY, "2");
+    }};
+
+    Set<String> hostNames = new HashSet<String>(){{
+      add(hostname);
+    }};
+
+    return heartbeatTestHelper.getDummyCluster("cluster1", "HDP-0.1", configProperties, hostNames);
+  }
+}


Mime
View raw message