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 2014/12/15 20:35:27 UTC

ambari git commit: AMBARI-8540. Upgrade Execute: add an endpoint to do pre-requisite checks (Yurii Shylov via ncole)

Repository: ambari
Updated Branches:
  refs/heads/trunk 2ccfa617a -> 190176e61


AMBARI-8540. Upgrade Execute: add an endpoint to do pre-requisite 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/190176e6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/190176e6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/190176e6

Branch: refs/heads/trunk
Commit: 190176e6174b7d610d1a9f26cda91662ad8171ff
Parents: 2ccfa61
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Dec 15 14:12:23 2014 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Dec 15 14:12:23 2014 -0500

----------------------------------------------------------------------
 .../resources/ResourceInstanceFactoryImpl.java  |   4 +
 .../server/api/services/ClusterService.java     |  14 ++
 .../api/services/PreUpgradeCheckService.java    |  73 +++++++++
 .../internal/DefaultProviderModule.java         |   2 +
 .../PreUpgradeCheckResourceProvider.java        | 129 +++++++++++++++
 .../ambari/server/controller/spi/Resource.java  |   2 +
 .../ambari/server/state/UpgradeChecks.java      | 161 +++++++++++++++++++
 .../state/stack/upgrade/UpgradeCheck.java       |  82 ++++++++++
 .../state/stack/upgrade/UpgradeCheckStatus.java |  26 +++
 .../state/stack/upgrade/UpgradeCheckType.java   |  27 ++++
 .../server/api/services/ClusterServiceTest.java |  12 +-
 .../services/PreUpgradeCheckServiceTest.java    |  82 ++++++++++
 12 files changed, 610 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index a353be6..e55b2cb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -334,6 +334,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
             Resource.Type.UpgradeItem, "upgrade_item", "upgrade_items", Resource.Type.Task);
         break;
 
+      case PreUpgradeCheck:
+        resourceDefinition = new SimpleResourceDefinition(Resource.Type.PreUpgradeCheck, "rolling_upgrade_check", "rolling_upgrade_checks");
+        break;
+
       case Stage:
         resourceDefinition = new SimpleResourceDefinition(Resource.Type.Stage, "stage", "stages", Resource.Type.Task);
         break;

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index e950d57..ead49ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -447,6 +447,20 @@ public class ClusterService extends BaseService {
     return new UpgradeService(clusterName);
   }
 
+  /**
+   * Gets the pre-upgrade checks service.
+   *
+   * @param request the request
+   * @param clusterName the cluster name
+   *
+   * @return the pre-upgrade checks service.
+   */
+  @Path("{clusterName}/rolling_upgrades_check")
+  public PreUpgradeCheckService getPreUpgradeCheckService(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+    hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
+    return new PreUpgradeCheckService(clusterName);
+  }
+
   // ----- helper methods ----------------------------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/api/services/PreUpgradeCheckService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/PreUpgradeCheckService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/PreUpgradeCheckService.java
new file mode 100644
index 0000000..0525b3a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/PreUpgradeCheckService.java
@@ -0,0 +1,73 @@
+/**
+ * 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.api.services;
+
+import java.util.Collections;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Service responsible for cluster pre-upgrade checks.
+ */
+public class PreUpgradeCheckService extends BaseService {
+
+  /**
+   * Cluster name.
+   */
+  private String clusterName = null;
+
+  /**
+   * Constructor.
+   *
+   * @param clusterName cluster name
+   */
+  public PreUpgradeCheckService(String clusterName) {
+    this.clusterName = clusterName;
+  }
+
+  /**
+   * Handles GET /rolling_upgrades_check request.
+   *
+   * @param body body
+   * @param headers headers
+   * @param ui uri info
+   * @return information about upgrade checks
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getPreUpgradeChecks(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, body, ui, Request.Type.GET, createResource());
+  }
+
+  /**
+   * Creates an upgrade check resource instance.
+   *
+   * @return an upgrade check resource instance
+   */
+  private ResourceInstance createResource() {
+    return createResource(Resource.Type.PreUpgradeCheck, Collections.singletonMap(Resource.Type.Cluster, clusterName));
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
index 41bee76..be2a9ad 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
@@ -104,6 +104,8 @@ public class DefaultProviderModule extends AbstractProviderModule {
         return new UpgradeItemResourceProvider(managementController);
       case ClusterStackVersion:
         return new ClusterStackVersionResourceProvider(managementController);
+      case PreUpgradeCheck:
+        return new PreUpgradeCheckResourceProvider(managementController);
       case HostStackVersion:
         return new HostStackVersionResourceProvider(managementController);
       case Stage:

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/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
new file mode 100644
index 0000000..0cb20c1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
@@ -0,0 +1,129 @@
+/**
+ * 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.internal;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+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.stack.upgrade.UpgradeCheck;
+
+import com.google.inject.Inject;
+
+/**
+ * Resource provider for pre-upgrade checks.
+ */
+@StaticallyInject
+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");
+
+  @SuppressWarnings("serial")
+  private static Set<String> pkPropertyIds = new HashSet<String>() {
+    {
+      add(UPGRADE_CHECK_ID_PROPERTY_ID);
+    }
+  };
+
+  @SuppressWarnings("serial")
+  public static Set<String> propertyIds = new HashSet<String>() {
+    {
+      add(UPGRADE_CHECK_ID_PROPERTY_ID);
+      add(UPGRADE_CHECK_CHECK_PROPERTY_ID);
+      add(UPGRADE_CHECK_STATUS_PROPERTY_ID);
+      add(UPGRADE_CHECK_REASON_PROPERTY_ID);
+      add(UPGRADE_CHECK_FAILED_ON_PROPERTY_ID);
+      add(UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID);
+      add(UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID);
+    }
+  };
+
+  @SuppressWarnings("serial")
+  public static Map<Type, String> keyPropertyIds = new HashMap<Type, String>() {
+    {
+      put(Type.PreUpgradeCheck, UPGRADE_CHECK_ID_PROPERTY_ID);
+      put(Type.Cluster, UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID);
+    }
+  };
+
+  @Inject
+  private static UpgradeChecks upgradeChecks;
+
+  /**
+   * Constructor.
+   *
+   * @param managementController management controller
+   */
+  public PreUpgradeCheckResourceProvider(AmbariManagementController managementController) {
+    super(propertyIds, keyPropertyIds, managementController);
+  }
+
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    final Set<Resource> resources = new HashSet<Resource>();
+    final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+    final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+
+    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 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);
+        setResourceProperty(resource, UPGRADE_CHECK_STATUS_PROPERTY_ID, upgradeCheck.getStatus(), requestedIds);
+        setResourceProperty(resource, UPGRADE_CHECK_REASON_PROPERTY_ID, upgradeCheck.getFailReason(), requestedIds);
+        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);
+        resources.add(resource);
+      }
+    }
+
+    return resources;
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 5c9366a..89d6837 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -134,6 +134,7 @@ public interface Resource {
     Upgrade,
     UpgradeGroup,
     UpgradeItem,
+    PreUpgradeCheck,
     Stage;
 
     /**
@@ -229,6 +230,7 @@ public interface Resource {
     public static final Type Upgrade = InternalType.Upgrade.getType();
     public static final Type UpgradeGroup = InternalType.UpgradeGroup.getType();
     public static final Type UpgradeItem = InternalType.UpgradeItem.getType();
+    public static final Type PreUpgradeCheck = InternalType.PreUpgradeCheck.getType();
     public static final Type Stage = InternalType.Stage.getType();
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/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
new file mode 100644
index 0000000..83cd632
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeChecks.java
@@ -0,0 +1,161 @@
+/**
+ * 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/190176e6/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
new file mode 100644
index 0000000..0d85a93
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheck.java
@@ -0,0 +1,82 @@
+/**
+ * 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.stack.upgrade;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contains information about performed upgrade check.
+ *
+ */
+public class UpgradeCheck {
+  private final String id;
+  private final String description;
+  private final UpgradeCheckType type;
+  private final String clusterName;
+  private UpgradeCheckStatus status;
+  private String failReason = "";
+  private List<String> failedOn = new ArrayList<String>();
+
+  public UpgradeCheck(String id, String description, UpgradeCheckType type, String clusterName) {
+    this.id = id;
+    this.description = description;
+    this.type = type;
+    this.clusterName = clusterName;
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public UpgradeCheckStatus getStatus() {
+    return status;
+  }
+
+  public void setStatus(UpgradeCheckStatus status) {
+    this.status = status;
+  }
+
+  public String getFailReason() {
+    return failReason;
+  }
+
+  public void setFailReason(String failReason) {
+    this.failReason = failReason;
+  }
+
+  public List<String> getFailedOn() {
+    return failedOn;
+  }
+
+  public void setFailedOn(List<String> failedOn) {
+    this.failedOn = failedOn;
+  }
+
+  public UpgradeCheckType getType() {
+    return type;
+  }
+
+  public String getClusterName() {
+    return clusterName;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckStatus.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckStatus.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckStatus.java
new file mode 100644
index 0000000..ee70525
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckStatus.java
@@ -0,0 +1,26 @@
+/**
+ * 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.stack.upgrade;
+
+/**
+ * Indicates status of upgrade check.
+ */
+public enum UpgradeCheckStatus {
+  PASS,
+  FAIL
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckType.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckType.java
new file mode 100644
index 0000000..dfef47e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeCheckType.java
@@ -0,0 +1,27 @@
+/**
+ * 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.stack.upgrade;
+
+/**
+ * Type of upgrade check.
+ */
+public enum UpgradeCheckType {
+  SERVICE,
+  HOST,
+  CLUSTER
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/test/java/org/apache/ambari/server/api/services/ClusterServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ClusterServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ClusterServiceTest.java
index 9051059..c8f020e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ClusterServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ClusterServiceTest.java
@@ -33,21 +33,25 @@ import java.util.List;
 
 import static org.junit.Assert.assertEquals;
 
-
 /**
  * Unit tests for ClusterService.
  */
 public class ClusterServiceTest extends BaseServiceTest {
 
 
+  @Override
   public List<ServiceTestInvocation> getTestInvocations() throws Exception {
     List<ServiceTestInvocation> listInvocations = new ArrayList<ServiceTestInvocation>();
     Clusters clusters = new TestClusters();
 
+    ClusterService clusterService;
+    Method m;
+    Object[] args;
+
     //getCluster
-    ClusterService clusterService = new TestClusterService(clusters, "clusterName");
-    Method m = clusterService.getClass().getMethod("getCluster", String.class, HttpHeaders.class, UriInfo.class, String.class);
-    Object[] args = new Object[] {null, getHttpHeaders(), getUriInfo(), "clusterName"};
+    clusterService = new TestClusterService(clusters, "clusterName");
+    m = clusterService.getClass().getMethod("getCluster", String.class, HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {null, getHttpHeaders(), getUriInfo(), "clusterName"};
     listInvocations.add(new ServiceTestInvocation(Request.Type.GET, clusterService, m, args, null));
 
     //getClusters

http://git-wip-us.apache.org/repos/asf/ambari/blob/190176e6/ambari-server/src/test/java/org/apache/ambari/server/api/services/PreUpgradeCheckServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/PreUpgradeCheckServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/PreUpgradeCheckServiceTest.java
new file mode 100644
index 0000000..f851133
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/PreUpgradeCheckServiceTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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.api.services;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
+import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+
+/**
+ * Unit tests for PreUpgradeCheckService.
+ */
+public class PreUpgradeCheckServiceTest extends BaseServiceTest {
+
+  @Override
+  public List<ServiceTestInvocation> getTestInvocations() throws Exception {
+    List<ServiceTestInvocation> listInvocations = new ArrayList<ServiceTestInvocation>();
+
+    PreUpgradeCheckService service;
+    Method m;
+    Object[] args;
+
+    //getPreUpgradeChecks
+    service = new TestPreUpgradeCheckService("cluster");
+    m = service.getClass().getMethod("getPreUpgradeChecks", String.class, HttpHeaders.class, UriInfo.class);
+    args = new Object[] {"body", getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, "body"));
+
+    return listInvocations;
+  }
+
+  private class TestPreUpgradeCheckService extends PreUpgradeCheckService {
+
+    public TestPreUpgradeCheckService(String clusterName) {
+      super(clusterName);
+    }
+
+    @Override
+    protected ResourceInstance createResource(Type type, Map<Type, String> mapIds) {
+      return getTestResource();
+    }
+
+    @Override
+    RequestFactory getRequestFactory() {
+      return getTestRequestFactory();
+    }
+
+    @Override
+    protected RequestBodyParser getBodyParser() {
+      return getTestBodyParser();
+    }
+
+    @Override
+    protected ResultSerializer getResultSerializer() {
+      return getTestResultSerializer();
+    }
+  }
+}
\ No newline at end of file