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].