You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2015/01/02 22:17:35 UTC
ambari git commit: AMBARI-8898. Implement all pre-upgrade checks
(Yurii Shylov via ncole)
Repository: ambari
Updated Branches:
refs/heads/trunk d81bc9b33 -> 64424e6ff
AMBARI-8898. Implement all pre-upgrade checks (Yurii Shylov via ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/64424e6f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/64424e6f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/64424e6f
Branch: refs/heads/trunk
Commit: 64424e6ff3f21f465f3aa479c2af82e427bd1051
Parents: d81bc9b
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Jan 2 15:56:58 2015 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Jan 2 15:56:58 2015 -0500
----------------------------------------------------------------------
.../controller/PreUpgradeCheckRequest.java | 43 ++
.../PreUpgradeCheckResourceProvider.java | 31 +-
.../ambari/server/orm/dao/HostVersionDAO.java | 2 +-
.../ambari/server/state/UpgradeCheckHelper.java | 454 +++++++++++++++++++
.../ambari/server/state/UpgradeChecks.java | 161 -------
.../state/stack/upgrade/UpgradeCheck.java | 2 +-
.../server/state/UpgradeCheckHelperTest.java | 88 ++++
7 files changed, 607 insertions(+), 174 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/ambari-server/src/main/java/org/apache/ambari/server/controller/PreUpgradeCheckRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/PreUpgradeCheckRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/PreUpgradeCheckRequest.java
new file mode 100644
index 0000000..86619e8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/PreUpgradeCheckRequest.java
@@ -0,0 +1,43 @@
+/**
+ * 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.controller;
+
+/**
+ * Represents a pre upgrade request.
+ */
+public class PreUpgradeCheckRequest {
+ private final String clusterName;
+ private String repositoryVersionName;
+
+ //TODO make repositoryVersionName also final as soon as UI will be changed to always provide it to API
+ public PreUpgradeCheckRequest(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public String getRepositoryVersionName() {
+ return repositoryVersionName;
+ }
+
+ public void setRepositoryVersionName(String repositoryVersionName) {
+ this.repositoryVersionName = repositoryVersionName;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/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 0cb20c1..009b5fe 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
@@ -24,6 +24,7 @@ import java.util.Set;
import org.apache.ambari.server.StaticallyInject;
import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.PreUpgradeCheckRequest;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -33,7 +34,7 @@ import org.apache.ambari.server.controller.spi.Resource.Type;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.state.UpgradeChecks;
+import org.apache.ambari.server.state.UpgradeCheckHelper;
import org.apache.ambari.server.state.stack.upgrade.UpgradeCheck;
import com.google.inject.Inject;
@@ -46,13 +47,14 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
//----- Property ID constants ---------------------------------------------
- public static final String UPGRADE_CHECK_ID_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "id");
- public static final String UPGRADE_CHECK_CHECK_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "check");
- public static final String UPGRADE_CHECK_STATUS_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "status");
- public static final String UPGRADE_CHECK_REASON_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "reason");
- public static final String UPGRADE_CHECK_FAILED_ON_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "failed_on");
- public static final String UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "check_type");
- public static final String UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "cluster_name");
+ public static final String UPGRADE_CHECK_ID_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "id");
+ public static final String UPGRADE_CHECK_CHECK_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "check");
+ public static final String UPGRADE_CHECK_STATUS_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "status");
+ public static final String UPGRADE_CHECK_REASON_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "reason");
+ public static final String UPGRADE_CHECK_FAILED_ON_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "failed_on");
+ public static final String UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "check_type");
+ public static final String UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "cluster_name");
+ public static final String UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "repository_version");
@SuppressWarnings("serial")
private static Set<String> pkPropertyIds = new HashSet<String>() {
@@ -71,6 +73,7 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
add(UPGRADE_CHECK_FAILED_ON_PROPERTY_ID);
add(UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID);
add(UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID);
+ add(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID);
}
};
@@ -83,7 +86,7 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
};
@Inject
- private static UpgradeChecks upgradeChecks;
+ private static UpgradeCheckHelper upgradeChecks;
/**
* Constructor.
@@ -104,8 +107,11 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
for (Map<String, Object> propertyMap: propertyMaps) {
final String clusterName = propertyMap.get(UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID).toString();
-
- for (UpgradeCheck upgradeCheck: upgradeChecks.performAll(clusterName)) {
+ final PreUpgradeCheckRequest upgradeCheckRequest = new PreUpgradeCheckRequest(clusterName);
+ if (propertyMap.containsKey(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID)) {
+ upgradeCheckRequest.setRepositoryVersionName(propertyMap.get(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID).toString());
+ }
+ for (UpgradeCheck upgradeCheck: upgradeChecks.performPreUpgradeChecks(upgradeCheckRequest)) {
final Resource resource = new ResourceImpl(Resource.Type.PreUpgradeCheck);
setResourceProperty(resource, UPGRADE_CHECK_ID_PROPERTY_ID, upgradeCheck.getId(), requestedIds);
setResourceProperty(resource, UPGRADE_CHECK_CHECK_PROPERTY_ID, upgradeCheck.getDescription(), requestedIds);
@@ -114,6 +120,9 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
setResourceProperty(resource, UPGRADE_CHECK_FAILED_ON_PROPERTY_ID, upgradeCheck.getFailedOn(), requestedIds);
setResourceProperty(resource, UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID, upgradeCheck.getType(), requestedIds);
setResourceProperty(resource, UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID, upgradeCheck.getClusterName(), requestedIds);
+ if (upgradeCheckRequest.getRepositoryVersionName() != null) {
+ setResourceProperty(resource, UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID, upgradeCheckRequest.getRepositoryVersionName(), requestedIds);
+ }
resources.add(resource);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index 1afc850..ed9fa24 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -128,7 +128,7 @@ public class HostVersionDAO {
* Retrieve the single host version for the given cluster, stack name, stack version, and host name.
*
* @param clusterName Cluster name
- * @param stack Stack name (e.g., HDP)
+ * @param stack Stack name (e.g., HDP-2.2)
* @param version Stack version (e.g., 2.2.0.1-995)
* @param hostName FQDN of host
* @return Returns the single host version that matches the criteria.
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeCheckHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeCheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeCheckHelper.java
new file mode 100644
index 0000000..355532f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeCheckHelper.java
@@ -0,0 +1,454 @@
+/**
+ * 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.state;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ServiceNotFoundException;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.PreUpgradeCheckRequest;
+import org.apache.ambari.server.orm.dao.HostVersionDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.stack.HostsType;
+import org.apache.ambari.server.stack.MasterHostResolver;
+import org.apache.ambari.server.state.HostHealthStatus.HealthStatus;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeCheck;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeCheckStatus;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeCheckType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Manages pre-upgrade checks.
+ */
+@Singleton
+public class UpgradeCheckHelper {
+
+ /**
+ * Log.
+ */
+ private static Logger LOG = LoggerFactory.getLogger(UpgradeCheckHelper.class);
+
+ /**
+ * List of all possible upgrade checks.
+ */
+ final List<UpgradeCheckDescriptor> registry = new ArrayList<UpgradeCheckDescriptor>();
+
+ @Inject
+ Provider<Clusters> clustersProvider;
+
+ @Inject
+ Provider<Configuration> configurationProvider;
+
+ @Inject
+ Provider<HostVersionDAO> hostVersionDaoProvider;
+
+ @Inject
+ Provider<RepositoryVersionDAO> repositoryVersionDaoProvider;
+
+ /**
+ * Constructor. Fills upgrade check registry upon creation.
+ */
+ public UpgradeCheckHelper() {
+ registry.add(new HostsHeartbeatCheck());
+ registry.add(new HostsMasterMaintenanceCheck());
+ registry.add(new HostsRepositoryVersionCheck());
+ registry.add(new ServicesMaintenanceModeCheck());
+ registry.add(new ServicesNamenodeHighAvailabilityCheck());
+ registry.add(new ServicesYarnWorkPreservingCheck());
+ registry.add(new ServicesDecommissionCheck());
+ registry.add(new ServicesJobsDistributedCacheCheck());
+ }
+
+ /**
+ * Executes all registered pre upgrade checks.
+ *
+ * @param request pre upgrade check request
+ * @return list of upgrade check results
+ */
+ public List<UpgradeCheck> performPreUpgradeChecks(PreUpgradeCheckRequest request) {
+ final String clusterName = request.getClusterName();
+ final List<UpgradeCheck> upgradeCheckResults = new ArrayList<UpgradeCheck>();
+ for (UpgradeCheckDescriptor upgradeCheckDescriptor: registry) {
+ final UpgradeCheck upgradeCheck = new UpgradeCheck(
+ upgradeCheckDescriptor.id, upgradeCheckDescriptor.description,
+ upgradeCheckDescriptor.type, clusterName);
+ try {
+ if (upgradeCheckDescriptor.isApplicable(request)) {
+ upgradeCheckDescriptor.perform(upgradeCheck, request);
+ upgradeCheckResults.add(upgradeCheck);
+ }
+ } catch (Exception ex) {
+ LOG.error("Pre-upgrade check " + upgradeCheckDescriptor.id + " failed", ex);
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("Unexpected server error happened");
+ upgradeCheckResults.add(upgradeCheck);
+ }
+ }
+ return upgradeCheckResults;
+ }
+
+ /**
+ * Describes upgrade check.
+ */
+ protected abstract class UpgradeCheckDescriptor {
+
+ private final String id;
+ private final String description;
+ private final UpgradeCheckType type;
+
+ /**
+ * Constructor.
+ *
+ * @param id unique identifier
+ * @param type type
+ * @param description description
+ */
+ public UpgradeCheckDescriptor(String id, UpgradeCheckType type, String description) {
+ this.id = id;
+ this.type = type;
+ this.description = description;
+ }
+
+ /**
+ * Tests if the upgrade check is applicable to given cluster. By default returns true.
+ *
+ * @param request pre upgrade check request
+ * @return true if check should be performed
+ *
+ * @throws AmbariException if server error happens
+ */
+ public boolean isApplicable(PreUpgradeCheckRequest request) throws AmbariException {
+ return true;
+ }
+
+ /**
+ * Executes check against given cluster.
+ *
+ * @param upgradeCheck dto for upgrade check results
+ * @param request pre upgrade check request
+ *
+ * @throws AmbariException if server error happens
+ */
+ public abstract void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException;
+ }
+
+ /**
+ * Checks that services are in the maintenance mode.
+ */
+ protected class ServicesMaintenanceModeCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public ServicesMaintenanceModeCheck() {
+ super("SERVICES_MAINTENANCE_MODE", UpgradeCheckType.SERVICE, "No service can be in maintenance mode");
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ for (Map.Entry<String, Service> serviceEntry : cluster.getServices().entrySet()) {
+ final Service service = serviceEntry.getValue();
+ if (service.getDesiredState() != State.STARTED || service.getMaintenanceState() == MaintenanceState.ON) {
+ upgradeCheck.getFailedOn().add(service.getName());
+ }
+ }
+ if (!upgradeCheck.getFailedOn().isEmpty()) {
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("Some services are in Maintenance Mode");
+ }
+ }
+ }
+
+ /**
+ * Checks that all hosts are either in maintenance mode or heartbeating with the server.
+ */
+ protected class HostsHeartbeatCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public HostsHeartbeatCheck() {
+ super("HOSTS_HEARTBEAT", UpgradeCheckType.HOST, "All hosts must be heartbeating with the server unless they are in Maintenance Mode");
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ final Map<String, Host> clusterHosts = clustersProvider.get().getHostsForCluster(clusterName);
+ for (Map.Entry<String, Host> hostEntry : clusterHosts.entrySet()) {
+ final Host host = hostEntry.getValue();
+ if (host.getHealthStatus().getHealthStatus() == HealthStatus.UNKNOWN && host.getMaintenanceState(cluster.getClusterId()) == MaintenanceState.OFF) {
+ upgradeCheck.getFailedOn().add(host.getHostName());
+ }
+ }
+ if (!upgradeCheck.getFailedOn().isEmpty()) {
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("Some hosts are not heartbeating with the server");
+ }
+ }
+ }
+
+ /**
+ * Checks that all hosts in maintenance state do not have master components.
+ */
+ protected class HostsMasterMaintenanceCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public HostsMasterMaintenanceCheck() {
+ super("HOSTS_MASTER_MAINTENANCE", UpgradeCheckType.HOST, "Hosts in Maintenance Mode must not have any master components");
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ final MasterHostResolver masterHostResolver = new MasterHostResolver(cluster);
+ final Set<String> hostsWithMasterComponent = new HashSet<String>();
+ for (Entry<String, Service> serviceEntry: cluster.getServices().entrySet()) {
+ final Service service = serviceEntry.getValue();
+ for (Entry<String, ServiceComponent> serviceComponentEntry: service.getServiceComponents().entrySet()) {
+ final ServiceComponent serviceComponent = serviceComponentEntry.getValue();
+ final HostsType hostsType = masterHostResolver.getMasterAndHosts(service.getName(), serviceComponent.getName());
+ if (hostsType != null && hostsType.master != null) {
+ hostsWithMasterComponent.add(hostsType.master);
+ }
+ }
+ }
+ final Map<String, Host> clusterHosts = clustersProvider.get().getHostsForCluster(clusterName);
+ for (Map.Entry<String, Host> hostEntry : clusterHosts.entrySet()) {
+ final Host host = hostEntry.getValue();
+ if (host.getMaintenanceState(cluster.getClusterId()) == MaintenanceState.ON && hostsWithMasterComponent.contains(host.getHostName())) {
+ upgradeCheck.getFailedOn().add(host.getHostName());
+ }
+ }
+ if (!upgradeCheck.getFailedOn().isEmpty()) {
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("Some hosts with master components are in Maintenance Mode");
+ }
+ }
+ }
+
+ /**
+ * Checks that all hosts have particular repository version.
+ */
+ protected class HostsRepositoryVersionCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public HostsRepositoryVersionCheck() {
+ super("HOSTS_REPOSITORY_VERSION", UpgradeCheckType.HOST, "Hosts should have the new repository version installed");
+ }
+
+ @Override
+ public boolean isApplicable(PreUpgradeCheckRequest request) throws AmbariException {
+ return request.getRepositoryVersionName() != null;
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ final Map<String, Host> clusterHosts = clustersProvider.get().getHostsForCluster(clusterName);
+ for (Map.Entry<String, Host> hostEntry : clusterHosts.entrySet()) {
+ final Host host = hostEntry.getValue();
+ if (host.getMaintenanceState(cluster.getClusterId()) == MaintenanceState.OFF) {
+ final RepositoryVersionEntity repositoryVersion = repositoryVersionDaoProvider.get().findByDisplayName(request.getRepositoryVersionName());
+ final HostVersionEntity hostVersion = hostVersionDaoProvider.get().findByClusterStackVersionAndHost(clusterName, repositoryVersion.getStack(), repositoryVersion.getVersion(), host.getHostName());
+ if (hostVersion == null || hostVersion.getState() != RepositoryVersionState.INSTALLED) {
+ upgradeCheck.getFailedOn().add(host.getHostName());
+ }
+ }
+ }
+ if (!upgradeCheck.getFailedOn().isEmpty()) {
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("Some hosts do not have repository version " + request.getRepositoryVersionName() + " installed");
+ }
+
+ }
+ }
+
+ /**
+ * Checks that namenode high availability is enabled.
+ */
+ protected class ServicesNamenodeHighAvailabilityCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public ServicesNamenodeHighAvailabilityCheck() {
+ super("SERVICES_NAMENODE_HA", UpgradeCheckType.SERVICE, "Namenode high availability should be enabled");
+ }
+
+ @Override
+ public boolean isApplicable(PreUpgradeCheckRequest request) throws AmbariException {
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ return cluster.getService("HDFS") != null;
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ final String configType = "hdfs-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("dfs.nameservices")) {
+ upgradeCheck.getFailedOn().add("HDFS");
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("Namenode high availability is disabled");
+ }
+ }
+ }
+
+ /**
+ * Checks that YARN has work-preserving restart enabled.
+ */
+ protected class ServicesYarnWorkPreservingCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public ServicesYarnWorkPreservingCheck() {
+ super("SERVICES_YARN_WP", UpgradeCheckType.SERVICE, "YARN work preserving restart should be enabled");
+ }
+
+ @Override
+ public boolean isApplicable(PreUpgradeCheckRequest request) throws AmbariException {
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ try {
+ cluster.getService("YARN");
+ } catch (ServiceNotFoundException ex) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest 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") ||
+ !Boolean.getBoolean(config.getProperties().get("yarn.resourcemanager.work-preserving-recovery.enabled"))) {
+ upgradeCheck.getFailedOn().add("YARN");
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("YARN doesn't have work preserving restart, yarn.resourcemanager.work-preserving-recovery.enabled property is missing");
+ }
+ }
+ }
+
+ /**
+ * Checks that there are no services in decommission state.
+ */
+ protected class ServicesDecommissionCheck extends UpgradeCheckDescriptor {
+
+ /**
+ * Constructor.
+ */
+ public ServicesDecommissionCheck() {
+ super("SERVICES_DECOMMISSION", UpgradeCheckType.SERVICE, "Services should not be in Decommission state");
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ for (Entry<String, Service> serviceEntry: cluster.getServices().entrySet()) {
+ final Service service = serviceEntry.getValue();
+ for (Entry<String, ServiceComponent> serviceComponentEntry: service.getServiceComponents().entrySet()) {
+ final ServiceComponent serviceComponent = serviceComponentEntry.getValue();
+ for (String hostName : serviceComponent.getServiceComponentHosts().keySet()) {
+ final ServiceComponentHost scHost = serviceComponent.getServiceComponentHost(hostName);
+ if (scHost.getComponentAdminState() == HostComponentAdminState.DECOMMISSIONED || scHost.getComponentAdminState() == HostComponentAdminState.DECOMMISSIONING) {
+ upgradeCheck.getFailedOn().add(serviceComponent.getName());
+ }
+ }
+ }
+ }
+ if (!upgradeCheck.getFailedOn().isEmpty()) {
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("There are services in decommission or decommissioning state");
+ }
+ }
+ }
+
+ /**
+ * Checks that MR, Oozie and Tez jobs reference hadoop libraries from the distributed cache.
+ */
+ protected class ServicesJobsDistributedCacheCheck extends UpgradeCheckDescriptor {
+
+ @Override
+ public boolean isApplicable(PreUpgradeCheckRequest request)
+ throws AmbariException {
+ final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+ try {
+ cluster.getService("YARN");
+ } catch (ServiceNotFoundException ex) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Constructor.
+ */
+ public ServicesJobsDistributedCacheCheck() {
+ super("SERVICES_JOBS_DISTRIBUTED_CACHE", UpgradeCheckType.SERVICE, "Jobs should reference hadoop libraries from the distributed cache");
+ }
+
+ @Override
+ public void perform(UpgradeCheck upgradeCheck, PreUpgradeCheckRequest request) throws AmbariException {
+ final String clusterName = request.getClusterName();
+ final Cluster cluster = clustersProvider.get().getCluster(clusterName);
+ final String configType = "mapred-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("mapreduce.application.framework.path") || !config.getProperties().containsKey("mapreduce.application.classpath")) {
+ // TODO actually it is needed to validate that these properties contain proper values but the tickets for these changes are still open, so it will cause
+ // preupgrade checks to fail
+ upgradeCheck.getFailedOn().add("MR");
+ upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
+ upgradeCheck.setFailReason("mapreduce.application.framework.path and mapreduce.application.classpath should reference distributed cache");
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeChecks.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeChecks.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeChecks.java
deleted file mode 100644
index 83cd632..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeChecks.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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.state;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.state.HostHealthStatus.HealthStatus;
-import org.apache.ambari.server.state.stack.upgrade.UpgradeCheck;
-import org.apache.ambari.server.state.stack.upgrade.UpgradeCheckStatus;
-import org.apache.ambari.server.state.stack.upgrade.UpgradeCheckType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-
-/**
- * Manages pre-upgrade checks.
- */
-@Singleton
-public class UpgradeChecks {
-
- /**
- * Log.
- */
- private static Logger LOG = LoggerFactory.getLogger(UpgradeChecks.class);
-
- /**
- * List of all possible upgrade checks.
- */
- private static final List<UpgradeCheckDescriptor> UPGRADE_CHECK_REGISTRY = new ArrayList<UpgradeCheckDescriptor>();
-
- @Inject
- Provider<Clusters> clustersProvider;
-
- /**
- * Constructor. Fills upgrade check registry upon creation.
- */
- public UpgradeChecks() {
- UPGRADE_CHECK_REGISTRY.add(new UpgradeCheckDescriptor() {
-
- @Override
- public UpgradeCheck perform(String clusterName) {
- final UpgradeCheck upgradeCheck = new UpgradeCheck(
- "SERVICES_MAINTENANCE_MODE",
- "All services must not be in Maintenance Mode",
- UpgradeCheckType.SERVICE,
- clusterName);
-
- try {
- final Cluster cluster = clustersProvider.get().getCluster(clusterName);
- for (Map.Entry<String, Service> serviceEntry: cluster.getServices().entrySet()) {
- final Service service = serviceEntry.getValue();
- if (service.getMaintenanceState() == MaintenanceState.ON) {
- upgradeCheck.getFailedOn().add(service.getName());
- }
- }
- if (upgradeCheck.getFailedOn().isEmpty()) {
- upgradeCheck.setStatus(UpgradeCheckStatus.PASS);
- } else {
- upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
- upgradeCheck.setFailReason("Some services are in Maintenance Mode");
- }
- } catch (AmbariException ex) {
- LOG.error("Pre-upgrade check " + upgradeCheck.getId() + " failed", ex);
- upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
- upgradeCheck.setFailReason("Unexpected server error happened");
- }
-
- return upgradeCheck;
- }
- });
-
- UPGRADE_CHECK_REGISTRY.add(new UpgradeCheckDescriptor() {
-
- @Override
- public UpgradeCheck perform(String clusterName) {
- final UpgradeCheck upgradeCheck = new UpgradeCheck(
- "HOST_HEARTBEAT",
- "All hosts must be heartbeating with the server unless they are in Maintenance Mode",
- UpgradeCheckType.HOST,
- clusterName);
-
- try {
- final Map<String, Host> clusterHosts = clustersProvider.get().getHostsForCluster(clusterName);
- for (Map.Entry<String, Host> hostEntry: clusterHosts.entrySet()) {
- final Host host = hostEntry.getValue();
- if (host.getHealthStatus().getHealthStatus() == HealthStatus.UNKNOWN) {
- upgradeCheck.getFailedOn().add(host.getHostName());
- }
- }
- if (upgradeCheck.getFailedOn().isEmpty()) {
- upgradeCheck.setStatus(UpgradeCheckStatus.PASS);
- } else {
- upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
- upgradeCheck.setFailReason("Some hosts are not heartbeating with the server");
- }
- } catch (AmbariException ex) {
- LOG.error("Pre-upgrade check " + upgradeCheck.getId() + " failed", ex);
- upgradeCheck.setStatus(UpgradeCheckStatus.FAIL);
- upgradeCheck.setFailReason("Unexpected server error happened");
- }
-
- return upgradeCheck;
- }
- });
- }
-
- public List<UpgradeCheck> performAll(String clusterName) {
- final List<UpgradeCheck> upgradeCheckResults = new ArrayList<UpgradeCheck>();
- for (UpgradeCheckDescriptor upgradeCheck: UPGRADE_CHECK_REGISTRY) {
- if (upgradeCheck.isApplicable()) {
- upgradeCheckResults.add(upgradeCheck.perform(clusterName));
- }
- }
- return upgradeCheckResults;
- }
-
- /**
- * Describes upgrade check.
- */
- private abstract class UpgradeCheckDescriptor {
-
- /**
- * By default returns true.
- *
- * @return true if check should be performed
- */
- public boolean isApplicable() {
- return true;
- }
-
- /**
- * Executes check against given cluster.
- *
- * @param clusterName cluster name
- * @return the results of the check
- */
- public abstract UpgradeCheck perform(String clusterName);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheck.java
index 0d85a93..80c4bbf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheck.java
@@ -29,7 +29,7 @@ public class UpgradeCheck {
private final String description;
private final UpgradeCheckType type;
private final String clusterName;
- private UpgradeCheckStatus status;
+ private UpgradeCheckStatus status = UpgradeCheckStatus.PASS;
private String failReason = "";
private List<String> failedOn = new ArrayList<String>();
http://git-wip-us.apache.org/repos/asf/ambari/blob/64424e6f/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeCheckHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeCheckHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeCheckHelperTest.java
new file mode 100644
index 0000000..2cbe088
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeCheckHelperTest.java
@@ -0,0 +1,88 @@
+/**
+ * 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.state;
+
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PreUpgradeCheckRequest;
+import org.apache.ambari.server.state.UpgradeCheckHelper.UpgradeCheckDescriptor;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeCheck;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeCheckStatus;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+/**
+ * Tests the {@link UpgradeCheckHelper} class
+ */
+public class UpgradeCheckHelperTest {
+
+ /**
+ * Makes sure that people don't forget to add new checks to registry.
+ */
+ @Test
+ public void defaultConstructorTest() throws Exception {
+ final UpgradeCheckHelper helper = new UpgradeCheckHelper();
+
+ Assert.assertEquals(UpgradeCheckHelper.class.getDeclaredClasses().length - 1, helper.registry.size());
+ }
+
+ @Test
+ public void performPreUpgradeChecksTest_ok() throws Exception {
+ final UpgradeCheckHelper helper = new UpgradeCheckHelper();
+ helper.registry.clear();
+ UpgradeCheckDescriptor descriptor = EasyMock.createNiceMock(UpgradeCheckDescriptor.class);
+ descriptor.perform(EasyMock.<UpgradeCheck> anyObject(), EasyMock.<PreUpgradeCheckRequest> anyObject());
+ EasyMock.expectLastCall().times(1);
+ EasyMock.expect(descriptor.isApplicable(EasyMock.<PreUpgradeCheckRequest> anyObject())).andReturn(true);
+ EasyMock.replay(descriptor);
+ helper.registry.add(descriptor);
+ helper.performPreUpgradeChecks(new PreUpgradeCheckRequest("cluster"));
+ EasyMock.verify(descriptor);
+ }
+
+ @Test
+ public void performPreUpgradeChecksTest_notApplicable() throws Exception {
+ final UpgradeCheckHelper helper = new UpgradeCheckHelper();
+ helper.registry.clear();
+ UpgradeCheckDescriptor descriptor = EasyMock.createNiceMock(UpgradeCheckDescriptor.class);
+ EasyMock.expect(descriptor.isApplicable(EasyMock.<PreUpgradeCheckRequest> anyObject())).andReturn(false);
+ EasyMock.replay(descriptor);
+ helper.registry.add(descriptor);
+ helper.performPreUpgradeChecks(new PreUpgradeCheckRequest("cluster"));
+ EasyMock.verify(descriptor);
+ }
+
+ @Test
+ public void performPreUpgradeChecksTest_throwsException() throws Exception {
+ final UpgradeCheckHelper helper = new UpgradeCheckHelper();
+ helper.registry.clear();
+ UpgradeCheckDescriptor descriptor = EasyMock.createNiceMock(UpgradeCheckDescriptor.class);
+ descriptor.perform(EasyMock.<UpgradeCheck> anyObject(), EasyMock.<PreUpgradeCheckRequest> anyObject());
+ EasyMock.expectLastCall().andThrow(new AmbariException("error"));
+ EasyMock.expect(descriptor.isApplicable(EasyMock.<PreUpgradeCheckRequest> anyObject())).andReturn(true);
+ EasyMock.replay(descriptor);
+ helper.registry.add(descriptor);
+ final List<UpgradeCheck> upgradeChecks = helper.performPreUpgradeChecks(new PreUpgradeCheckRequest("cluster"));
+ EasyMock.verify(descriptor);
+ Assert.assertEquals(UpgradeCheckStatus.FAIL, upgradeChecks.get(0).getStatus());
+ }
+
+}