You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2015/05/07 14:12:09 UTC
ambari git commit: AMBARI-10976 - HDP-2.2 To HDP-2.3 Upgrade
Pre-Upgrade Checks (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/trunk e65bad149 -> f4725228e
AMBARI-10976 - HDP-2.2 To HDP-2.3 Upgrade Pre-Upgrade Checks (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f4725228
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f4725228
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f4725228
Branch: refs/heads/trunk
Commit: f4725228e79416712986d0c2de1cb251c47e80b0
Parents: e65bad1
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed May 6 20:47:46 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu May 7 08:12:02 2015 -0400
----------------------------------------------------------------------
.../server/checks/AbstractCheckDescriptor.java | 37 ++++-
.../ambari/server/checks/CheckDescription.java | 38 ++++-
.../server/checks/ClientRetryPropertyCheck.java | 116 +++++++++++++
.../server/checks/ConfigurationMergeCheck.java | 3 +
.../HiveDynamicServiceDiscoveryCheck.java | 102 ++++++++++++
.../server/checks/HostsHeartbeatCheck.java | 4 +
.../checks/HostsMasterMaintenanceCheck.java | 4 +
.../checks/HostsRepositoryVersionCheck.java | 4 +
.../checks/SecondaryNamenodeDeletedCheck.java | 3 +
.../checks/ServicesDecommissionCheck.java | 3 +
.../checks/ServicesMaintenanceModeCheck.java | 4 +
.../ServicesMapReduceDistributedCacheCheck.java | 4 +
.../ServicesNamenodeHighAvailabilityCheck.java | 4 +
.../ServicesTezDistributedCacheCheck.java | 4 +
.../ambari/server/checks/ServicesUpCheck.java | 4 +
.../checks/ServicesYarnWorkPreservingCheck.java | 26 +--
.../ambari/server/checks/UpgradeCheck.java | 58 +++++++
.../ambari/server/checks/UpgradeCheckGroup.java | 83 ++++++++++
.../server/checks/UpgradeCheckRegistry.java | 113 +++++++++++++
.../checks/YarnRMHighAvailabilityCheck.java | 80 +++++++++
.../YarnTimelineServerStatePreservingCheck.java | 94 +++++++++++
.../server/controller/ControllerModule.java | 54 +++++-
.../PreUpgradeCheckResourceProvider.java | 74 +--------
.../apache/ambari/server/state/CheckHelper.java | 31 ++--
.../checks/ClientRetryPropertyCheckTest.java | 164 +++++++++++++++++++
.../server/checks/UpgradeCheckOrderTest.java | 103 ++++++++++++
...nTimelineServerStatePreservingCheckTest.java | 127 ++++++++++++++
.../ambari/server/state/CheckHelperTest.java | 15 +-
28 files changed, 1246 insertions(+), 110 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
index 1816ce8..8cabf29 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
@@ -28,6 +28,8 @@ import org.apache.ambari.server.orm.dao.HostVersionDAO;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
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.DesiredConfig;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.stack.PrereqCheckType;
@@ -46,8 +48,8 @@ import com.google.inject.Provider;
public abstract class AbstractCheckDescriptor {
private static final Logger LOG = LoggerFactory.getLogger(AbstractCheckDescriptor.class);
- private static final StackId STACK_HDP_22 = new StackId("HDP", "2.2");
- private static final StackId STACK_HDP_23 = new StackId("HDP", "2.3");
+ protected static final StackId STACK_HDP_22 = new StackId("HDP", "2.2");
+ protected static final StackId STACK_HDP_23 = new StackId("HDP", "2.3");
protected static final String DEFAULT = "default";
@@ -178,6 +180,37 @@ public abstract class AbstractCheckDescriptor {
}
/**
+ * Gets a cluster configuration property if it exists, or {@code null}
+ * otherwise.
+ *
+ * @param request
+ * the request (not {@code null}).
+ * @param configType
+ * the configuration type, such as {@code hdfs-site} (not
+ * {@code null}).
+ * @param propertyName
+ * the name of the property (not {@code null}).
+ * @return the property value or {@code null} if not found.
+ * @throws AmbariException
+ */
+ protected String getProperty(PrereqCheckRequest request, String configType, String propertyName)
+ throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ final Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
+ final DesiredConfig desiredConfig = desiredConfigs.get(configType);
+
+ if (null == desiredConfig) {
+ return null;
+ }
+
+ final Config config = cluster.getConfig(configType, desiredConfig.getTag());
+
+ Map<String, String> properties = config.getProperties();
+ return properties.get(propertyName);
+ }
+
+ /**
* Gets the fail reason
* @param key the failure text key
* @param prerequisiteCheck the check being performed
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
index b00d6fb..7103566 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
@@ -28,6 +28,17 @@ import org.apache.ambari.server.state.stack.PrereqCheckType;
*/
public enum CheckDescription {
+ CLIENT_RETRY(PrereqCheckType.SERVICE,
+ "Client Retry Properties",
+ new HashMap<String, String>() {{
+ put(ClientRetryPropertyCheck.HDFS_CLIENT_RETRY_MISSING_KEY,
+ "The hdfs-site.xml property dfs.client.retry.policy.enabled should be set to true.");
+ put(ClientRetryPropertyCheck.HIVE_CLIENT_RETRY_MISSING_KEY,
+ "The hive-site.xml property hive.metastore.failure.retries should be set to a positive value.");
+ put(ClientRetryPropertyCheck.OOZIE_CLIENT_RETRY_MISSING_KEY,
+ "The oozie-env.sh script must contain a retry count such as export OOZIE_CLIENT_OPTS=\"${OOZIE_CLIENT_OPTS} -Doozie.connection.retry.count=5\"");
+ }}),
+
HOSTS_HEARTBEAT(PrereqCheckType.HOST,
"All hosts must be heartbeating with the Ambari Server unless they are in Maintenance Mode",
new HashMap<String, String>() {{
@@ -87,7 +98,7 @@ public enum CheckDescription {
}}),
SERVICES_NAMENODE_HA(PrereqCheckType.SERVICE,
- "NameNode High Availability must be enabled",
+ "NameNode High Availability must be enabled",
new HashMap<String, String>() {{
put(AbstractCheckDescriptor.DEFAULT,
"NameNode High Availability is not enabled. Verify that dfs.nameservices property is present in hdfs-site.xml.");
@@ -123,6 +134,31 @@ public enum CheckDescription {
"YARN should have work preserving restart enabled. The yarn-site.xml property yarn.resourcemanager.work-preserving-recovery.enabled property should be set to true.");
}}),
+ SERVICES_YARN_RM_HA(PrereqCheckType.SERVICE,
+ "YARN ResourceManager HA should be enabled to prevent a disruption in service during the upgrade",
+ new HashMap<String, String>() {{
+ put(AbstractCheckDescriptor.DEFAULT,
+ "YARN ResourceManager High Availability is not enabled. Verify that dfs.nameservices property is present in hdfs-site.xml.");
+ }}),
+
+ SERVICES_YARN_TIMELINE_ST(PrereqCheckType.SERVICE,
+ "YARN Timeline state preserving restart should be enabled",
+ new HashMap<String, String>() {{
+ put(AbstractCheckDescriptor.DEFAULT,
+ "YARN should have state preserving restart enabled for the Timeline server. The yarn-site.xml property yarn.timeline-service.recovery.enabled should be set to true.");
+ }}),
+
+ SERVICES_HIVE_DYNAMIC_SERVICE_DISCOVERY(PrereqCheckType.SERVICE,
+ "Hive Dynamic Service Discovery",
+ new HashMap<String, String>() {{
+ put(HiveDynamicServiceDiscoveryCheck.HIVE_DYNAMIC_SERVICE_DISCOVERY_ENABLED_KEY,
+ "The hive-site.xml property hive.server2.support.dynamic.service.discovery should be set to true.");
+ put(HiveDynamicServiceDiscoveryCheck.HIVE_DYNAMIC_SERVICE_ZK_QUORUM_KEY,
+ "The hive-site.xml property hive.zookeeper.quorum should be set to a comma-separate list of ZooKeeper hosts:port pairs.");
+ put(HiveDynamicServiceDiscoveryCheck.HIVE_DYNAMIC_SERVICE_ZK_NAMESPACE_KEY,
+ "The hive-site.xml property hive.server2.zookeeper.namespace should be set to the value for the root namespace on ZooKeeper.");
+ }}),
+
CONFIG_MERGE(PrereqCheckType.CLUSTER,
"Configuration Merge Check",
new HashMap<String, String>() {{
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
new file mode 100644
index 0000000..5fbb5e4
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
@@ -0,0 +1,116 @@
+/*
+ * 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.checks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link ClientRetryPropertyCheck} class is used to check that the
+ * client retry properties for HDFS, HIVE, and OOZIE are set.
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.CLIENT_RETRY_PROPERTY)
+public class ClientRetryPropertyCheck extends AbstractCheckDescriptor {
+
+ static final String HDFS_CLIENT_RETRY_MISSING_KEY = "hdfs.client.retry.missing.key";
+ static final String HIVE_CLIENT_RETRY_MISSING_KEY = "hive.client.retry.missing.key";
+ static final String OOZIE_CLIENT_RETRY_MISSING_KEY = "oozie.client.retry.missing.key";
+
+ /**
+ * Constructor.
+ */
+ public ClientRetryPropertyCheck() {
+ super(CheckDescription.CLIENT_RETRY);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
+ if (!super.isApplicable(request)) {
+ return false;
+ }
+
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ Map<String, Service> services = cluster.getServices();
+
+ if (services.containsKey("HDFS") || services.containsKey("HIVE")
+ || services.containsKey("OOZIE")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ Map<String, Service> services = cluster.getServices();
+
+ List<String> errorMessages = new ArrayList<String>();
+
+ // check hdfs client property
+ if (services.containsKey("HDFS")) {
+ String hdfsClientRetry = getProperty(request, "hdfs-site", "dfs.client.retry.policy.enabled");
+ if (null == hdfsClientRetry || !Boolean.parseBoolean(hdfsClientRetry)) {
+ errorMessages.add(getFailReason(HDFS_CLIENT_RETRY_MISSING_KEY, prerequisiteCheck, request));
+ prerequisiteCheck.getFailedOn().add("HDFS");
+ }
+ }
+
+ // check hive client properties
+ if (services.containsKey("HIVE")) {
+ String hiveClientRetryCount = getProperty(request, "hive-site",
+ "hive.metastore.failure.retries");
+
+ if (null != hiveClientRetryCount && Integer.parseInt(hiveClientRetryCount) <= 0) {
+ errorMessages.add(getFailReason(HIVE_CLIENT_RETRY_MISSING_KEY, prerequisiteCheck, request));
+ prerequisiteCheck.getFailedOn().add("HIVE");
+ }
+ }
+
+ if (services.containsKey("OOZIE")) {
+ String oozieClientRetry = getProperty(request, "oozie-env", "template");
+ if (null == oozieClientRetry || !oozieClientRetry.contains("-Doozie.connection.retry.count")) {
+ errorMessages.add(getFailReason(OOZIE_CLIENT_RETRY_MISSING_KEY, prerequisiteCheck, request));
+ prerequisiteCheck.getFailedOn().add("OOZIE");
+ }
+ }
+
+ if (!errorMessages.isEmpty()) {
+ prerequisiteCheck.setFailReason(StringUtils.join(errorMessages, " "));
+ prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
index e4dd0e6..095ecd5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
@@ -33,10 +33,13 @@ import org.apache.ambari.server.state.stack.PrerequisiteCheck;
import org.apache.commons.lang.StringUtils;
import com.google.inject.Inject;
+import com.google.inject.Singleton;
/**
* Checks for configuration merge conflicts.
*/
+@Singleton
+@UpgradeCheck(order = 99.0f)
public class ConfigurationMergeCheck extends AbstractCheckDescriptor {
@Inject
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
new file mode 100644
index 0000000..74bed8a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
@@ -0,0 +1,102 @@
+/*
+ * 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.checks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link HiveDynamicServiceDiscoveryCheck} class is used to check that HIVE
+ * is properly configured for dynamic discovery.
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 1.0f)
+public class HiveDynamicServiceDiscoveryCheck extends AbstractCheckDescriptor {
+
+ static final String HIVE_DYNAMIC_SERVICE_DISCOVERY_ENABLED_KEY = "hive.dynamic-service.discovery.enabled.key";
+ static final String HIVE_DYNAMIC_SERVICE_ZK_QUORUM_KEY = "hive.dynamic-service.discovery.zk-quorum.key";
+ static final String HIVE_DYNAMIC_SERVICE_ZK_NAMESPACE_KEY = "hive.dynamic-service.zk-namespace.key";
+
+ /**
+ * Constructor.
+ */
+ public HiveDynamicServiceDiscoveryCheck() {
+ super(CheckDescription.SERVICES_HIVE_DYNAMIC_SERVICE_DISCOVERY);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
+ if (!super.isApplicable(request)) {
+ return false;
+ }
+
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ Map<String, Service> services = cluster.getServices();
+ if (services.containsKey("HIVE")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+ List<String> errorMessages = new ArrayList<String>();
+
+ String dynamicServiceDiscoveryEnabled = getProperty(request, "hive-site", "hive.server2.support.dynamic.service.discovery");
+ String zookeeperQuorum = getProperty(request, "hive-site", "hive.zookeeper.quorum");
+ String zookeeperNamespace = getProperty(request, "hive-site", "hive.server2.zookeeper.namespace");
+
+ if (null == dynamicServiceDiscoveryEnabled || !Boolean.parseBoolean(dynamicServiceDiscoveryEnabled)) {
+ errorMessages.add(getFailReason(HIVE_DYNAMIC_SERVICE_DISCOVERY_ENABLED_KEY, prerequisiteCheck, request));
+ }
+
+ if (StringUtils.isBlank(zookeeperQuorum)) {
+ errorMessages.add(getFailReason(HIVE_DYNAMIC_SERVICE_ZK_QUORUM_KEY, prerequisiteCheck,
+ request));
+ }
+
+ if (StringUtils.isBlank(zookeeperNamespace)) {
+ errorMessages.add(getFailReason(HIVE_DYNAMIC_SERVICE_ZK_NAMESPACE_KEY, prerequisiteCheck,
+ request));
+ }
+
+ if (!errorMessages.isEmpty()) {
+ prerequisiteCheck.setFailReason(StringUtils.join(errorMessages, " "));
+ prerequisiteCheck.getFailedOn().add("HIVE");
+ prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
index cf9e4ae..6076a32 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
@@ -28,9 +28,13 @@ import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import com.google.inject.Singleton;
+
/**
* Checks that all hosts are either in maintenance mode or heartbeating with the server.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 1.0f)
public class HostsHeartbeatCheck extends AbstractCheckDescriptor {
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
index 2c5ff28..ef93337 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
@@ -34,9 +34,13 @@ import org.apache.ambari.server.state.stack.PrerequisiteCheck;
import org.apache.ambari.server.state.stack.UpgradePack;
import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
+import com.google.inject.Singleton;
+
/**
* Checks that all hosts in maintenance state do not have master components.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.MAINTENANCE_MODE, order = 1.0f)
public class HostsMasterMaintenanceCheck extends AbstractCheckDescriptor {
static final String KEY_NO_UPGRADE_NAME = "no_upgrade_name";
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
index 0ea5d08..6ebf8e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
@@ -32,9 +32,13 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import com.google.inject.Singleton;
+
/**
* Checks that all hosts have particular repository version.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.REPOSITORY_VERSION)
public class HostsRepositoryVersionCheck extends AbstractCheckDescriptor {
static final String KEY_NO_REPO_VERSION = "no_repo_version";
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
index 14ec2c1..493042f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
@@ -34,10 +34,13 @@ import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
import com.google.inject.Inject;
+import com.google.inject.Singleton;
/**
* Checks that the Secondary NameNode is not present on any of the hosts.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.NAMENODE_HA, order = 2.0f)
public class SecondaryNamenodeDeletedCheck extends AbstractCheckDescriptor {
@Inject
HostComponentStateDAO hostComponentStateDao;
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesDecommissionCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesDecommissionCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesDecommissionCheck.java
index 7497c2f..6ebfd1f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesDecommissionCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesDecommissionCheck.java
@@ -29,9 +29,12 @@ import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import com.google.inject.Singleton;
+
/**
* Checks that there are no services in decommission state.
*/
+@Singleton
public class ServicesDecommissionCheck extends AbstractCheckDescriptor {
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
index 0ae5c46..2b5ff49 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
@@ -28,9 +28,13 @@ import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import com.google.inject.Singleton;
+
/**
* Checks that services are in the maintenance mode.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.MAINTENANCE_MODE, order = 2.0f)
public class ServicesMaintenanceModeCheck extends AbstractCheckDescriptor {
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
index 36526e3..be5d11a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
@@ -31,9 +31,13 @@ import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
import org.apache.commons.lang.StringUtils;
+import com.google.inject.Singleton;
+
/**
* Checks that MR jobs reference hadoop libraries from the distributed cache.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.NAMENODE_HA, order = 3.0f)
public class ServicesMapReduceDistributedCacheCheck extends AbstractCheckDescriptor {
static final String KEY_APP_CLASSPATH = "app_classpath";
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
index e43e4fb..d92f12d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
@@ -28,9 +28,13 @@ import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import com.google.inject.Singleton;
+
/**
* Checks that namenode high availability is enabled.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.NAMENODE_HA, order = 1.0f)
public class ServicesNamenodeHighAvailabilityCheck extends AbstractCheckDescriptor {
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
index 41735b4..68a7103 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
@@ -31,9 +31,13 @@ import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
import org.apache.commons.lang.StringUtils;
+import com.google.inject.Singleton;
+
/**
* Checks that Tez jobs reference hadoop libraries from the distributed cache.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.NAMENODE_HA, order = 4.0f)
public class ServicesTezDistributedCacheCheck extends AbstractCheckDescriptor {
static final String KEY_LIB_URI_MISSING = "tez_lib_uri_missing";
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
index e0696fa..243b26d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
@@ -27,9 +27,13 @@ import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import com.google.inject.Singleton;
+
/**
* Checks that services are up.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 2.0f)
public class ServicesUpCheck extends AbstractCheckDescriptor {
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
index a56f35d..a0b2b59 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
@@ -17,21 +17,21 @@
*/
package org.apache.ambari.server.checks;
-import java.util.Map;
-
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.controller.PrereqCheckRequest;
import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.PrerequisiteCheck;
import org.apache.commons.lang.BooleanUtils;
+import com.google.inject.Singleton;
+
/**
* Checks that YARN has work-preserving restart enabled.
*/
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 1.0f)
public class ServicesYarnWorkPreservingCheck extends AbstractCheckDescriptor {
/**
@@ -41,6 +41,9 @@ public class ServicesYarnWorkPreservingCheck extends AbstractCheckDescriptor {
super(CheckDescription.SERVICES_YARN_WP);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
if (!super.isApplicable(request)) {
@@ -56,16 +59,15 @@ public class ServicesYarnWorkPreservingCheck extends AbstractCheckDescriptor {
return true;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
- final String clusterName = request.getClusterName();
- final Cluster cluster = clustersProvider.get().getCluster(clusterName);
- final String configType = "yarn-site";
- final Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
- final DesiredConfig desiredConfig = desiredConfigs.get(configType);
- final Config config = cluster.getConfig(configType, desiredConfig.getTag());
- if (!config.getProperties().containsKey("yarn.resourcemanager.work-preserving-recovery.enabled") ||
- !BooleanUtils.toBoolean(config.getProperties().get("yarn.resourcemanager.work-preserving-recovery.enabled"))) {
+ String propertyValue = getProperty(request, "yarn-site",
+ "yarn.resourcemanager.work-preserving-recovery.enabled");
+
+ if (null == propertyValue || !BooleanUtils.toBoolean(propertyValue)) {
prerequisiteCheck.getFailedOn().add("YARN");
prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
prerequisiteCheck.setFailReason(getFailReason(prerequisiteCheck, request));
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
new file mode 100644
index 0000000..9fa8916
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
@@ -0,0 +1,58 @@
+/**
+ * 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.checks;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import com.google.inject.ScopeAnnotation;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link UpgradeCheck} annotation is used to provide ordering and grouping
+ * to any {@link AbstractCheckDescriptor} instance.
+ * <p/>
+ * Classes marked with this annotation should also be {@link Singleton}. They
+ * will be discovered on the classpath and then registered with the
+ * {@link UpgradeCheckRegistry}.
+ */
+@Target({ ElementType.TYPE })
+@Retention(RUNTIME)
+@ScopeAnnotation
+public @interface UpgradeCheck {
+
+ /**
+ * The group that the pre-upgrade check belongs to.
+ *
+ * @return the group, or {@link UpgradeCheckGroup#DEFAULT} if not specified.
+ */
+ UpgradeCheckGroup group() default UpgradeCheckGroup.DEFAULT;
+
+ /**
+ * The order of the pre-upgrade check within its group.
+ * <p/>
+ * The order is determined by a {@code float} so that new checks can be added
+ * in between others without the need to reorder all of the existing checks.
+ *
+ * @return the order, or {@code 1.0f} if not specified.
+ */
+ float order() default 1.0f;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java
new file mode 100644
index 0000000..16e56f3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java
@@ -0,0 +1,83 @@
+/**
+ * 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.checks;
+
+/**
+ * The {@link UpgradeCheckGroup} enum is used to organize pre-upgrade checks
+ * into specific groups that have their own relational ordering.
+ * <p/>
+ * The order for each group is determined by a {@code float} so that new groups
+ * can be added in between others without the need to reorder all of the groups.
+ */
+public enum UpgradeCheckGroup {
+
+ /**
+ * Check for masters in maintenance mode and then services in maintenance
+ * mode.
+ */
+ MAINTENANCE_MODE(1.0f),
+
+ /**
+ * Checks the repository version on the hosts.
+ */
+ REPOSITORY_VERSION(2.0f),
+
+ /**
+ * Checks for NameNode HA and checks that depend on NameNode HA.
+ */
+ NAMENODE_HA(3.0f),
+
+ /**
+ * Checks for the state of a host or service being alive and responsive.
+ */
+ LIVELINESS(4.0f),
+
+ /**
+ * Checks for the client retry properties to be set in clients that support
+ * this.
+ */
+ CLIENT_RETRY_PROPERTY(5.0f),
+
+ /**
+ * All other checks.
+ */
+ DEFAULT(Float.MAX_VALUE);
+
+ /**
+ * The order of upgrade check groups.
+ */
+ private final Float m_order;
+
+ /**
+ * Constructor.
+ *
+ * @param order
+ */
+ private UpgradeCheckGroup(Float order) {
+ m_order = order;
+ }
+
+ /**
+ * Gets the group's order.
+ *
+ * @return the order of the group.
+ */
+ public Float getOrder() {
+ return m_order;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
new file mode 100644
index 0000000..8be572c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
@@ -0,0 +1,113 @@
+/**
+ * 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.checks;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link UpgradeCheckRegistry} contains the ordered list of all pre-upgrade
+ * checks. This will order the checks according to
+ * {@link PreUpgradeCheckComparator}.
+ */
+@Singleton
+public class UpgradeCheckRegistry {
+
+ /**
+ * The list of upgrade checks to run through.
+ */
+ private Set<AbstractCheckDescriptor> m_upgradeChecks = new TreeSet<AbstractCheckDescriptor>(
+ new PreUpgradeCheckComparator());
+
+ /**
+ * Register an upgrade check.
+ *
+ * @param upgradeCheck
+ * the check to register (not {@code null}).
+ */
+ public void register(AbstractCheckDescriptor upgradeCheck) {
+ m_upgradeChecks.add(upgradeCheck);
+ }
+
+ /**
+ * Gets an ordered list of all of the upgrade checks.
+ *
+ * @return
+ */
+ public List<AbstractCheckDescriptor> getUpgradeChecks() {
+ return new ArrayList<AbstractCheckDescriptor>(m_upgradeChecks);
+ }
+
+ /**
+ * THe {@link PreUpgradeCheckComparator} class is used to compare
+ * {@link AbstractCheckDescriptor} based on their {@link UpgradeCheck}
+ * annotations.
+ */
+ private static final class PreUpgradeCheckComparator implements
+ Comparator<AbstractCheckDescriptor> {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int compare(AbstractCheckDescriptor check1, AbstractCheckDescriptor check2) {
+ Class<? extends AbstractCheckDescriptor> clazz1 = check1.getClass();
+ Class<? extends AbstractCheckDescriptor> clazz2 = check2.getClass();
+
+ UpgradeCheck annotation1 = clazz1.getAnnotation(UpgradeCheck.class);
+ UpgradeCheck annotation2 = clazz2.getAnnotation(UpgradeCheck.class);
+
+ UpgradeCheckGroup group1 = UpgradeCheckGroup.DEFAULT;
+ UpgradeCheckGroup group2 = UpgradeCheckGroup.DEFAULT;
+ Float groupOrder1 = Float.valueOf(group1.getOrder());
+ Float groupOrder2 = Float.valueOf(group2.getOrder());
+
+ Float order1 = 1.0f;
+ Float order2 = 1.0f;
+
+ if (null != annotation1) {
+ group1 = annotation1.group();
+ groupOrder1 = Float.valueOf(group1.getOrder());
+ order1 = Float.valueOf(annotation1.order());
+ }
+
+ if (null != annotation2) {
+ group2 = annotation2.group();
+ groupOrder2 = Float.valueOf(group2.getOrder());
+ order2 = Float.valueOf(annotation2.order());
+ }
+
+ int groupComparison = groupOrder1.compareTo(groupOrder2);
+ if (groupComparison != 0) {
+ return groupComparison;
+ }
+
+ int orderComparison = order1.compareTo(order2);
+ if (orderComparison != 0) {
+ return orderComparison;
+ }
+
+ return clazz1.getName().compareTo(clazz2.getName());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
new file mode 100644
index 0000000..db8af29
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
@@ -0,0 +1,80 @@
+/*
+ * 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.checks;
+
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.commons.lang.BooleanUtils;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link YarnRMHighAvailabilityCheck} checks that YARN has HA mode enabled
+ * for ResourceManager..
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 1.0f)
+public class YarnRMHighAvailabilityCheck extends AbstractCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public YarnRMHighAvailabilityCheck() {
+ super(CheckDescription.SERVICES_YARN_RM_HA);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
+ if (!super.isApplicable(request)) {
+ return false;
+ }
+
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ Map<String, Service> services = cluster.getServices();
+ if (!services.containsKey("YARN")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+ // pretty weak sauce here; probably should do a bit more, like query JMX to
+ // see that there is at least 1 RM active and 1 in standby
+ String propertyValue = getProperty(request, "yarn-site", "yarn.resourcemanager.ha.enabled");
+
+ if (null == propertyValue || !BooleanUtils.toBoolean(propertyValue)) {
+ prerequisiteCheck.getFailedOn().add("YARN");
+ prerequisiteCheck.setStatus(PrereqCheckStatus.WARNING);
+ prerequisiteCheck.setFailReason(getFailReason(prerequisiteCheck, request));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
new file mode 100644
index 0000000..ef7cbff
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
@@ -0,0 +1,94 @@
+/*
+ * 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.checks;
+
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.ambari.server.utils.VersionUtils;
+import org.apache.commons.lang.BooleanUtils;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link YarnTimelineServerStatePreservingCheck} is used to check that the
+ * YARN Timeline server has state preserving mode enabled. This value is only
+ * present in HDP 2.2.4.2+.
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 1.0f)
+public class YarnTimelineServerStatePreservingCheck extends AbstractCheckDescriptor {
+
+ private final static String YARN_TIMELINE_STATE_RECOVERY_ENABLED_KEY = "yarn.timeline-service.recovery.enabled";
+
+ /**
+ * Constructor.
+ */
+ public YarnTimelineServerStatePreservingCheck() {
+ super(CheckDescription.SERVICES_YARN_TIMELINE_ST);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
+ if (!super.isApplicable(request)) {
+ return false;
+ }
+
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ Map<String, Service> services = cluster.getServices();
+ if (!services.containsKey("YARN")) {
+ return false;
+ }
+
+ // not applicable if not HDP 2.2.4.2 or later
+ String stackName = cluster.getCurrentStackVersion().getStackName();
+ if (!"HDP".equals(stackName)) {
+ return false;
+ }
+
+ String currentClusterRepositoryVersion = cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion();
+ if (VersionUtils.compareVersions(currentClusterRepositoryVersion, "2.2.4.2") < 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+ String propertyValue = getProperty(request, "yarn-site",
+ YARN_TIMELINE_STATE_RECOVERY_ENABLED_KEY);
+
+ if (null == propertyValue || !BooleanUtils.toBoolean(propertyValue)) {
+ prerequisiteCheck.getFailedOn().add("YARN");
+ prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
+ prerequisiteCheck.setFailReason(getFailReason(prerequisiteCheck, request));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 08a56d0..432e41a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -56,6 +56,8 @@ import org.apache.ambari.server.actionmanager.HostRoleCommandFactoryImpl;
import org.apache.ambari.server.actionmanager.RequestFactory;
import org.apache.ambari.server.actionmanager.StageFactory;
import org.apache.ambari.server.actionmanager.StageFactoryImpl;
+import org.apache.ambari.server.checks.AbstractCheckDescriptor;
+import org.apache.ambari.server.checks.UpgradeCheckRegistry;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType;
import org.apache.ambari.server.configuration.Configuration.DatabaseType;
@@ -144,6 +146,7 @@ import com.mchange.v2.c3p0.ComboPooledDataSource;
*/
public class ControllerModule extends AbstractModule {
private static Logger LOG = LoggerFactory.getLogger(ControllerModule.class);
+ private static final String AMBARI_PACKAGE = "org.apache.ambari.server";
private final Configuration configuration;
private final OsFamily os_family;
@@ -329,6 +332,7 @@ public class ControllerModule extends AbstractModule {
bindByAnnotation(null);
bindNotificationDispatchers();
+ registerUpgradeChecks();
}
@@ -451,7 +455,7 @@ public class ControllerModule extends AbstractModule {
scanner.addIncludeFilter(new AnnotationTypeFilter(cls));
}
- beanDefinitions = scanner.findCandidateComponents("org.apache.ambari.server");
+ beanDefinitions = scanner.findCandidateComponents(AMBARI_PACKAGE);
}
if (null == beanDefinitions || beanDefinitions.size() == 0) {
@@ -557,4 +561,52 @@ public class ControllerModule extends AbstractModule {
}
}
}
+
+ /**
+ * Searches for all instances of {@link AbstractCheckDescriptor} on the
+ * classpath and registers each as a singleton with the
+ * {@link UpgradeCheckRegistry}.
+ */
+ @SuppressWarnings("unchecked")
+ private void registerUpgradeChecks() {
+ ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
+ false);
+
+ // make the registry a singleton
+ UpgradeCheckRegistry registry = new UpgradeCheckRegistry();
+ bind(UpgradeCheckRegistry.class).toInstance(registry);
+
+ // match all implementations of the base check class
+ AssignableTypeFilter filter = new AssignableTypeFilter(AbstractCheckDescriptor.class);
+ scanner.addIncludeFilter(filter);
+
+ Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents(AMBARI_PACKAGE);
+
+ // no dispatchers is a problem
+ if (null == beanDefinitions || beanDefinitions.size() == 0) {
+ LOG.error("No instances of {} found to register", AbstractCheckDescriptor.class);
+ return;
+ }
+
+ // for every discovered check, singleton-ize them and register with the
+ // registry
+ for (BeanDefinition beanDefinition : beanDefinitions) {
+ String className = beanDefinition.getBeanClassName();
+ Class<?> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
+
+ try {
+ AbstractCheckDescriptor upgradeCheck = (AbstractCheckDescriptor) clazz.newInstance();
+ bind((Class<AbstractCheckDescriptor>) clazz).toInstance(upgradeCheck);
+ registry.register(upgradeCheck);
+ } catch (Exception exception) {
+ LOG.error("Unable to bind and register upgrade check {}", clazz, exception);
+ }
+ }
+
+ // log the order of the pre-upgrade checks
+ List<AbstractCheckDescriptor> upgradeChecks = registry.getUpgradeChecks();
+ for (AbstractCheckDescriptor upgradeCheck : upgradeChecks) {
+ LOG.error("Registered pre-upgrade check {}", upgradeCheck.getClass());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
index 3460423..207bf89 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
@@ -17,29 +17,15 @@
*/
package org.apache.ambari.server.controller.internal;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StaticallyInject;
-import org.apache.ambari.server.checks.AbstractCheckDescriptor;
-import org.apache.ambari.server.checks.ConfigurationMergeCheck;
-import org.apache.ambari.server.checks.HostsHeartbeatCheck;
-import org.apache.ambari.server.checks.HostsMasterMaintenanceCheck;
-import org.apache.ambari.server.checks.HostsRepositoryVersionCheck;
-import org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck;
-import org.apache.ambari.server.checks.ServicesDecommissionCheck;
-import org.apache.ambari.server.checks.ServicesMaintenanceModeCheck;
-import org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck;
-import org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck;
-import org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck;
-import org.apache.ambari.server.checks.ServicesUpCheck;
-import org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck;
+import org.apache.ambari.server.checks.UpgradeCheckRegistry;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.PrereqCheckRequest;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
@@ -80,65 +66,13 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
public static final String UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "repository_version");
@Inject
- private static ServicesMaintenanceModeCheck servicesMaintenanceModeCheck;
-
- @Inject
- private static HostsMasterMaintenanceCheck hostsMasterMaintenanceCheck;
-
- @Inject
- private static HostsRepositoryVersionCheck hostsRepositoryVersionCheck;
-
- @Inject
- private static ServicesNamenodeHighAvailabilityCheck servicesNamenodeHighAvailabilityCheck;
-
- @Inject
- private static SecondaryNamenodeDeletedCheck secondaryNamenodeDeletedCheck;
-
- @Inject
- private static ServicesYarnWorkPreservingCheck servicesYarnWorkPreservingCheck;
-
- @Inject
- private static ServicesDecommissionCheck servicesDecommissionCheck;
-
- @Inject
- private static ServicesMapReduceDistributedCacheCheck servicesJobsDistributedCacheCheck;
-
- @Inject
- private static HostsHeartbeatCheck heartbeatCheck;
-
- @Inject
- private static ServicesUpCheck servicesUpCheck;
-
- @Inject
- private static ServicesTezDistributedCacheCheck servicesTezDistributedCacheCheck;
-
- @Inject
- private static ConfigurationMergeCheck configMergeCheck;
-
- @Inject
private static Provider<Clusters> clustersProvider;
@Inject
private static RepositoryVersionDAO repositoryVersionDAO;
- /**
- * List of the registered upgrade checks. Make sure that if a check that
- * depends on the result of another check comes earlier in the list.
- * For example, MR2 and Tez distributed cache checks rely on NN-HA check passing.
- */
- private List<AbstractCheckDescriptor> updateChecksRegistry = Arrays.asList(
- hostsMasterMaintenanceCheck,
- hostsRepositoryVersionCheck,
- servicesMaintenanceModeCheck,
- servicesNamenodeHighAvailabilityCheck,
- secondaryNamenodeDeletedCheck,
- servicesYarnWorkPreservingCheck,
- servicesDecommissionCheck,
- servicesJobsDistributedCacheCheck,
- heartbeatCheck,
- servicesUpCheck,
- servicesTezDistributedCacheCheck,
- configMergeCheck);
+ @Inject
+ private static UpgradeCheckRegistry upgradeCheckRegistry;
private static Set<String> pkPropertyIds = Collections.singleton(UPGRADE_CHECK_ID_PROPERTY_ID);
@@ -203,7 +137,7 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
upgradeCheckRequest.setTargetStackId(repositoryVersionEntity.getStackId());
}
- for (PrerequisiteCheck prerequisiteCheck : checkHelper.performChecks(upgradeCheckRequest, updateChecksRegistry)) {
+ for (PrerequisiteCheck prerequisiteCheck : checkHelper.performChecks(upgradeCheckRequest, upgradeCheckRegistry.getUpgradeChecks())) {
final Resource resource = new ResourceImpl(Resource.Type.PreUpgradeCheck);
setResourceProperty(resource, UPGRADE_CHECK_ID_PROPERTY_ID, prerequisiteCheck.getId(), requestedIds);
setResourceProperty(resource, UPGRADE_CHECK_CHECK_PROPERTY_ID, prerequisiteCheck.getDescription(), requestedIds);
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
index abaf8e7..5a8d4fd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
@@ -37,27 +37,31 @@ public class CheckHelper {
*/
private static Logger LOG = LoggerFactory.getLogger(CheckHelper.class);
-
/**
* Executes all registered pre-requisite checks.
*
- * @param request pre-requisite check request
+ * @param request
+ * pre-requisite check request
* @return list of pre-requisite check results
*/
- public List<PrerequisiteCheck> performChecks(PrereqCheckRequest request, List<AbstractCheckDescriptor> checksRegistry) {
+ public List<PrerequisiteCheck> performChecks(PrereqCheckRequest request,
+ List<AbstractCheckDescriptor> checksRegistry) {
final String clusterName = request.getClusterName();
final List<PrerequisiteCheck> prerequisiteCheckResults = new ArrayList<PrerequisiteCheck>();
for (AbstractCheckDescriptor checkDescriptor : checksRegistry) {
final PrerequisiteCheck prerequisiteCheck = new PrerequisiteCheck(
checkDescriptor.getDescription(), clusterName);
- try {
- if (checkDescriptor.isApplicable(request)) {
- checkDescriptor.perform(prerequisiteCheck, request);
- prerequisiteCheckResults.add(prerequisiteCheck);
- request.addResult(checkDescriptor.getDescription(), prerequisiteCheck.getStatus());
+ try {
+ if (!checkDescriptor.isApplicable(request)) {
+ continue;
}
+
+ checkDescriptor.perform(prerequisiteCheck, request);
+ prerequisiteCheckResults.add(prerequisiteCheck);
+
+ request.addResult(checkDescriptor.getDescription(), prerequisiteCheck.getStatus());
} catch (ClusterNotFoundException ex) {
prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
prerequisiteCheck.setFailReason("Cluster with name " + clusterName + " doesn't exists");
@@ -72,19 +76,8 @@ public class CheckHelper {
request.addResult(checkDescriptor.getDescription(), prerequisiteCheck.getStatus());
}
-
-
-
-
-
-
-
-
-
-
}
-
return prerequisiteCheckResults;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/test/java/org/apache/ambari/server/checks/ClientRetryPropertyCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ClientRetryPropertyCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ClientRetryPropertyCheckTest.java
new file mode 100644
index 0000000..92b6a85
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ClientRetryPropertyCheckTest.java
@@ -0,0 +1,164 @@
+/*
+ * 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.checks;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+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.DesiredConfig;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.google.inject.Provider;
+
+/**
+ * Tests for {@link ClientRetryPropertyCheckTest}
+ */
+public class ClientRetryPropertyCheckTest {
+ private final Clusters m_clusters = Mockito.mock(Clusters.class);
+
+ private final ClientRetryPropertyCheck m_check = new ClientRetryPropertyCheck();
+
+ /**
+ *
+ */
+ @Before
+ public void setup() {
+ m_check.clustersProvider = new Provider<Clusters>() {
+
+ @Override
+ public Clusters get() {
+ return m_clusters;
+ }
+ };
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testIsApplicable() throws Exception {
+ final Cluster cluster = Mockito.mock(Cluster.class);
+ Mockito.when(cluster.getClusterId()).thenReturn(1L);
+ Mockito.when(m_clusters.getCluster("cluster")).thenReturn(cluster);
+
+ Map<String, Service> services = new HashMap<String, Service>();
+ Mockito.when(cluster.getServices()).thenReturn(services);
+
+ PrereqCheckRequest request = new PrereqCheckRequest("cluster");
+ request.setRepositoryVersion("2.3.0.0");
+
+ // nothing installed
+ Assert.assertFalse(m_check.isApplicable(request));
+
+ // YARN installed
+ services.put("HDFS", Mockito.mock(Service.class));
+ Assert.assertTrue(m_check.isApplicable(request));
+
+ // OOZIE installed
+ services.clear();
+ services.put("OOZIE", Mockito.mock(Service.class));
+ Assert.assertTrue(m_check.isApplicable(request));
+ }
+
+ @Test
+ public void testPerform() throws Exception {
+ final Cluster cluster = Mockito.mock(Cluster.class);
+
+ Mockito.when(cluster.getClusterId()).thenReturn(1L);
+ Mockito.when(m_clusters.getCluster("cluster")).thenReturn(cluster);
+ Map<String, Service> services = new HashMap<String, Service>();
+ Mockito.when(cluster.getServices()).thenReturn(services);
+
+ services.put("HDFS", Mockito.mock(Service.class));
+
+ final DesiredConfig desiredConfig = Mockito.mock(DesiredConfig.class);
+ Mockito.when(desiredConfig.getTag()).thenReturn("tag");
+ Map<String, DesiredConfig> configMap = new HashMap<String, DesiredConfig>();
+ configMap.put("hdfs-site", desiredConfig);
+ configMap.put("hive-site", desiredConfig);
+ configMap.put("oozie-env", desiredConfig);
+
+ Mockito.when(cluster.getDesiredConfigs()).thenReturn(configMap);
+ final Config config = Mockito.mock(Config.class);
+ Mockito.when(cluster.getConfig(Mockito.anyString(), Mockito.anyString())).thenReturn(config);
+ final Map<String, String> properties = new HashMap<String, String>();
+ Mockito.when(config.getProperties()).thenReturn(properties);
+
+ PrerequisiteCheck check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+
+ // hdfs retry false
+ properties.put("dfs.client.retry.policy.enabled", "false");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+
+ // hdfs retry true
+ properties.put("dfs.client.retry.policy.enabled", "true");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+ // add hive
+ services.put("HIVE", Mockito.mock(Service.class));
+
+ // fail with bad property
+ properties.put("hive.metastore.failure.retries", "0");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+
+ // add hive retry
+ properties.put("hive.metastore.failure.retries", "5");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+ // add oozie
+ services.put("OOZIE", Mockito.mock(Service.class));
+
+ // fail without property
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+
+ // fail without right property
+ properties.put("template", "foo bar baz");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+
+ // pass with right property
+ properties.put("template", "foo bar baz -Doozie.connection.retry.count=5 foobarbaz");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
new file mode 100644
index 0000000..7d70311
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
@@ -0,0 +1,103 @@
+/**
+ * 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.checks;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.ControllerModule;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * Tests the order of pre-upgrade checks.
+ */
+public class UpgradeCheckOrderTest {
+
+ /**
+ * Tests that instances of {@link AbstractCheckDescriptor} are ordered
+ * correctly.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpgradeOrder() throws Exception {
+ String sourceResourceDirectory = "src" + File.separator + "test" + File.separator + "resources";
+
+ Properties properties = new Properties();
+ properties.setProperty(Configuration.SERVER_PERSISTENCE_TYPE_KEY, "in-memory");
+ properties.setProperty(Configuration.OS_VERSION_KEY, "centos6");
+ properties.setProperty(Configuration.SHARED_RESOURCES_DIR_KEY, sourceResourceDirectory);
+
+ Injector injector = Guice.createInjector(new ControllerModule(properties));
+ UpgradeCheckRegistry registry = injector.getInstance(UpgradeCheckRegistry.class);
+ UpgradeCheckRegistry registry2 = injector.getInstance(UpgradeCheckRegistry.class);
+
+ // verify singleton
+ Assert.assertEquals(registry, registry2);
+
+ // get the check list
+ List<AbstractCheckDescriptor> checks = registry.getUpgradeChecks();
+
+ // scan for all checks
+ ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+ AssignableTypeFilter filter = new AssignableTypeFilter(AbstractCheckDescriptor.class);
+ scanner.addIncludeFilter(filter);
+
+ // verify they are equal
+ Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents("org.apache.ambari.server");
+ Assert.assertEquals(beanDefinitions.size(), checks.size());
+
+ AbstractCheckDescriptor lastCheck = null;
+ for (AbstractCheckDescriptor check : checks) {
+ UpgradeCheckGroup group = UpgradeCheckGroup.DEFAULT;
+ UpgradeCheckGroup lastGroup = UpgradeCheckGroup.DEFAULT;
+ Float order = 1.0f;
+ Float lastOrder = 1.0f;
+
+ if (null == lastCheck) {
+ lastCheck = check;
+ }
+
+ UpgradeCheck annotation = check.getClass().getAnnotation(UpgradeCheck.class);
+ UpgradeCheck lastAnnotation = lastCheck.getClass().getAnnotation(UpgradeCheck.class);
+
+ if (null != annotation) {
+ group = annotation.group();
+ order = annotation.order();
+ }
+
+ if (null != lastAnnotation) {
+ lastGroup = lastAnnotation.group();
+ lastOrder = lastAnnotation.order();
+ }
+
+ Assert.assertTrue(lastGroup.getOrder().compareTo(group.getOrder()) <= 0);
+ Assert.assertTrue(lastOrder.compareTo(order) <= 0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/test/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheckTest.java
new file mode 100644
index 0000000..4f2da3b
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheckTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.checks;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+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.DesiredConfig;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.google.inject.Provider;
+
+/**
+ * Tests for {@link YarnTimelineServerStatePreservingCheckTest}
+ */
+public class YarnTimelineServerStatePreservingCheckTest {
+ private final Clusters m_clusters = Mockito.mock(Clusters.class);
+
+ private final YarnTimelineServerStatePreservingCheck m_check = new YarnTimelineServerStatePreservingCheck();
+
+ /**
+ *
+ */
+ @Before
+ public void setup() {
+ m_check.clustersProvider = new Provider<Clusters>() {
+
+ @Override
+ public Clusters get() {
+ return m_clusters;
+ }
+ };
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testIsApplicable() throws Exception {
+ final Cluster cluster = Mockito.mock(Cluster.class);
+ Mockito.when(cluster.getClusterId()).thenReturn(1L);
+ Mockito.when(m_clusters.getCluster("cluster")).thenReturn(cluster);
+ Mockito.when(cluster.getCurrentStackVersion()).thenReturn(new StackId("HDP-2.2"));
+
+ Map<String, Service> services = new HashMap<String, Service>();
+ Mockito.when(cluster.getServices()).thenReturn(services);
+
+ ClusterVersionEntity clusterVersionEntity = Mockito.mock(ClusterVersionEntity.class);
+ Mockito.when(cluster.getCurrentClusterVersion()).thenReturn(clusterVersionEntity);
+
+ RepositoryVersionEntity repositoryVersionEntity = Mockito.mock(RepositoryVersionEntity.class);
+ Mockito.when(clusterVersionEntity.getRepositoryVersion()).thenReturn(repositoryVersionEntity);
+ Mockito.when(repositoryVersionEntity.getVersion()).thenReturn("2.2.4.2");
+
+ PrereqCheckRequest request = new PrereqCheckRequest("cluster");
+ request.setRepositoryVersion("2.3.0.0");
+
+ // YARN not installed
+ Assert.assertFalse(m_check.isApplicable(request));
+
+ // YARN installed
+ services.put("YARN", Mockito.mock(Service.class));
+ Assert.assertTrue(m_check.isApplicable(request));
+
+ Mockito.when(repositoryVersionEntity.getVersion()).thenReturn("2.2.0.0");
+ Assert.assertFalse(m_check.isApplicable(request));
+
+ Mockito.when(repositoryVersionEntity.getVersion()).thenReturn("2.2.4.2");
+ Assert.assertTrue(m_check.isApplicable(request));
+ }
+
+ @Test
+ public void testPerform() throws Exception {
+ final Cluster cluster = Mockito.mock(Cluster.class);
+ Mockito.when(cluster.getClusterId()).thenReturn(1L);
+ Mockito.when(m_clusters.getCluster("cluster")).thenReturn(cluster);
+
+ final DesiredConfig desiredConfig = Mockito.mock(DesiredConfig.class);
+ Mockito.when(desiredConfig.getTag()).thenReturn("tag");
+ Map<String, DesiredConfig> configMap = new HashMap<String, DesiredConfig>();
+ configMap.put("yarn-site", desiredConfig);
+ configMap.put("core-site", desiredConfig);
+
+ Mockito.when(cluster.getDesiredConfigs()).thenReturn(configMap);
+ final Config config = Mockito.mock(Config.class);
+ Mockito.when(cluster.getConfig(Mockito.anyString(), Mockito.anyString())).thenReturn(config);
+ final Map<String, String> properties = new HashMap<String, String>();
+ Mockito.when(config.getProperties()).thenReturn(properties);
+
+ PrerequisiteCheck check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
+
+ properties.put("yarn.timeline-service.recovery.enabled", "true");
+ check = new PrerequisiteCheck(null, null);
+ m_check.perform(check, new PrereqCheckRequest("cluster"));
+ Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f4725228/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
index 17a8abe..e3836cb 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
@@ -58,7 +58,7 @@ public class CheckHelperTest {
*/
@Test
- public void performPreUpgradeChecksTest_ok() throws Exception {
+ public void testPreUpgradeCheck() throws Exception {
final CheckHelper helper = new CheckHelper();
List<AbstractCheckDescriptor> updateChecksRegistry = new ArrayList<AbstractCheckDescriptor>();
AbstractCheckDescriptor descriptor = EasyMock.createNiceMock(AbstractCheckDescriptor.class);
@@ -73,7 +73,7 @@ public class CheckHelperTest {
}
@Test
- public void performPreUpgradeChecksTest_notApplicable() throws Exception {
+ public void testPreUpgradeCheckNotApplicable() throws Exception {
final CheckHelper helper = new CheckHelper();
List<AbstractCheckDescriptor> updateChecksRegistry = new ArrayList<AbstractCheckDescriptor>();
AbstractCheckDescriptor descriptor = EasyMock.createNiceMock(AbstractCheckDescriptor.class);
@@ -85,7 +85,7 @@ public class CheckHelperTest {
}
@Test
- public void performPreUpgradeChecksTest_throwsException() throws Exception {
+ public void testPreUpgradeCheckThrowsException() throws Exception {
final CheckHelper helper = new CheckHelper();
List<AbstractCheckDescriptor> updateChecksRegistry = new ArrayList<AbstractCheckDescriptor>();
AbstractCheckDescriptor descriptor = EasyMock.createNiceMock(AbstractCheckDescriptor.class);
@@ -102,7 +102,7 @@ public class CheckHelperTest {
}
@Test
- public void performPreUpgradeChecksTest_clusterIsMissing() throws Exception {
+ public void testPreUpgradeCheckClusterMissing() throws Exception {
final Clusters clusters = Mockito.mock(Clusters.class);
Mockito.when(clusters.getCluster(Mockito.anyString())).thenAnswer(new Answer<Cluster>() {
@Override
@@ -115,6 +115,7 @@ public class CheckHelperTest {
}
}
});
+
final Injector injector = Guice.createInjector(new AbstractModule() {
@Override
@@ -124,11 +125,15 @@ public class CheckHelperTest {
bind(RepositoryVersionDAO.class).toProvider(Providers.<RepositoryVersionDAO>of(null));
bind(RepositoryVersionHelper.class).toProvider(Providers.<RepositoryVersionHelper>of(null));
bind(AmbariMetaInfo.class).toProvider(Providers.<AmbariMetaInfo>of(null));
+ bind(ServicesUpCheck.class).toInstance(new ServicesUpCheck());
}
});
+
final CheckHelper helper = injector.getInstance(CheckHelper.class);
List<AbstractCheckDescriptor> updateChecksRegistry = new ArrayList<AbstractCheckDescriptor>();
- updateChecksRegistry.add(injector.getInstance(ServicesUpCheck.class)); //mocked Cluster has no services, so the check should always be PASS
+
+ // mocked Cluster has no services, so the check should always be PASS
+ updateChecksRegistry.add(injector.getInstance(ServicesUpCheck.class));
List<PrerequisiteCheck> upgradeChecks = helper.performChecks(new PrereqCheckRequest("existing"), updateChecksRegistry);
Assert.assertEquals(PrereqCheckStatus.PASS, upgradeChecks.get(0).getStatus());
upgradeChecks = helper.performChecks(new PrereqCheckRequest("non-existing"), updateChecksRegistry);