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

amagyar pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new ba010cf  [AMBARI-23553]. Unable to delete Slider after Ambari upgrade, 
due to Hive dependency (amagyar) (#1039)
ba010cf is described below

commit ba010cfa0c7813a6bf2730b95192d6d705e171b8
Author: Attila Magyar <[email protected]>
AuthorDate: Thu Apr 19 16:14:28 2018 +0200

    [AMBARI-23553]. Unable to delete Slider after Ambari upgrade, due to Hive 
dependency (amagyar) (#1039)
    
    * AMBARI-23553. Unable to delete Slider after Ambari upgrade, due to Hive 
dependency (amagyar)
    
    * AMBARI-23553. Unable to delete Slider after Ambari upgrade, due to Hive 
dependency (amagyar)
    
    * AMBARI-23553. Unable to delete Slider after Ambari upgrade, due to Hive 
dependency (amagyar)
    
    * AMBARI-23553. Unable to delete Slider after Ambari upgrade, due to Hive 
dependency (amagyar)
    
    * AMBARI-23553. Unable to delete Slider after Ambari upgrade, due to Hive 
dependency (amagyar)
---
 .../ambari/server/checks/CheckDescription.java     |  14 +-
 .../server/checks/ComponentsExistInRepoCheck.java  | 151 +++------
 .../server/controller/PrereqCheckRequest.java      |  11 +
 .../ambari/server/orm/entities/UpgradeEntity.java  |   9 +
 .../DeleteUnsupportedServicesAndComponents.java    |  95 ++++++
 .../apache/ambari/server/state/ConfigHelper.java   |   6 +-
 .../ambari/server/state/ConfigMergeHelper.java     |  15 +-
 .../server/state/ServiceComponentSupport.java      | 108 ++++++
 .../ambari/server/state/stack/UpgradePack.java     |   2 +-
 .../state/stack/upgrade/ServerSideActionTask.java  |   4 +
 .../checks/ComponentExistsInRepoCheckTest.java     | 366 ++++-----------------
 .../server/state/ServiceComponentSupportTest.java  | 118 +++++++
 12 files changed, 491 insertions(+), 408 deletions(-)

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 fa9e583..0946f6b 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
@@ -343,11 +343,13 @@ public class CheckDescription {
           .build());
 
   public static CheckDescription COMPONENTS_EXIST_IN_TARGET_REPO = new 
CheckDescription("COMPONENTS_EXIST_IN_TARGET_REPO",
-      PrereqCheckType.CLUSTER,
-      "Verify Cluster Components Exist In Target Repository",
-      new ImmutableMap.Builder<String, String>()
-        .put(AbstractCheckDescriptor.DEFAULT, "The following components do not 
exist in the target repository's stack. They must be removed from the cluster 
before upgrading.")
-          .build());
+    PrereqCheckType.CLUSTER,
+    "Check installed services which are not supported in the installed stack",
+    new ImmutableMap.Builder<String, String>()
+      .put(ComponentsExistInRepoCheck.AUTO_REMOVE, "The following services 
and/or components do not exist in the target stack and will be automatically 
removed during the upgrade.")
+      .put(ComponentsExistInRepoCheck.MANUAL_REMOVE, "The following components 
do not exist in the target repository's stack. They must be removed from the 
cluster before upgrading.")
+      .build()
+    );
 
   public static CheckDescription DRUID_HA_WARNING = new CheckDescription(
       "DRUID_HA",
@@ -360,7 +362,7 @@ public class CheckDescription {
           )
           .build()
   );
-  
+
   public static CheckDescription VALID_SERVICES_INCLUDED_IN_REPOSITORY = new 
CheckDescription("VALID_SERVICES_INCLUDED_IN_REPOSITORY",
       PrereqCheckType.CLUSTER,
       "The repository is missing services which are required",
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsExistInRepoCheck.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsExistInRepoCheck.java
index 17630b1..a64d381 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsExistInRepoCheck.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsExistInRepoCheck.java
@@ -17,28 +17,24 @@
  */
 package org.apache.ambari.server.checks;
 
-import java.text.MessageFormat;
+import java.util.Collection;
 import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.stream.Collectors;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.StackAccessException;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
-import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import 
org.apache.ambari.server.serveraction.upgrades.DeleteUnsupportedServicesAndComponents;
 import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceInfo;
-import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.ServiceComponentSupport;
+import org.apache.ambari.server.state.UpgradeHelper;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.ambari.server.state.stack.UpgradePack;
+import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping;
+import org.apache.ambari.server.state.stack.upgrade.ServerActionTask;
+import org.apache.ambari.server.state.stack.upgrade.Task;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
-import org.apache.commons.lang.StringUtils;
 
+import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
 /**
@@ -48,105 +44,64 @@ import com.google.inject.Singleton;
  */
 @Singleton
 @UpgradeCheck(
-    group = UpgradeCheckGroup.TOPOLOGY,
-    required = { UpgradeType.ROLLING, UpgradeType.NON_ROLLING, 
UpgradeType.HOST_ORDERED })
+  group = UpgradeCheckGroup.INFORMATIONAL_WARNING,
+  required = { UpgradeType.ROLLING, UpgradeType.NON_ROLLING })
 public class ComponentsExistInRepoCheck extends AbstractCheckDescriptor {
+  public static final String AUTO_REMOVE = "auto_remove";
+  public static final String MANUAL_REMOVE = "manual_remove";
+  @Inject
+  ServiceComponentSupport serviceComponentSupport;
+  @Inject
+  UpgradeHelper upgradeHelper;
 
-  /**
-   * Constructor.
-   */
   public ComponentsExistInRepoCheck() {
     super(CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO);
   }
 
   @Override
-  public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest 
request)
-      throws AmbariException {
-    final String clusterName = request.getClusterName();
-    final Cluster cluster = clustersProvider.get().getCluster(clusterName);
-    RepositoryVersionEntity repositoryVersion = 
request.getTargetRepositoryVersion();
-
-    StackId sourceStack = request.getSourceStackId();
-    StackId targetStack = repositoryVersion.getStackId();
-
-    Set<ServiceDetail> failedServices = new TreeSet<>();
-    Set<ServiceComponentDetail> failedComponents = new TreeSet<>();
-
-    Set<String> servicesInUpgrade = getServicesInUpgrade(request);
-    for (String serviceName : servicesInUpgrade) {
-      try {
-        ServiceInfo serviceInfo = 
ambariMetaInfo.get().getService(targetStack.getStackName(),
-            targetStack.getStackVersion(), serviceName);
-
-        if (serviceInfo.isDeleted() || !serviceInfo.isValid()) {
-          failedServices.add(new ServiceDetail(serviceName));
-          continue;
-        }
-
-        Service service = cluster.getService(serviceName);
-        Map<String, ServiceComponent> componentsInUpgrade = 
service.getServiceComponents();
-        for (String componentName : componentsInUpgrade.keySet()) {
-          try {
-            ComponentInfo componentInfo = ambariMetaInfo.get().getComponent(
-                targetStack.getStackName(), targetStack.getStackVersion(), 
serviceName,
-                componentName);
-
-            // if this component isn't included in the upgrade, then skip it
-            if (!componentInfo.isVersionAdvertised()) {
-              continue;
-            }
-
-            if (componentInfo.isDeleted()) {
-              failedComponents.add(new ServiceComponentDetail(serviceName, 
componentName));
-            }
-
-          } catch (StackAccessException stackAccessException) {
-            failedComponents.add(new ServiceComponentDetail(serviceName, 
componentName));
-          }
-        }
-      } catch (StackAccessException stackAccessException) {
-        failedServices.add(new ServiceDetail(serviceName));
-      }
-    }
+  public void perform(PrerequisiteCheck check, PrereqCheckRequest request) 
throws AmbariException {
+    Cluster cluster = 
clustersProvider.get().getCluster(request.getClusterName());
+    String stackName = request.getTargetRepositoryVersion().getStackName();
+    String stackVersion = 
request.getTargetRepositoryVersion().getStackVersion();
+    Collection<String> allUnsupported = 
serviceComponentSupport.allUnsupported(cluster, stackName, stackVersion);
+    report(check, request, allUnsupported);
+  }
 
-    if (failedServices.isEmpty() && failedComponents.isEmpty()) {
+  private void report(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest 
request, Collection<String> allUnsupported) throws AmbariException {
+    if (allUnsupported.isEmpty()) {
       prerequisiteCheck.setStatus(PrereqCheckStatus.PASS);
       return;
     }
-
-    Set<String> failedServiceNames = failedServices.stream().map(
-        failureDetail -> failureDetail.serviceName).collect(
-            Collectors.toCollection(LinkedHashSet::new));
-
-    Set<String> failedComponentNames = failedComponents.stream().map(
-        failureDetail -> failureDetail.componentName).collect(
-            Collectors.toCollection(LinkedHashSet::new));
-
-    LinkedHashSet<String> failures = new LinkedHashSet<>();
-    failures.addAll(failedServiceNames);
-    failures.addAll(failedComponentNames);
-
-    prerequisiteCheck.setFailedOn(failures);
-    prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
-
-    prerequisiteCheck.getFailedDetail().addAll(failedServices);
-    prerequisiteCheck.getFailedDetail().addAll(failedComponents);
-
-    String message = "The following {0} exist in {1} but are not included in 
{2}. They must be removed before upgrading.";
-    String messageFragment = "";
-    if (!failedServices.isEmpty()) {
-      messageFragment = "services";
+    prerequisiteCheck.setFailedOn(new LinkedHashSet<>(allUnsupported));
+    if (hasDeleteUnsupportedServicesAction(upgradePack(request))) {
+      prerequisiteCheck.setStatus(PrereqCheckStatus.WARNING);
+      prerequisiteCheck.setFailReason(getFailReason(AUTO_REMOVE, 
prerequisiteCheck, request));
+    } else {
+      prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
+      prerequisiteCheck.setFailReason(getFailReason(MANUAL_REMOVE, 
prerequisiteCheck, request));
     }
+  }
 
-    if( !failedComponents.isEmpty() ){
-      if(!StringUtils.isEmpty(messageFragment)){
-        messageFragment += " and ";
-      }
+  private UpgradePack upgradePack(PrereqCheckRequest request) throws 
AmbariException {
+    return upgradeHelper.suggestUpgradePack(
+      request.getClusterName(),
+      request.getSourceStackId(),
+      request.getTargetRepositoryVersion().getStackId(),
+      request.getDirection(),
+      request.getUpgradeType(),
+      null);
+  }
 
-      messageFragment += "components";
-    }
+  private boolean hasDeleteUnsupportedServicesAction(UpgradePack upgradePack) {
+    return upgradePack.getAllGroups().stream()
+      .filter(ClusterGrouping.class::isInstance)
+      .flatMap(group -> ((ClusterGrouping) group).executionStages.stream())
+      .map(executeStage -> executeStage.task)
+      .anyMatch(this::isDeleteUnsupportedTask);
+  }
 
-    message = MessageFormat.format(message, messageFragment, sourceStack, 
targetStack);
-    prerequisiteCheck.setFailReason(message);
+  private boolean isDeleteUnsupportedTask(Task task) {
+    return task instanceof ServerActionTask
+      && 
DeleteUnsupportedServicesAndComponents.class.getName().equals(((ServerActionTask)task).getImplementationClass());
   }
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
index 6d9f655..40e21e5 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
@@ -25,6 +25,7 @@ import 
org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import 
org.apache.ambari.server.state.stack.UpgradePack.PrerequisiteCheckConfig;
+import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
 /**
@@ -150,4 +151,14 @@ public class PrereqCheckRequest {
   public boolean isRevert() {
     return m_revert;
   }
+
+  public Direction getDirection() {
+    int direction = 
m_sourceStackId.compareTo(m_targetRepositoryVersion.getStackId());
+    if (direction < 0) {
+      return Direction.UPGRADE;
+    } else if (direction > 0) {
+      return Direction.DOWNGRADE;
+    }
+    throw new RuntimeException("Invalid upgrade direction. Source and target 
version is the same.");
+  }
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
index 1361c94..ef2e45a 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
@@ -18,6 +18,7 @@
 package org.apache.ambari.server.orm.entities;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import javax.persistence.CascadeType;
@@ -498,4 +499,12 @@ public class UpgradeEntity {
         upgradePackage);
   }
 
+ /**
+ * Removes historical entries for a service component in this upgrade.
+ */
+ public void removeHistories(Collection<UpgradeHistoryEntity> 
upgradeHistoryEntity) {
+    if (upgradeHistory != null) {
+      upgradeHistory.removeAll(upgradeHistoryEntity);
+    }
+  }
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/DeleteUnsupportedServicesAndComponents.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/DeleteUnsupportedServicesAndComponents.java
new file mode 100644
index 0000000..03fb281
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/DeleteUnsupportedServicesAndComponents.java
@@ -0,0 +1,95 @@
+/*
+ *
+ *  * 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.serveraction.upgrades;
+
+import static java.util.stream.Collectors.toList;
+import static org.apache.commons.collections.CollectionUtils.union;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Predicate;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.agent.CommandReport;
+import 
org.apache.ambari.server.controller.internal.DeleteHostComponentStatusMetaData;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
+import org.apache.ambari.server.orm.entities.UpgradeHistoryEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentSupport;
+import org.apache.ambari.server.state.UpgradeContext;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Inject;
+
+/**
+ * Upgrade Server Action that deletes the components and services which are no 
longer supported in the target stack.
+ * The deletable component or service should be in deletable state (stopped) 
before executing this.
+ */
+public class DeleteUnsupportedServicesAndComponents extends 
AbstractUpgradeServerAction {
+  @Inject
+  private ServiceComponentSupport serviceComponentSupport;
+
+  @Override
+  public CommandReport execute(ConcurrentMap<String, Object> 
requestSharedDataContext) throws AmbariException, InterruptedException {
+    Cluster cluster = 
getClusters().getCluster(getExecutionCommand().getClusterName());
+    if (cluster.getUpgradeInProgress().isDowngradeAllowed()) {
+      throw new AmbariException(this.getClass() + " should not be used in 
upgrade packs with downgrade support");
+    }
+    UpgradeContext upgradeContext = getUpgradeContext(cluster);
+    Set<String> removedComponents = deleteUnsupportedComponents(cluster, 
upgradeContext.getRepositoryVersion());
+    Set<String> removedServices = deleteUnsupportedServices(cluster, 
upgradeContext.getRepositoryVersion());
+    return createCommandReport(0, HostRoleStatus.COMPLETED, "{}",
+      "Removed services: " + StringUtils.join(union(removedComponents, 
removedServices), ", "), "");
+  }
+
+  private Set<String> deleteUnsupportedServices(Cluster cluster, 
RepositoryVersionEntity repoVersion) throws AmbariException {
+    Set<String> servicesToBeRemoved = 
serviceComponentSupport.unsupportedServices(cluster, 
repoVersion.getStackName(), repoVersion.getStackVersion());
+    for (String serviceName : servicesToBeRemoved) {
+      cluster.deleteService(serviceName, new 
DeleteHostComponentStatusMetaData());
+      deleteUpgradeHistory(cluster, history -> 
serviceName.equals(history.getServiceName()));
+    }
+    return servicesToBeRemoved;
+  }
+
+  private Set<String> deleteUnsupportedComponents(Cluster cluster, 
RepositoryVersionEntity repoVersion) throws AmbariException {
+    Set<String> deletedComponents = new HashSet<>();
+    for (ServiceComponent component : 
serviceComponentSupport.unsupportedComponents(cluster, 
repoVersion.getStackName(), repoVersion.getStackVersion())) {
+      
cluster.getService(component.getServiceName()).deleteServiceComponent(component.getName(),
 new DeleteHostComponentStatusMetaData());
+      deleteUpgradeHistory(cluster, history -> 
component.getName().equals(history.getComponentName()));
+      deletedComponents.add(component.getName());
+    }
+    return deletedComponents;
+  }
+
+  private void deleteUpgradeHistory(Cluster cluster, 
Predicate<UpgradeHistoryEntity> predicate) {
+    UpgradeEntity upgradeInProgress = cluster.getUpgradeInProgress();
+    List<UpgradeHistoryEntity> removed = 
upgradeInProgress.getHistory().stream()
+      .filter(each -> each != null && predicate.test(each))
+      .collect(toList());
+    upgradeInProgress.removeHistories(removed);
+    m_upgradeDAO.merge(upgradeInProgress);
+  }
+}
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
index f040605..6371302 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
@@ -787,7 +787,11 @@ public class ConfigHelper {
     }
 
     for (Service service : cluster.getServices().values()) {
-      Set<PropertyInfo> serviceProperties = new 
HashSet<>(servicesMap.get(service.getName()).getProperties());
+      ServiceInfo serviceInfo = servicesMap.get(service.getName());
+      if (serviceInfo == null) {
+        continue;
+      }
+      Set<PropertyInfo> serviceProperties = new 
HashSet<>(serviceInfo.getProperties());
       for (PropertyInfo serviceProperty : serviceProperties) {
         if (serviceProperty.getPropertyTypes().contains(propertyType)) {
           String stackPropertyConfigType = 
fileNameToConfigType(serviceProperty.getFilename());
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigMergeHelper.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigMergeHelper.java
index cf55660..b04314b 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigMergeHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigMergeHelper.java
@@ -26,6 +26,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StackAccessException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
@@ -60,14 +61,18 @@ public class ConfigMergeHelper {
 
     // Collect service-level properties for old and new stack
     for (String serviceName : cluster.getServices().keySet()) {
+      try {
+        Set<PropertyInfo> newStackProperties = 
m_ambariMetaInfo.get().getServiceProperties(
+          targetStack.getStackName(), targetStack.getStackVersion(), 
serviceName);
+        addToMap(newMap, newStackProperties);
+      } catch (StackAccessException e) {
+        LOG.info("Skipping service {} which is currently installed but does 
not exist in the target stack {}", serviceName, targetStack);
+        continue;
+      }
       Set<PropertyInfo> oldStackProperties = 
m_ambariMetaInfo.get().getServiceProperties(
           oldStack.getStackName(), oldStack.getStackVersion(), serviceName);
       addToMap(oldMap, oldStackProperties);
-
-      Set<PropertyInfo> newStackProperties = 
m_ambariMetaInfo.get().getServiceProperties(
-          targetStack.getStackName(), targetStack.getStackVersion(), 
serviceName);
-      addToMap(newMap, newStackProperties);
-    }
+  }
 
     // Collect stack-level properties defined for old and new stack
     Set<PropertyInfo> set = m_ambariMetaInfo.get().getStackProperties(
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentSupport.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentSupport.java
new file mode 100644
index 0000000..d1aebac
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentSupport.java
@@ -0,0 +1,108 @@
+/*
+ *
+ *  * 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 static java.util.stream.Collectors.toSet;
+import static org.apache.commons.collections.CollectionUtils.union;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StackAccessException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Collects services and components which are installed but not supported in 
the target stack
+ */
+@Singleton
+public class ServiceComponentSupport {
+  private final Provider<AmbariMetaInfo> metaInfo;
+
+  @Inject
+  public ServiceComponentSupport(Provider<AmbariMetaInfo> metaInfo) {
+    this.metaInfo = metaInfo;
+  }
+
+  /**
+   * Collects the service names from the cluster which are not supported 
(service doesn't exist or was deleted) in the given stack.
+   */
+  public Set<String> unsupportedServices(Cluster cluster, String stackName, 
String stackVersion) {
+    return cluster.getServices().keySet().stream()
+      .filter(serviceName -> !isServiceSupported(serviceName, stackName, 
stackVersion))
+      .collect(toSet());
+  }
+
+  private boolean isServiceSupported(String serviceName, String stackName, 
String stackVersion) {
+    try {
+      ServiceInfo service = metaInfo.get().getServices(stackName, 
stackVersion).get(serviceName);
+      return service != null && !service.isDeleted();
+    } catch (AmbariException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
+   * Collects the ServiceComponents from the cluster which are not supported 
(component doesn't exist or was deleted) in the given stack.
+   * Non versionAdvertised components are ignored.
+   */
+  public Set<ServiceComponent> unsupportedComponents(Cluster cluster, String 
stackName, String stackVersion) throws AmbariException {
+
+    Set<ServiceComponent> unsupportedComponents = new HashSet<>();
+    for (Service service : cluster.getServices().values()) {
+      for (ServiceComponent component : 
service.getServiceComponents().values()) {
+        if (!component.isVersionAdvertised())
+          continue;
+        if (!isComponentSupported(service.getName(), component.getName(), 
stackName, stackVersion)) {
+          unsupportedComponents.add(component);
+        }
+      }
+    }
+    return unsupportedComponents;
+  }
+
+  private boolean isComponentSupported(String serviceName, String 
componentName, String stackName, String stackVersion) throws AmbariException {
+    try {
+      ComponentInfo component = metaInfo.get().getComponent(stackName, 
stackVersion, serviceName, componentName);
+      return !component.isDeleted();
+    } catch (StackAccessException e) {
+      return false;
+    }
+  }
+
+  /**
+   * @return the union of unsupported components and services
+   */
+  public Collection<String> allUnsupported(Cluster cluster, String stackName, 
String stackVersion) throws AmbariException {
+    return union(
+      unsupportedServices(cluster, stackName, stackVersion),
+      names(unsupportedComponents(cluster, stackName, stackVersion)));
+  }
+
+  private Set<String> names(Set<ServiceComponent> serviceComponents) {
+    return serviceComponents.stream().map(each -> 
each.getName()).collect(toSet());
+  }
+}
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
index 7fb04f5..0ce4181 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
@@ -72,7 +72,7 @@ public class UpgradePack {
 
   @XmlElementWrapper(name="order")
   @XmlElement(name="group")
-  private List<Grouping> groups;
+  private List<Grouping> groups = new ArrayList<>();
 
   @XmlElement(name="prerequisite-checks")
   private PrerequisiteChecks prerequisiteChecks;
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
index 844ef24..587b5c6 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
@@ -52,6 +52,10 @@ public abstract class ServerSideActionTask extends Task {
     return implClass;
   }
 
+  public void setImplClass(String implClass) {
+    this.implClass = implClass;
+  }
+
   @XmlElement(name="message")
   public List<String> messages = new ArrayList<>();
 
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentExistsInRepoCheckTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentExistsInRepoCheckTest.java
index 3a88d0f..f5635fe 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentExistsInRepoCheckTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/checks/ComponentExistsInRepoCheckTest.java
@@ -17,344 +17,116 @@
  */
 package org.apache.ambari.server.checks;
 
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.ambari.server.StackAccessException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import 
org.apache.ambari.server.serveraction.upgrades.DeleteUnsupportedServicesAndComponents;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.RepositoryType;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.ServiceComponentSupport;
 import org.apache.ambari.server.state.StackId;
-import org.apache.ambari.server.state.repository.ClusterVersionSummary;
-import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+import org.apache.ambari.server.state.UpgradeHelper;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
-import org.apache.commons.lang.StringUtils;
+import org.apache.ambari.server.state.stack.UpgradePack;
+import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping;
+import org.apache.ambari.server.state.stack.upgrade.ServerActionTask;
+import org.easymock.EasyMockRunner;
 import org.easymock.EasyMockSupport;
 import org.easymock.Mock;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
-import com.google.inject.Provider;
-
-/**
- * Tests for {@link ComponentsExistInRepoCheck}
- */
+@RunWith(EasyMockRunner.class)
 public class ComponentExistsInRepoCheckTest extends EasyMockSupport {
-
-  private final ComponentsExistInRepoCheck m_check = new 
ComponentsExistInRepoCheck();
-
-  @Mock
-  private Clusters m_clusters;
-
-  @Mock
-  private Cluster m_cluster;
-
-  // pick two stacks which have different services
-  private final StackId SOURCE_STACK = new StackId("HDP", "0.1");
-  private final StackId TARGET_STACK = new StackId("HDP", "2.2.0");
-
-  private final Map<String, Service> CLUSTER_SERVICES = new HashMap<>();
-  private final Map<String, ServiceComponent> FOO_SERVICE_COMPONENTS = new 
HashMap<>();
-  private final Map<String, ServiceComponent> ZK_SERVICE_COMPONENTS = new 
HashMap<>();
-
-  @Mock
-  private AmbariMetaInfo m_ambariMetaInfo;
-
-  @Mock
-  private Service m_fooService;
-
-  @Mock
-  private Service m_zookeeperService;
-
-  @Mock
-  private ServiceInfo m_fooInfo;
-
-  @Mock
-  private ServiceInfo m_zookeeperInfo;
-
-  @Mock
-  private ComponentInfo m_fooComponentInfo;
-
-  @Mock
-  private ComponentInfo m_zookeeperServerInfo;
-
+  public static final String STACK_NAME = "HDP";
+  public static final String STACK_VERSION = "2.2.0";
+  private ComponentsExistInRepoCheck check = new ComponentsExistInRepoCheck();
   @Mock
-  private ServiceComponent m_fooComponent;
-
-  @Mock
-  private ServiceComponent m_zookeeperServer;
-
+  private Clusters clusters;
   @Mock
-  private ClusterVersionSummary m_clusterVersionSummary;
-
+  private Cluster cluster;
   @Mock
-  private VersionDefinitionXml m_vdfXml;
-
+  private ServiceComponentSupport serviceComponentSupport;
   @Mock
-  private RepositoryVersionEntity m_repositoryVersion;
+  private UpgradeHelper upgradeHelper;
+  private PrerequisiteCheck prereq = new 
PrerequisiteCheck(CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
+  private PrereqCheckRequest request = new PrereqCheckRequest("cluster");
 
   @Before
   public void before() throws Exception {
-
-    EasyMockSupport.injectMocks(this);
-
-    m_check.clustersProvider = new Provider<Clusters>() {
-      @Override
-      public Clusters get() {
-        return m_clusters;
-      }
-    };
-
-    m_check.ambariMetaInfo = new Provider<AmbariMetaInfo>() {
-      @Override
-      public AmbariMetaInfo get() {
-        return m_ambariMetaInfo;
-      }
-    };
-
-    expect(m_cluster.getServices()).andReturn(CLUSTER_SERVICES).atLeastOnce();
-    
expect(m_cluster.getService("ZOOKEEPER")).andReturn(m_zookeeperService).anyTimes();
-    
expect(m_cluster.getService("FOO_SERVICE")).andReturn(m_fooService).anyTimes();
-
-    expect(m_clusters.getCluster((String) 
anyObject())).andReturn(m_cluster).anyTimes();
-
-    ZK_SERVICE_COMPONENTS.put("ZOOKEEPER_SERVER", m_zookeeperServer);
-    FOO_SERVICE_COMPONENTS.put("FOO_COMPONENT", m_fooComponent);
-
-    
expect(m_zookeeperService.getServiceComponents()).andReturn(ZK_SERVICE_COMPONENTS).anyTimes();
-    
expect(m_fooService.getServiceComponents()).andReturn(FOO_SERVICE_COMPONENTS).anyTimes();
-
-    expect(m_zookeeperInfo.getComponentByName("ZOOKEEPER_SERVER")).andReturn(
-        m_zookeeperServerInfo).anyTimes();
-
-    
expect(m_fooInfo.getComponentByName("FOO_COMPONENT")).andReturn(m_fooComponentInfo).anyTimes();
-
-    expect(m_ambariMetaInfo.getService(TARGET_STACK.getStackName(), 
TARGET_STACK.getStackVersion(),
-        "ZOOKEEPER")).andReturn(m_zookeeperInfo).anyTimes();
-
-    expect(m_ambariMetaInfo.getComponent(TARGET_STACK.getStackName(),
-        TARGET_STACK.getStackVersion(), "ZOOKEEPER", 
"ZOOKEEPER_SERVER")).andReturn(
-            m_zookeeperServerInfo).anyTimes();
-
-    
expect(m_repositoryVersion.getType()).andReturn(RepositoryType.STANDARD).anyTimes();
-    
expect(m_repositoryVersion.getStackId()).andReturn(TARGET_STACK).anyTimes();
-    expect(m_repositoryVersion.getVersion()).andReturn("2.2.0").anyTimes();
-
-    
expect(m_repositoryVersion.getRepositoryXml()).andReturn(m_vdfXml).anyTimes();
-    
expect(m_vdfXml.getClusterSummary(anyObject(Cluster.class))).andReturn(m_clusterVersionSummary).anyTimes();
-    
expect(m_clusterVersionSummary.getAvailableServiceNames()).andReturn(CLUSTER_SERVICES.keySet()).anyTimes();
-
+    check.clustersProvider = () -> clusters;
+    check.serviceComponentSupport = serviceComponentSupport;
+    check.upgradeHelper = upgradeHelper;
+    expect(clusters.getCluster((String) 
anyObject())).andReturn(cluster).anyTimes();
+    request.setTargetRepositoryVersion(repoVersion());
+    request.setSourceStackId(new StackId(STACK_NAME, "1.0"));
   }
 
-  /**
-   * Tests that the check passes when services and components exist.
-   *
-   * @throws Exception
-   */
   @Test
-  public void testCheckPassesWhenServicAndComponentsExist() throws Exception {
-    PrerequisiteCheck check = new 
PrerequisiteCheck(CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
-    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
-    request.setSourceStackId(SOURCE_STACK);
-    request.setTargetRepositoryVersion(m_repositoryVersion);
-
-    CLUSTER_SERVICES.put("ZOOKEEPER", m_zookeeperService);
-    expect(m_zookeeperInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperInfo.isDeleted()).andReturn(false).atLeastOnce();
-    
expect(m_zookeeperServerInfo.isVersionAdvertised()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperServerInfo.isDeleted()).andReturn(false).atLeastOnce();
-
+  public void testPassesWhenNoUnsupportedInTargetStack() throws Exception {
+    expect(serviceComponentSupport.allUnsupported(cluster, STACK_NAME, 
STACK_VERSION)).andReturn(emptyList()).anyTimes();
     replayAll();
-
-    Assert.assertTrue(m_check.isApplicable(request));
-
-    m_check.perform(check, request);
-
-    Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
-    Assert.assertTrue(check.getFailedDetail().isEmpty());
-    Assert.assertTrue(StringUtils.isBlank(check.getFailReason()));
+    check.perform(prereq, request);
+    assertEquals(PrereqCheckStatus.PASS, prereq.getStatus());
   }
 
-  /**
-   * Tests that the check passes when a service doesn't exist but isn't
-   * advertising its version.
-   *
-   * @throws Exception
-   */
   @Test
-  public void testCheckPassesWhenComponentNotAdvertisingVersion() throws 
Exception {
-    PrerequisiteCheck check = new 
PrerequisiteCheck(CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
-    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
-    request.setSourceStackId(SOURCE_STACK);
-    request.setTargetRepositoryVersion(m_repositoryVersion);
-
-    CLUSTER_SERVICES.put("FOO_SERVICE", m_fooService);
-
-    expect(m_ambariMetaInfo.getService(TARGET_STACK.getStackName(), 
TARGET_STACK.getStackVersion(),
-        "FOO_SERVICE")).andReturn(m_fooInfo).anyTimes();
-
-    expect(m_ambariMetaInfo.getComponent(TARGET_STACK.getStackName(),
-        TARGET_STACK.getStackVersion(), "FOO_SERVICE", 
"FOO_COMPONENT")).andReturn(
-            m_fooComponentInfo).atLeastOnce();
-
-    expect(m_fooInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_fooInfo.isDeleted()).andReturn(false).atLeastOnce();
-    
expect(m_fooComponentInfo.isVersionAdvertised()).andReturn(false).atLeastOnce();
-    expect(m_fooComponentInfo.isDeleted()).andReturn(true).atLeastOnce();
-
+  public void testFailsWhenUnsupportedFoundInTargetStack() throws Exception {
+    expect(serviceComponentSupport.allUnsupported(cluster, STACK_NAME, 
STACK_VERSION)).andReturn(singletonList("ANY_SERVICE")).anyTimes();
+    suggestedUpgradePackIs(new UpgradePack());
     replayAll();
-
-    Assert.assertTrue(m_check.isApplicable(request));
-
-    m_check.perform(check, request);
-
-    Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
-    Assert.assertTrue(check.getFailedDetail().isEmpty());
-    Assert.assertTrue(StringUtils.isBlank(check.getFailReason()));
+    check.perform(prereq, request);
+    assertEquals(PrereqCheckStatus.FAIL, prereq.getStatus());
   }
 
-  /**
-   * Tests that the check fails when the service exists but was deleted.
-   *
-   * @throws Exception
-   */
   @Test
-  public void testCheckFailsWhenServiceExistsButIsDeleted() throws Exception {
-    PrerequisiteCheck check = new 
PrerequisiteCheck(CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
-    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
-    request.setSourceStackId(SOURCE_STACK);
-    request.setTargetRepositoryVersion(m_repositoryVersion);
-
-    CLUSTER_SERVICES.put("ZOOKEEPER", m_zookeeperService);
-    expect(m_zookeeperInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperInfo.isDeleted()).andReturn(true).atLeastOnce();
-
+  public void 
testWarnsWhenUnsupportedFoundInTargetStackAndUpgradePackHasAutoDeleteTask() 
throws Exception {
+    expect(serviceComponentSupport.allUnsupported(cluster, STACK_NAME, 
STACK_VERSION)).andReturn(singletonList("ANY_SERVICE")).anyTimes();
+    suggestedUpgradePackIs(upgradePackWithDeleteUnsupportedTask());
     replayAll();
-
-    Assert.assertTrue(m_check.isApplicable(request));
-
-    m_check.perform(check, request);
-
-    Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
-    Assert.assertEquals(1, check.getFailedDetail().size());
-    Assert.assertTrue(check.getFailedOn().contains("ZOOKEEPER"));
+    check.perform(prereq, request);
+    assertEquals(PrereqCheckStatus.WARNING, prereq.getStatus());
   }
 
-  /**
-   * Tests that the check fails when the component exists but what deleted.
-   *
-   * @throws Exception
-   */
-  @Test
-  public void testCheckFailsWhenComponentExistsButIsDeleted() throws Exception 
{
-    PrerequisiteCheck check = new 
PrerequisiteCheck(CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
-    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
-    request.setSourceStackId(SOURCE_STACK);
-    request.setTargetRepositoryVersion(m_repositoryVersion);
-
-    CLUSTER_SERVICES.put("ZOOKEEPER", m_zookeeperService);
-    expect(m_zookeeperInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperInfo.isDeleted()).andReturn(false).atLeastOnce();
-    
expect(m_zookeeperServerInfo.isVersionAdvertised()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperServerInfo.isDeleted()).andReturn(true).atLeastOnce();
-
-    replayAll();
-
-    Assert.assertTrue(m_check.isApplicable(request));
-
-    m_check.perform(check, request);
-
-    Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
-    Assert.assertEquals(1, check.getFailedDetail().size());
-    Assert.assertTrue(check.getFailedOn().contains("ZOOKEEPER_SERVER"));
+  private RepositoryVersionEntity repoVersion() {
+    RepositoryVersionEntity repositoryVersion = new RepositoryVersionEntity();
+    repositoryVersion.setType(RepositoryType.STANDARD);
+    StackEntity stack = new StackEntity();
+    repositoryVersion.setStack(stack);
+    stack.setStackName(STACK_NAME);
+    stack.setStackVersion(STACK_VERSION);
+    return repositoryVersion;
   }
 
-  /**
-   * Tests that the check fails when the component exists but what deleted.
-   *
-   * @throws Exception
-   */
-  @Test
-  public void testCheckFailsWhenServiceIsMissing() throws Exception {
-    PrerequisiteCheck check = new PrerequisiteCheck(
-        CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
-    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
-    request.setSourceStackId(SOURCE_STACK);
-    request.setTargetRepositoryVersion(m_repositoryVersion);
-
-    CLUSTER_SERVICES.put("ZOOKEEPER", m_zookeeperService);
-    CLUSTER_SERVICES.put("FOO_SERVICE", m_fooService);
-
-    expect(m_ambariMetaInfo.getService(TARGET_STACK.getStackName(), 
TARGET_STACK.getStackVersion(),
-        "FOO_SERVICE")).andThrow(new StackAccessException(""));
-
-    expect(m_zookeeperInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperInfo.isDeleted()).andReturn(false).atLeastOnce();
-    
expect(m_zookeeperServerInfo.isVersionAdvertised()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperServerInfo.isDeleted()).andReturn(false).atLeastOnce();
-
-    replayAll();
-
-    Assert.assertTrue(m_check.isApplicable(request));
-
-    m_check.perform(check, request);
-
-    Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
-    Assert.assertEquals(1, check.getFailedDetail().size());
-    Assert.assertTrue(check.getFailedOn().contains("FOO_SERVICE"));
+  private void suggestedUpgradePackIs(UpgradePack upgradePack) throws 
AmbariException {
+    expect(upgradeHelper.suggestUpgradePack(
+      "cluster",
+      request.getSourceStackId(),
+      request.getTargetRepositoryVersion().getStackId(),
+      request.getDirection(),
+      request.getUpgradeType(),
+      null)).andReturn(upgradePack).anyTimes();
   }
 
-  /**
-   * Tests that the check fails when the component exists but what deleted.
-   *
-   * @throws Exception
-   */
-  @Test
-  public void testCheckFailsWhenComponentIsMissing() throws Exception {
-    PrerequisiteCheck check = new PrerequisiteCheck(
-        CheckDescription.COMPONENTS_EXIST_IN_TARGET_REPO, "c1");
-    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
-    request.setSourceStackId(SOURCE_STACK);
-    request.setTargetRepositoryVersion(m_repositoryVersion);
-
-    CLUSTER_SERVICES.put("FOO_SERVICE", m_fooService);
-
-    expect(m_ambariMetaInfo.getService(TARGET_STACK.getStackName(), 
TARGET_STACK.getStackVersion(),
-        "FOO_SERVICE")).andReturn(m_fooInfo).anyTimes();
-
-    expect(m_ambariMetaInfo.getComponent(TARGET_STACK.getStackName(),
-        TARGET_STACK.getStackVersion(), "FOO_SERVICE", 
"FOO_COMPONENT")).andThrow(
-            new StackAccessException(""));
-
-    expect(m_zookeeperInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperInfo.isDeleted()).andReturn(false).atLeastOnce();
-    
expect(m_zookeeperServerInfo.isVersionAdvertised()).andReturn(true).atLeastOnce();
-    expect(m_zookeeperServerInfo.isDeleted()).andReturn(false).atLeastOnce();
-
-    expect(m_fooInfo.isValid()).andReturn(true).atLeastOnce();
-    expect(m_fooInfo.isDeleted()).andReturn(false).atLeastOnce();
-
-    replayAll();
-
-    Assert.assertTrue(m_check.isApplicable(request));
-
-    m_check.perform(check, request);
-
-    Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
-    Assert.assertEquals(1, check.getFailedDetail().size());
-    Assert.assertTrue(check.getFailedOn().contains("FOO_COMPONENT"));
+  private UpgradePack upgradePackWithDeleteUnsupportedTask() {
+    UpgradePack upgradePack = new UpgradePack();
+    ClusterGrouping group = new ClusterGrouping();
+    ClusterGrouping.ExecuteStage stage = new ClusterGrouping.ExecuteStage();
+    ServerActionTask task = new ServerActionTask();
+    task.setImplClass(DeleteUnsupportedServicesAndComponents.class.getName());
+    stage.task = task;
+    group.executionStages = singletonList(stage);
+    upgradePack.getAllGroups().add(group);
+    return upgradePack;
   }
-
 }
\ No newline at end of file
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentSupportTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentSupportTest.java
new file mode 100644
index 0000000..779a440
--- /dev/null
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentSupportTest.java
@@ -0,0 +1,118 @@
+/*
+ *
+ *  * 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 static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.core.AllOf.allOf;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.internal.matchers.IsCollectionContaining.hasItems;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.easymock.EasyMockRunner;
+import org.easymock.EasyMockSupport;
+import org.easymock.Mock;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(EasyMockRunner.class)
+public class ServiceComponentSupportTest extends EasyMockSupport {
+  private static final String STACK_NAME = "HDP";
+  private static final String VERSION = "3.0";
+  @Mock
+  private AmbariMetaInfo ambariMetaInfo;
+  private ServiceComponentSupport componentSupport;
+
+  @Before
+  public void setUp() throws Exception {
+    componentSupport = new ServiceComponentSupport(() -> ambariMetaInfo);
+  }
+
+  @Test
+  public void testNoUnsupportedIfAllExistsInTargetStack() throws Exception {
+    targetStackWith("SERVICE1", "SERVICE2");
+    Set<String> unsupported = unsupportedServices(clusterWith("SERVICE1", 
"SERVICE2"));
+    assertThat(unsupported, hasSize(0));
+    verifyAll();
+  }
+
+  @Test
+  public void testUnsupportedIfDoesntExistInTargetStack() throws Exception {
+    targetStackWith("SERVICE1");
+    Set<String> unsupported = unsupportedServices(clusterWith("SERVICE1", 
"SERVICE2"));
+    assertThat(unsupported, hasOnlyItems(is("SERVICE2")));
+    verifyAll();
+  }
+
+  @Test
+  public void testUnsupportedIfDeletedFromTargetStack() throws Exception {
+    targetStackWith("SERVICE1", "SERVICE2");
+    markAsDeleted("SERVICE2");
+    Set<String> unsupported = unsupportedServices(clusterWith("SERVICE1", 
"SERVICE2"));
+    assertThat(unsupported, hasOnlyItems(is("SERVICE2")));
+    verifyAll();
+  }
+
+  private void targetStackWith(String... serviceNames) throws AmbariException {
+    expect(ambariMetaInfo.getServices(STACK_NAME, 
VERSION)).andReturn(serviceInfoMap(serviceNames)).anyTimes();
+    replay(ambariMetaInfo);
+  }
+
+  private Map<String, ServiceInfo> serviceInfoMap(String... serviceNames) {
+    Map<String, ServiceInfo> serviceInfoMap = new HashMap<>();
+    for (String serviceName : serviceNames) {
+      serviceInfoMap.put(serviceName, new ServiceInfo());
+    }
+    return serviceInfoMap;
+  }
+
+  private Set<String> unsupportedServices(Cluster cluster) {
+    return componentSupport.unsupportedServices(cluster, STACK_NAME, VERSION);
+  }
+
+  private Cluster clusterWith(String... installedServiceNames) {
+    Cluster cluster = mock(Cluster.class);
+    Map<String, Service> serviceMap = new HashMap<>();
+    for (String serviceName : installedServiceNames) {
+      serviceMap.put(serviceName, null);
+    }
+    expect(cluster.getServices()).andReturn(serviceMap);
+    replay(cluster);
+    return cluster;
+  }
+
+  private void markAsDeleted(String serviceName) throws AmbariException {
+    ambariMetaInfo.getServices(STACK_NAME, 
VERSION).get(serviceName).setDeleted(true);
+  }
+
+  private static Matcher hasOnlyItems(Matcher... matchers) {
+    return allOf(hasSize(matchers.length), hasItems(matchers));
+  }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to