You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2018/10/16 14:24:27 UTC
[ambari] branch trunk updated: [AMBARI-24768] - Load Upgrade Checks
Dynamically From Stacks (#2451)
This is an automated email from the ASF dual-hosted git repository.
jonathanhurley 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 6f2622c [AMBARI-24768] - Load Upgrade Checks Dynamically From Stacks (#2451)
6f2622c is described below
commit 6f2622c76d63a49f9bf06cb062b939836a8a96b7
Author: Jonathan Hurley <jo...@apache.org>
AuthorDate: Tue Oct 16 10:24:21 2018 -0400
[AMBARI-24768] - Load Upgrade Checks Dynamically From Stacks (#2451)
---
.../ambari/annotations/UpgradeCheckInfo.java | 2 -
.../apache/ambari/spi/upgrade/UpgradeCheck.java | 6 +-
ambari-server/docs/configuration/index.md | 1 +
.../ambari/server/api/services/AmbariMetaInfo.java | 7 -
.../ambari/server/checks/UpgradeCheckRegistry.java | 217 ++++++++++++---------
.../checks/UpgradeCheckRegistryProvider.java | 109 +++++++++++
.../server/checks/UpgradeTypeQualification.java | 65 ++++++
.../server/cleanup/ClasspathScannerUtils.java | 32 ++-
.../ambari/server/controller/ControllerModule.java | 62 +-----
.../internal/PreUpgradeCheckResourceProvider.java | 33 ++--
.../apache/ambari/server/stack/StackDirectory.java | 102 +++++++++-
.../apache/ambari/server/stack/StackModule.java | 12 +-
.../ambari/server/stack/upgrade/UpgradePack.java | 34 ++++
.../stack/upgrade/orchestrate/UpgradeHelper.java | 2 +-
.../apache/ambari/server/state/CheckHelper.java | 8 +-
.../org/apache/ambari/server/state/StackInfo.java | 63 ++++--
.../server/api/services/AmbariMetaInfoTest.java | 11 +-
.../server/checks/AutoStartDisabledCheckTest.java | 2 +-
.../ambari/server/checks/ClusterCheckTest.java | 22 ---
.../server/checks/UpgradeCheckOrderTest.java | 5 +-
.../checks/UpgradeTypeQualificationTest.java | 121 ++++++++++++
.../PreUpgradeCheckResourceProviderTest.java | 205 ++++++++++++-------
.../server/orm/InMemoryDefaultTestModule.java | 10 -
.../ambari/server/state/CheckHelperTest.java | 36 +++-
24 files changed, 821 insertions(+), 346 deletions(-)
diff --git a/ambari-server-spi/src/main/java/org/apache/ambari/annotations/UpgradeCheckInfo.java b/ambari-server-spi/src/main/java/org/apache/ambari/annotations/UpgradeCheckInfo.java
index 3c3ce36..d72e1a0 100644
--- a/ambari-server-spi/src/main/java/org/apache/ambari/annotations/UpgradeCheckInfo.java
+++ b/ambari-server-spi/src/main/java/org/apache/ambari/annotations/UpgradeCheckInfo.java
@@ -27,7 +27,6 @@ import org.apache.ambari.spi.RepositoryType;
import org.apache.ambari.spi.upgrade.UpgradeCheckGroup;
import org.apache.ambari.spi.upgrade.UpgradeType;
-import com.google.inject.ScopeAnnotation;
import com.google.inject.Singleton;
/**
@@ -40,7 +39,6 @@ import com.google.inject.Singleton;
*/
@Target({ ElementType.TYPE })
@Retention(RUNTIME)
-@ScopeAnnotation
public @interface UpgradeCheckInfo {
/**
diff --git a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeCheck.java b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeCheck.java
index 2ac42dc..d887bd0 100644
--- a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeCheck.java
+++ b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeCheck.java
@@ -20,11 +20,15 @@ package org.apache.ambari.spi.upgrade;
import java.util.List;
import java.util.Set;
+import org.apache.ambari.annotations.UpgradeCheckInfo;
import org.apache.ambari.server.AmbariException;
/**
* The {@link UpgradeCheck} is used before an upgrade in order to present the
- * administrator with a warning or a failure about an upgrade.
+ * administrator with a warning or a failure about an upgrade. All
+ * implementations of this class should used the {@link UpgradeCheckInfo}
+ * annotation to specify information about the check, such as its associated
+ * upgrade type(s) and ordering.
*/
public interface UpgradeCheck {
diff --git a/ambari-server/docs/configuration/index.md b/ambari-server/docs/configuration/index.md
index a0c2d04..2c9d05e 100644
--- a/ambari-server/docs/configuration/index.md
+++ b/ambari-server/docs/configuration/index.md
@@ -289,6 +289,7 @@ The following are the properties which can be used to configure Ambari.
| view.extraction.threadpool.timeout | The time, in milliseconds, that non-core threads will live when extraction views on Ambari Server startup. |`100000` |
| view.request.threadpool.size.max | The maximum number of threads which will be allocated to handling REST API requests from embedded views. This value should be smaller than `agent.threadpool.size.max`<br/><br/> This property is related to `agent.threadpool.size.max`. |`0` |
| view.request.threadpool.timeout | The time, milliseconds, that REST API requests from embedded views can wait if there are no threads available to service the view's request. Setting this too low can cause views to timeout. |`2000` |
+| views.additional.classpath | Additional class path added to each Ambari View. Comma separated jars or directories | |
| views.ambari.request.connect.timeout.millis | The amount of time, in milliseconds, that a view will wait when trying to connect on HTTP(S) operations to the Ambari REST API. |`30000` |
| views.ambari.request.read.timeout.millis | The amount of time, in milliseconds, that a view will wait before terminating an HTTP(S) read request to the Ambari REST API. |`45000` |
| views.dir | The directory on the Ambari Server file system used for expanding Views and storing webapp work. |`/var/lib/ambari-server/resources/views` |
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 6e5c66e..d15d02a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -58,7 +58,6 @@ import org.apache.ambari.server.metadata.AmbariServiceAlertDefinitions;
import org.apache.ambari.server.mpack.MpackManager;
import org.apache.ambari.server.mpack.MpackManagerFactory;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
-import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.MpackEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
@@ -136,9 +135,6 @@ public class AmbariMetaInfo {
@Inject
private OsFamily osFamily;
- @Inject
- private Gson gson;
-
/**
* ALL_SUPPORTED_OS is dynamically generated list from loaded families from os_family.json
* Instead of append values here, please, add new families in json for tests and production
@@ -161,9 +157,6 @@ public class AmbariMetaInfo {
private File mpacksV2Staging;
- @Inject
- private MetainfoDAO metaInfoDAO;
-
/**
* Alert Definition DAO used to merge stack definitions into the database.
*/
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
index d64f804..52ccc7e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
@@ -17,164 +17,193 @@
*/
package org.apache.ambari.server.checks;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.net.URL;
-import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.ambari.annotations.UpgradeCheckInfo;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.stack.upgrade.UpgradePack;
-import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.CheckHelper;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.spi.upgrade.CheckQualification;
import org.apache.ambari.spi.upgrade.UpgradeCheck;
import org.apache.ambari.spi.upgrade.UpgradeCheckGroup;
import org.apache.ambari.spi.upgrade.UpgradeType;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.util.ClassUtils;
-import com.google.inject.Singleton;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Provider;
/**
* The {@link UpgradeCheckRegistry} contains the ordered list of all pre-upgrade
* checks. This will order the checks according to
* {@link PreUpgradeCheckComparator}.
+ * <p>
+ * There are two types of checks which can be loaded into this registry:
+ * <ul>
+ * <li>Built-in: checks which ship with Ambari
+ * <li>Plug-in: checks which are specified in the upgrade pack for a stack, and
+ * either come from Ambari's checks or from the library classpath of the stack.
+ * </ul>
*/
-@Singleton
public class UpgradeCheckRegistry {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeCheckRegistry.class);
+ @Inject
+ private Provider<AmbariMetaInfo> metainfoProvider;
+
/**
- * The list of upgrade checks to run through.
+ * Used for injecting dependencies into plugin upgrade check classes. There
+ * are cases where an upgrade pack specifies a built-in check which uses a
+ * dependency, such as the Ambari Configuration singleton.
*/
- private Set<UpgradeCheck> m_upgradeChecks = new TreeSet<>(
+ @Inject
+ private Injector m_injector;
+
+ /**
+ * The list of upgrade checks provided by the system which are required, as
+ * specified by {@link UpgradeCheckInfo#required()}.
+ */
+ private final Set<UpgradeCheck> m_builtInChecks = new TreeSet<>(
new PreUpgradeCheckComparator());
/**
+ * The upgrade checks discovered on a per-stack, per-upgrade pack basis.
+ */
+ private final Map<UpgradePack, Set<UpgradeCheck>> m_pluginChecks = new HashMap<>();
+
+ /**
* Register an upgrade check.
*
* @param upgradeCheck
* the check to register (not {@code null}).
*/
public void register(UpgradeCheck upgradeCheck) {
- m_upgradeChecks.add(upgradeCheck);
+ m_builtInChecks.add(upgradeCheck);
}
/**
- * Gets an ordered list of all of the upgrade checks.
+ * Gets a list of all of the built-in upgrade checks.
*
* @return
*/
- public List<UpgradeCheck> getUpgradeChecks() {
- return new ArrayList<>(m_upgradeChecks);
+ public List<UpgradeCheck> getBuiltInUpgradeChecks() {
+ return new ArrayList<>(m_builtInChecks);
}
- public List<UpgradeCheck> getServiceLevelUpgradeChecks(UpgradePack upgradePack, Map<String, ServiceInfo> services) {
- List<String> prerequisiteChecks = upgradePack.getPrerequisiteChecks();
- List<String> missingChecks = new ArrayList<>();
- for (String prerequisiteCheck : prerequisiteChecks) {
- if (!isRegistered(prerequisiteCheck)) {
- missingChecks.add(prerequisiteCheck);
+ /**
+ * Gets the ordered upgrade checks which should execute for the specified
+ * upgrade pack. This list of checks will include required built-in checks
+ * from Ambari and plugin checks loaded from the upgrade pack.
+ * <p>
+ * This collection of upgrade checks will be further scrutinized via
+ * {@link CheckQualification}s to determine if they indeed need to run by the
+ * {@link CheckHelper}.
+ *
+ * @param upgradePack
+ * Upgrade pack object with the list of required checks to be
+ * included
+ * @return
+ */
+ public List<UpgradeCheck> getFilteredUpgradeChecks(UpgradePack upgradePack) throws AmbariException {
+ List<UpgradeCheck> builtInRequiredChecks = new ArrayList<>();
+
+ // iterate over all of the built-in checks, dropping any which are not
+ // required for the upgrade pack's upgrade type
+ for (UpgradeCheck builtInCheck : m_builtInChecks) {
+ if (isBuiltInCheckRequired(builtInCheck, upgradePack.getType())) {
+ builtInRequiredChecks.add(builtInCheck);
}
}
- List<UpgradeCheck> checks = new ArrayList<>(missingChecks.size());
- if (missingChecks.isEmpty()) {
- return checks;
- }
+ // for any checks defined in the upgrade pack, add them since they have been
+ // explicitely defined
+ Set<UpgradeCheck> pluginChecks = m_pluginChecks.get(upgradePack);
- List<URL> urls = new ArrayList<>();
- for (ServiceInfo service : services.values()) {
- File dir = service.getChecksFolder();
- File[] jars = dir.listFiles(new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.endsWith(".jar");
- }
- });
- for (File jar : jars) {
- try {
- URL url = jar.toURI().toURL();
- urls.add(url);
- LOG.debug("Adding service check jar to classpath: {}", url);
- }
- catch (Exception e) {
- LOG.error("Failed to add service check jar to classpath: {}", jar.getAbsolutePath(), e);
- }
- }
- }
+ // see if the upgrade checks have been processes for this pack yet
+ if (null == pluginChecks) {
+ pluginChecks = new TreeSet<>(new PreUpgradeCheckComparator());
+ m_pluginChecks.put(upgradePack, pluginChecks);
- ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), ClassUtils.getDefaultClassLoader());
- for (String prerequisiteCheck : missingChecks) {
- Class<?> clazz = null;
- try {
- clazz = ClassUtils.resolveClassName(prerequisiteCheck, classLoader);
- }
- catch (IllegalArgumentException illegalArgumentException) {
- LOG.error("Unable to find upgrade check {}", prerequisiteCheck, illegalArgumentException);
- }
- try {
- if (clazz != null) {
- UpgradeCheck upgradeCheck = (UpgradeCheck) clazz.newInstance();
- checks.add(upgradeCheck);
- }
- } catch (Exception exception) {
- LOG.error("Unable to create upgrade check {}", prerequisiteCheck, exception);
+ List<String> pluginCheckClassNames = upgradePack.getPrerequisiteChecks();
+ if (null != pluginCheckClassNames && !pluginCheckClassNames.isEmpty()) {
+ loadPluginUpgradeChecksFromStack(upgradePack, pluginChecks);
}
}
- return checks;
- }
- private boolean isRegistered(String prerequisiteCheck) {
- for (UpgradeCheck descriptor: m_upgradeChecks){
- if (prerequisiteCheck.equals(descriptor.getClass().getName())){
- return true;
- }
- }
- return false;
+ final Set<UpgradeCheck> combinedUpgradeChecks = new TreeSet<>(new PreUpgradeCheckComparator());
+ combinedUpgradeChecks.addAll(builtInRequiredChecks);
+ combinedUpgradeChecks.addAll(pluginChecks);
+
+ return new LinkedList<>(combinedUpgradeChecks);
}
/**
- * Gets an ordered and filtered list of the upgrade checks.
- * @param upgradePack Upgrade pack object with the list of required checks to be included
- * @return
+ * Uses the library classloader from the the target stack in order to find any
+ * plugin-in {@link UpgradeCheck}s which are declared in the upgrade pack.
+ *
+ * @param upgradePack
+ * the upgrade pack which defines the upgrade check classes.
+ * @param pluginChecks
+ * the collection to popoulate.
*/
- public List<UpgradeCheck> getFilteredUpgradeChecks(UpgradePack upgradePack){
- List<String> prerequisiteChecks = upgradePack.getPrerequisiteChecks();
- List<UpgradeCheck> resultCheckDescriptor = new ArrayList<>();
- for (UpgradeCheck descriptor: m_upgradeChecks){
- if (isRequired(descriptor, upgradePack.getType())) {
- resultCheckDescriptor.add(descriptor);
- } else if (prerequisiteChecks.contains(descriptor.getClass().getName())){
- resultCheckDescriptor.add(descriptor);
+ @SuppressWarnings("unchecked")
+ private void loadPluginUpgradeChecksFromStack(UpgradePack upgradePack,
+ Set<UpgradeCheck> pluginChecks) throws AmbariException {
+ List<String> pluginCheckClassNames = upgradePack.getPrerequisiteChecks();
+ StackId ownerStackId = upgradePack.getOwnerStackId();
+ StackInfo stackInfo = metainfoProvider.get().getStack(ownerStackId);
+
+ ClassLoader classLoader = stackInfo.getLibraryClassLoader();
+ if (null != classLoader) {
+ for (String pluginCheckClassName : pluginCheckClassNames) {
+ try {
+ Class<? extends UpgradeCheck> upgradeCheckClass = (Class<? extends UpgradeCheck>) classLoader.loadClass(
+ pluginCheckClassName);
+
+ UpgradeCheck upgradeCheck = m_injector.getInstance(upgradeCheckClass);
+ pluginChecks.add(upgradeCheck);
+
+ LOG.info("Registered pre-upgrade check {} for stack {}", upgradeCheckClass, ownerStackId);
+ } catch (Exception exception) {
+ LOG.error("Unable to load the upgrade check {}", pluginCheckClassName, exception);
+ }
}
+ } else {
+ LOG.error(
+ "Unable to perform the following upgrade checks because no libraries could be loaded for the {} stack: {}",
+ ownerStackId, StringUtils.join(pluginCheckClassNames, ","));
}
- return resultCheckDescriptor;
}
/**
- * Gets whether the upgrade check is required for the specified
- * {@link UpgradeType}. Checks which are marked as required do not need to be
- * explicitely declared in the {@link UpgradePack} to be run.
- *
- * @return {@code true} if it is required, {@code false} otherwise.
+ * Gets whether a built-in upgrade check is required to run.
*/
- public static boolean isRequired(UpgradeCheck upgradeCheck, UpgradeType upgradeType) {
- UpgradeType[] upgradeTypes = upgradeCheck.getClass().getAnnotation(UpgradeCheckInfo.class).required();
- for (UpgradeType requiredType : upgradeTypes) {
- if (upgradeType == requiredType) {
- return true;
- }
+ private boolean isBuiltInCheckRequired(UpgradeCheck upgradeCheck, UpgradeType upgradeType) {
+ if (upgradeType == null) {
+ return true;
}
- return false;
- }
+ UpgradeCheckInfo annotation = upgradeCheck.getClass().getAnnotation(UpgradeCheckInfo.class);
+ if (null == annotation) {
+ return false;
+ }
+ UpgradeType[] upgradeTypes = annotation.required();
+ return ArrayUtils.contains(upgradeTypes, upgradeType);
+ }
/**
* THe {@link PreUpgradeCheckComparator} class is used to compare
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistryProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistryProvider.java
new file mode 100644
index 0000000..d83e0f1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistryProvider.java
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.checks;
+
+import java.util.Set;
+
+import org.apache.ambari.spi.upgrade.UpgradeCheck;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+import org.springframework.util.ClassUtils;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Provider;
+
+/**
+ * The {@link UpgradeCheckRegistryProvider} is a provider which binds any
+ * requests for the {@link UpgradeCheckRegistry}. When first requested, it will
+ * perform a classpath scan looking for instances of {@link UpgradeCheck} and
+ * then return an initialized {@link UpgradeCheckRegistry}.
+ */
+public class UpgradeCheckRegistryProvider implements Provider<UpgradeCheckRegistry> {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(UpgradeCheckRegistryProvider.class);
+
+ /**
+ * Used to injecting members into the {@link UpgradeCheck} instances which are
+ * discovered.
+ */
+ @Inject
+ private Injector m_injector;
+
+ /**
+ * The singleton registry to inject with found checks.
+ */
+ private UpgradeCheckRegistry m_checkRegistry;
+
+ /**
+ * The scanned instances of {@link UpgradeCheck} from the classpath.
+ */
+ private Set<BeanDefinition> m_beanDefinitions = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UpgradeCheckRegistry get() {
+ if (null == m_beanDefinitions || m_beanDefinitions.isEmpty()) {
+ String packageName = ClusterCheck.class.getPackage().getName();
+ LOG.info("Searching package {} for classes matching {}", packageName, UpgradeCheck.class);
+
+ ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+
+ // match all implementations of the base check class
+ AssignableTypeFilter filter = new AssignableTypeFilter(UpgradeCheck.class);
+ scanner.addIncludeFilter(filter);
+
+ m_beanDefinitions = scanner.findCandidateComponents(packageName);
+ }
+
+ // no checks is a problem
+ if (null == m_beanDefinitions || m_beanDefinitions.size() == 0) {
+ LOG.error("No instances of {} found to register", UpgradeCheck.class);
+ return null;
+ }
+
+ m_checkRegistry = new UpgradeCheckRegistry();
+ m_injector.injectMembers(m_checkRegistry);
+
+ // for every discovered check, singleton-ize them and register with the
+ // registry
+ for (BeanDefinition beanDefinition : m_beanDefinitions) {
+ String className = beanDefinition.getBeanClassName();
+ Class<?> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
+
+ try {
+ UpgradeCheck upgradeCheck = (UpgradeCheck) m_injector.getInstance(clazz);
+ m_checkRegistry.register(upgradeCheck);
+
+ LOG.info("Registered pre-upgrade check {}", upgradeCheck.getClass());
+ } catch (Exception exception) {
+ LOG.error("Unable to bind and register upgrade check {}", clazz, exception);
+ }
+ }
+
+ return m_checkRegistry;
+ }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeTypeQualification.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeTypeQualification.java
new file mode 100644
index 0000000..cd4d039
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeTypeQualification.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.checks;
+
+import org.apache.ambari.annotations.UpgradeCheckInfo;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.spi.upgrade.CheckQualification;
+import org.apache.ambari.spi.upgrade.UpgradeCheck;
+import org.apache.ambari.spi.upgrade.UpgradeCheckRequest;
+import org.apache.ambari.spi.upgrade.UpgradeType;
+import org.apache.commons.lang.ArrayUtils;
+
+/**
+ * The {@link UpgradeTypeQualification} class is used to determine if the check
+ * is required to run based on the {@link UpgradeType}. {@link UpgradeCheck}s
+ * which do not specify any {@link UpgradeType}s will always return
+ * {@code true}.
+ */
+ public final class UpgradeTypeQualification implements CheckQualification {
+
+ private final Class<? extends UpgradeCheck> m_checkClass;
+
+ /**
+ * Constructor.
+ *
+ * @param checkClass
+ * the class of the check which is being considered for
+ * applicability.
+ */
+ public UpgradeTypeQualification(Class<? extends UpgradeCheck> checkClass) {
+ m_checkClass = checkClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isApplicable(UpgradeCheckRequest request) throws AmbariException {
+ UpgradeType upgradeType = request.getUpgradeType();
+
+ UpgradeCheckInfo annotation = m_checkClass.getAnnotation(UpgradeCheckInfo.class);
+ if (null == annotation) {
+ return true;
+ }
+
+ // empty upgrade type or matching should return true
+ UpgradeType[] upgradeTypes = annotation.required();
+ return (ArrayUtils.isEmpty(upgradeTypes) || ArrayUtils.contains(upgradeTypes, upgradeType));
+ }
+}
\ No newline at end of file
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/cleanup/ClasspathScannerUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/cleanup/ClasspathScannerUtils.java
index 913d026..7057378 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/cleanup/ClasspathScannerUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/cleanup/ClasspathScannerUtils.java
@@ -40,17 +40,41 @@ public class ClasspathScannerUtils {
/**
* Scans the classpath for classes based on the provided arguments
*
- * @param packageName the package to be scanned
- * @param exclusions a list with classes excluded from the result
- * @param selectors a list with annotation and interface classes that identify classes to be found (lookup criteria)
+ * @param packageName
+ * the package to be scanned
+ * @param exclusions
+ * a list with classes excluded from the result
+ * @param selectors
+ * a list with annotation and interface classes that identify classes
+ * to be found (lookup criteria)
* @return a list of classes from the classpath that match the lookup criteria
*/
public static Set<Class<?>> findOnClassPath(String packageName, List<Class<?>> exclusions,
List<Class<?>> selectors) {
+ return ClasspathScannerUtils.findOnClassPath(ClasspathScannerUtils.class.getClassLoader(),
+ packageName, exclusions, selectors);
+ }
+
+ /**
+ * Scans the classpath for classes based on the provided arguments
+ *
+ * @param classLoader
+ * the classloader which should be used for searching.
+ * @param packageName
+ * the package to be scanned
+ * @param exclusions
+ * a list with classes excluded from the result
+ * @param selectors
+ * a list with annotation and interface classes that identify classes
+ * to be found (lookup criteria)
+ * @return a list of classes from the classpath that match the lookup criteria
+ */
+ public static Set<Class<?>> findOnClassPath(ClassLoader classLoader, String packageName,
+ List<Class<?>> exclusions, List<Class<?>> selectors) {
Set<Class<?>> bindingSet = new LinkedHashSet<>();
try {
- ClassPath classpath = ClassPath.from(ClasspathScannerUtils.class.getClassLoader());
+ ClassPath classpath = ClassPath.from(classLoader);
LOGGER.info("Checking package [{}] for binding candidates.", packageName);
for (ClassPath.ClassInfo classInfo : classpath.getTopLevelClassesRecursive(packageName)) {
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index a821253..176e709 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -55,9 +55,9 @@ import org.apache.ambari.server.actionmanager.HostRoleCommandFactoryImpl;
import org.apache.ambari.server.actionmanager.RequestFactory;
import org.apache.ambari.server.actionmanager.StageFactory;
import org.apache.ambari.server.actionmanager.StageFactoryImpl;
-import org.apache.ambari.server.checks.ClusterCheck;
import org.apache.ambari.server.checks.DatabaseConsistencyCheckHelper;
import org.apache.ambari.server.checks.UpgradeCheckRegistry;
+import org.apache.ambari.server.checks.UpgradeCheckRegistryProvider;
import org.apache.ambari.server.cleanup.ClasspathScannerUtils;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType;
@@ -161,7 +161,6 @@ import org.apache.ambari.server.topology.SecurityConfigurationFactory;
import org.apache.ambari.server.topology.tasks.ConfigureClusterTaskFactory;
import org.apache.ambari.server.utils.PasswordUtils;
import org.apache.ambari.server.view.ViewInstanceHandlerList;
-import org.apache.ambari.spi.upgrade.UpgradeCheck;
import org.eclipse.jetty.server.session.SessionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -179,6 +178,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
+import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.name.Names;
import com.google.inject.persist.PersistModule;
@@ -406,7 +406,8 @@ public class ControllerModule extends AbstractModule {
bindByAnnotation(null);
bindNotificationDispatchers(null);
- registerUpgradeChecks(null);
+
+ bind(UpgradeCheckRegistry.class).toProvider(UpgradeCheckRegistryProvider.class).in(Singleton.class);
bind(HookService.class).to(UserHookService.class);
InternalAuthenticationInterceptor ambariAuthenticationInterceptor = new InternalAuthenticationInterceptor();
@@ -670,59 +671,4 @@ public class ControllerModule extends AbstractModule {
return beanDefinitions;
}
-
- /**
- * Searches for all instances of {@link UpgradeCheck} on the
- * classpath and registers each as a singleton with the
- * {@link UpgradeCheckRegistry}.
- */
- @SuppressWarnings("unchecked")
- protected Set<BeanDefinition> registerUpgradeChecks(Set<BeanDefinition> beanDefinitions) {
-
- // make the registry a singleton
- UpgradeCheckRegistry registry = new UpgradeCheckRegistry();
- bind(UpgradeCheckRegistry.class).toInstance(registry);
-
- if (null == beanDefinitions || beanDefinitions.isEmpty()) {
- String packageName = ClusterCheck.class.getPackage().getName();
- LOG.info("Searching package {} for classes matching {}", packageName,
- UpgradeCheck.class);
-
- ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
-
- // match all implementations of the base check class
- AssignableTypeFilter filter = new AssignableTypeFilter(UpgradeCheck.class);
- scanner.addIncludeFilter(filter);
-
- beanDefinitions = scanner.findCandidateComponents(packageName);
- }
-
- // no dispatchers is a problem
- if (null == beanDefinitions || beanDefinitions.size() == 0) {
- LOG.error("No instances of {} found to register", UpgradeCheck.class);
- return null;
- }
-
- // for every discovered check, singleton-ize them and register with the
- // registry
- for (BeanDefinition beanDefinition : beanDefinitions) {
- String className = beanDefinition.getBeanClassName();
- Class<?> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
-
- try {
- UpgradeCheck upgradeCheck = (UpgradeCheck) clazz.newInstance();
- bind((Class<UpgradeCheck>) clazz).toInstance(upgradeCheck);
- registry.register(upgradeCheck);
- } catch (Exception exception) {
- LOG.error("Unable to bind and register upgrade check {}", clazz, exception);
- }
- }
-
- // log the order of the pre-upgrade checks
- List<UpgradeCheck> upgradeChecks = registry.getUpgradeChecks();
- for (UpgradeCheck upgradeCheck : upgradeChecks) {
- LOG.info("Registered pre-upgrade check {}", upgradeCheck.getClass());
- }
- return beanDefinitions;
- }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
index 2b5e0e9..333e0d7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
@@ -25,7 +25,6 @@ import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ParentObjectNotFoundException;
import org.apache.ambari.server.StaticallyInject;
import org.apache.ambari.server.checks.UpgradeCheckRegistry;
import org.apache.ambari.server.configuration.Configuration;
@@ -51,7 +50,6 @@ import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.spi.ClusterInformation;
import org.apache.ambari.spi.RepositoryVersion;
@@ -104,8 +102,12 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
@Inject
private static RepositoryVersionDAO repositoryVersionDAO;
+ /**
+ * Used a {@link Provider} around this instance to force lazy loading so it
+ * doesn't hold up Ambari's startup process.
+ */
@Inject
- private static UpgradeCheckRegistry upgradeCheckRegistry;
+ private static Provider<UpgradeCheckRegistry> upgradeCheckRegistryProvider;
@Inject
private static Provider<UpgradeHelper> upgradeHelper;
@@ -249,27 +251,20 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
upgradeCheckRequest.setRevert(forRevert);
}
- // ToDo: properly handle exceptions, i.e. create fake check with error description
- List<UpgradeCheck> upgradeChecksToRun = upgradeCheckRegistry.getFilteredUpgradeChecks(upgradePack);
+ UpgradeCheckRegistry upgradeCheckRegistry = upgradeCheckRegistryProvider.get();
+ // ToDo: properly handle exceptions, i.e. create fake check with error description
+ final List<UpgradeCheck> upgradeChecksToRun;
try {
- // Register all the custom prechecks from the services
- Map<String, ServiceInfo> services = getManagementController().getAmbariMetaInfo().getServices(
- sourceStackId.getStackName(), sourceStackId.getStackVersion());
-
- List<UpgradeCheck> serviceLevelUpgradeChecksToRun = upgradeCheckRegistry.getServiceLevelUpgradeChecks(
- upgradePack, services);
-
- upgradeChecksToRun.addAll(serviceLevelUpgradeChecksToRun);
- } catch (ParentObjectNotFoundException parentNotFoundException) {
- LOG.error("Invalid stack version: {}", sourceStackId, parentNotFoundException);
+ upgradeChecksToRun = upgradeCheckRegistry.getFilteredUpgradeChecks(upgradePack);
} catch (AmbariException ambariException) {
- LOG.error("Unable to register all the custom prechecks from the services", ambariException);
- } catch (Exception e) {
- LOG.error("Failed to register custom prechecks for the services", e);
+ throw new SystemException("Unable to load upgrade checks", ambariException);
}
- for (UpgradeCheckResult prerequisiteCheck : checkHelper.performChecks(upgradeCheckRequest, upgradeChecksToRun, config.get())) {
+ List<UpgradeCheckResult> results = checkHelper.performChecks(upgradeCheckRequest,
+ upgradeChecksToRun, config.get());
+
+ for (UpgradeCheckResult prerequisiteCheck : results) {
final Resource resource = new ResourceImpl(Resource.Type.PreUpgradeCheck);
setResourceProperty(resource, UPGRADE_CHECK_ID_PROPERTY_ID, prerequisiteCheck.getId(), requestedIds);
setResourceProperty(resource, UPGRADE_CHECK_CHECK_PROPERTY_ID, prerequisiteCheck.getDescription(), requestedIds);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
index f195b0c..89eec37 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
@@ -21,12 +21,23 @@ package org.apache.ambari.server.stack;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nullable;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.stack.upgrade.ConfigUpgradePack;
@@ -39,6 +50,7 @@ import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.ClassUtils;
/**
* Encapsulates IO operations on a stack definition stack directory.
@@ -56,6 +68,13 @@ public class StackDirectory extends StackDefinitionDirectory {
public static final String SERVICE_METRIC_FILE_NAME = "metrics.json";
public static final String SERVICE_ALERT_FILE_NAME = "alerts.json";
public static final String SERVICE_ADVISOR_FILE_NAME = "service_advisor.py";
+
+ /**
+ * Allows stacks to provide their own JARs, such as those which implement
+ * classes in the SPI.
+ */
+ public static final String LIB_FOLDER_NAME = "lib";
+
/**
* The filename for a Kerberos descriptor preconfigure file at either the stack or service level
*/
@@ -76,6 +95,12 @@ public class StackDirectory extends StackDefinitionDirectory {
private String rcoFilePath;
/**
+ * The fully-qualified path to the stack's library directory where JARs can be
+ * provided, such as those which implement the SPI.
+ */
+ private String libraryDir;
+
+ /**
* kerberos descriptor (preconfigure) file path
*/
private String kerberosDescriptorPreconfigureFilePath;
@@ -116,6 +141,12 @@ public class StackDirectory extends StackDefinitionDirectory {
private StackMetainfoXml metaInfoXml;
/**
+ * A {@link ClassLoader} for any JARs discovered in the stack's library
+ * folder.
+ */
+ private URLClassLoader libraryClassLoader;
+
+ /**
* file unmarshaller
*/
ModuleFileUnmarshaller unmarshaller = new ModuleFileUnmarshaller();
@@ -133,11 +164,6 @@ public class StackDirectory extends StackDefinitionDirectory {
private final static String REPOSITORY_FOLDER_NAME = "repos";
/**
- * repository file name
- */
- private final static String REPOSITORY_FILE_NAME = "repoinfo.xml";
-
- /**
* metainfo file name
*/
private static final String STACK_METAINFO_FILE_NAME = "metainfo.xml";
@@ -148,11 +174,6 @@ public class StackDirectory extends StackDefinitionDirectory {
private static final String UPGRADE_PACK_FOLDER_NAME = "upgrades";
/**
- * role command order file name
- */
- private static final String ROLE_COMMAND_ORDER_FILE = "role_command_order.json";
-
- /**
* logger instance
*/
private final static Logger LOG = LoggerFactory.getLogger(StackDirectory.class);
@@ -197,6 +218,15 @@ public class StackDirectory extends StackDefinitionDirectory {
}
/**
+ * Gets the fully qualified path to the stack's library directory.
+ *
+ * @return the library directory.
+ */
+ public String getLibraryPath() {
+ return libraryDir;
+ }
+
+ /**
* Obtain the path to the (stack-level) Kerberos descriptor pre-configuration file
*
* @return the path to the (stack-level) Kerberos descriptor pre-configuration file
@@ -267,6 +297,17 @@ public class StackDirectory extends StackDefinitionDirectory {
}
/**
+ * Gets the {@link ClassLoader} that can be used to load classes found in JARs
+ * in the stack's library folder.
+ *
+ * @return the class loader for 3rd party JARs supplied by the stack or
+ * {@code null} if there are no libraries for this stack.
+ */
+ public @Nullable ClassLoader getLibraryClassLoader() {
+ return libraryClassLoader;
+ }
+
+ /**
* Parse the stack directory.
*
* @throws AmbariException if unable to parse the directory
@@ -278,6 +319,10 @@ public class StackDirectory extends StackDefinitionDirectory {
rcoFilePath = getAbsolutePath() + File.separator + RCO_FILE_NAME;
}
+ if (subDirs.contains(LIB_FOLDER_NAME)) {
+ libraryDir = getAbsolutePath() + File.separator + LIB_FOLDER_NAME;
+ }
+
if (subDirs.contains(KERBEROS_DESCRIPTOR_PRECONFIGURE_FILE_NAME)) {
// kerberosDescriptorPreconfigureFilePath is expected to be absolute
kerberosDescriptorPreconfigureFilePath = getAbsolutePath() + File.separator + KERBEROS_DESCRIPTOR_PRECONFIGURE_FILE_NAME;
@@ -288,6 +333,8 @@ public class StackDirectory extends StackDefinitionDirectory {
parseRepoFile(subDirs);
parseMetaInfoFile();
parseRoleCommandOrder();
+ parseLibraryClassLoader();
+
}
/**
@@ -478,4 +525,39 @@ public class StackDirectory extends StackDefinitionDirectory {
LOG.error(String.format("Can not read role command order info %s", rcoFilePath), e);
}
}
+
+ /**
+ * Loads any classes found in the {@link #libraryDir} and creates a
+ * {@link URLClassLoader} for them.
+ */
+ private void parseLibraryClassLoader() {
+ if (null == libraryDir) {
+ return;
+ }
+
+ Path libraryPath = Paths.get(libraryDir);
+ if (Files.notExists(libraryPath) || !Files.isDirectory(libraryPath)) {
+ return;
+ }
+
+ try {
+ List<URI> jarUris = Files.list(libraryPath).filter(
+ file -> file.toString().endsWith(".jar")).map(Path::toUri).collect(Collectors.toList());
+
+ List<URL> jarUrls = new ArrayList<>(jarUris.size());
+ for (URI jarUri : jarUris) {
+ try {
+ jarUrls.add(jarUri.toURL());
+ } catch (MalformedURLException malformedURLException) {
+ LOG.error("Unable to load the stack library {}", jarUri, malformedURLException);
+ }
+ }
+
+ URL[] jarUrlArray = new URL[jarUris.size()];
+ libraryClassLoader = new URLClassLoader(jarUrls.toArray(jarUrlArray),
+ ClassUtils.getDefaultClassLoader());
+ } catch (IOException ioException) {
+ LOG.error("Unable to load libraries from {}", libraryPath, ioException);
+ }
+ }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index 5c79117..09624a9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -158,7 +158,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
public StackModule(StackDirectory stackDirectory, StackContext stackContext) {
this.stackDirectory = stackDirectory;
this.stackContext = stackContext;
- this.stackInfo = new StackInfo();
+ stackInfo = new StackInfo();
populateStackInfo();
}
@@ -496,9 +496,9 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
setValid(false);
addError("The service '" + serviceInfo.getName() + "' in stack '" + stackInfo.getName() + ":"
+ stackInfo.getVersion() + "' extends a non-existent service: '" + parent + "'");
- }
- else
+ } else {
service.resolve(parentService, allStacks, commonServices, extensions);
+ }
}
}
@@ -574,6 +574,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
stackInfo.setUpgradePacks(stackDirectory.getUpgradePacks());
stackInfo.setConfigUpgradePack(stackDirectory.getConfigUpgradePack());
stackInfo.setRoleCommandOrder(stackDirectory.getRoleCommandOrder());
+ stackInfo.setLibraryClassLoader(stackDirectory.getLibraryClassLoader());
populateConfigurationModules();
}
@@ -1330,8 +1331,9 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
* @param service service
*/
private void mergeRoleCommandOrder(ServiceModule service) {
- if (service.getModuleInfo().getRoleCommandOrder() == null)
+ if (service.getModuleInfo().getRoleCommandOrder() == null) {
return;
+ }
stackInfo.getRoleCommandOrder().merge(service.getModuleInfo().getRoleCommandOrder(), true);
if (LOG.isDebugEnabled()) {
@@ -1394,7 +1396,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
@Override
public void addErrors(Collection<String> errors) {
- this.errorSet.addAll(errors);
+ errorSet.addAll(errors);
}
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/UpgradePack.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/UpgradePack.java
index 51051d7..075ff06 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/UpgradePack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/UpgradePack.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.function.Predicate;
import java.util.regex.Pattern;
@@ -41,6 +42,7 @@ import org.apache.ambari.server.stack.upgrade.Task.Type;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.spi.upgrade.UpgradeType;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -135,6 +137,38 @@ public class UpgradePack {
@XmlTransient
private StackId ownerStackId;
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, source, sourceStack, target, targetStack, ownerStackId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (!(object instanceof UpgradePack)) {
+ return false;
+ }
+
+ UpgradePack that = (UpgradePack) object;
+
+ return new EqualsBuilder()
+ .append(type, that.type)
+ .append(source, that.source)
+ .append(sourceStack, that.sourceStack)
+ .append(target, that.targetStack)
+ .append(ownerStackId, that.ownerStackId)
+ .isEquals();
+ }
+
public String getName() {
return name;
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeHelper.java
index 726fc17..fe79131 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeHelper.java
@@ -260,7 +260,7 @@ public class UpgradeHelper {
StackId upgradeStack = compareToSource ?
new StackId(upgradePack.getSourceStack()) : new StackId(upgradePack.getTargetStack());
- if (upgradeStack.equals(stackToFind)) {
+ if (upgradeStack.equals(stackToFind) && upgradePack.getType().equals(upgradeType)) {
if (null == result) {
result = upgradePack;
} else {
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
index 4d1b688..c4550fd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/CheckHelper.java
@@ -25,6 +25,7 @@ import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.checks.OrchestrationQualification;
+import org.apache.ambari.server.checks.UpgradeTypeQualification;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
@@ -81,7 +82,8 @@ public class CheckHelper {
// build some required qualifications
List<CheckQualification> qualifications = Lists.newArrayList(
new ServiceQualification(check),
- new OrchestrationQualification(check.getClass()));
+ new OrchestrationQualification(check.getClass()),
+ new UpgradeTypeQualification(check.getClass()));
// add any extras from the check
qualifications.addAll(check.getQualifications());
@@ -117,13 +119,13 @@ public class CheckHelper {
* @return list of pre-requisite check results
*/
public List<UpgradeCheckResult> performChecks(UpgradeCheckRequest request,
- List<UpgradeCheck> checksRegistry, Configuration config) {
+ List<UpgradeCheck> upgradeChecks, Configuration config) {
final String clusterName = request.getClusterName();
final List<UpgradeCheckResult> results = new ArrayList<>();
final boolean canBypassPreChecks = config.isUpgradePrecheckBypass();
- List<UpgradeCheck> applicablePreChecks = getApplicableChecks(request, checksRegistry);
+ List<UpgradeCheck> applicablePreChecks = getApplicableChecks(request, upgradeChecks);
for (UpgradeCheck check : applicablePreChecks) {
UpgradeCheckResult result = new UpgradeCheckResult(check);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index cc47a1a..679163a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -30,6 +30,8 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+
import org.apache.ambari.server.controller.StackVersionResponse;
import org.apache.ambari.server.stack.Validable;
import org.apache.ambari.server.stack.upgrade.ConfigUpgradePack;
@@ -52,9 +54,7 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
private String minUpgradeVersion;
private boolean active;
private String rcoFileLocation;
- private String kerberosDescriptorFileLocation;
private String kerberosDescriptorPreConfigurationFileLocation;
- private String widgetsDescriptorFileLocation;
private List<RepositoryInfo> repositories;
private Collection<ServiceInfo> services;
private Collection<ExtensionInfo> extensions;
@@ -69,11 +69,6 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
private Map<String, Map<PropertyInfo.PropertyType, Set<String>>> propertiesTypesCache =
Collections.synchronizedMap(new HashMap<String, Map<PropertyInfo.PropertyType, Set<String>>>());
private Map<String, Map<String, Map<String, String>>> configPropertyAttributes = null;
- /**
- * Meaning: stores subpath from stack root to exact hooks folder for stack. These hooks are
- * applied to all commands for services in current stack.
- */
- private String stackHooksFolder;
private String upgradesFolder = null;
private volatile Map<String, PropertyInfo> requiredProperties;
private Map<String, VersionDefinitionXml> versionDefinitions = new ConcurrentHashMap<>();
@@ -83,6 +78,12 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
private VersionDefinitionXml latestVersion = null;
/**
+ * A {@link ClassLoader} for any JARs discovered in the stack's library
+ * folder.
+ */
+ private ClassLoader libraryClassLoader = null;
+
+ /**
* List of services removed from current stack
* */
private List<String> removedServices = new ArrayList<>();
@@ -140,7 +141,7 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
@Override
public void addErrors(Collection<String> errors) {
- this.errorSet.addAll(errors);
+ errorSet.addAll(errors);
}
public String getName() {
@@ -160,7 +161,9 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
}
public List<RepositoryInfo> getRepositories() {
- if( repositories == null ) repositories = new ArrayList<>();
+ if( repositories == null ) {
+ repositories = new ArrayList<>();
+ }
return repositories;
}
@@ -172,7 +175,9 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
}
public synchronized Collection<ServiceInfo> getServices() {
- if (services == null) services = new ArrayList<>();
+ if (services == null) {
+ services = new ArrayList<>();
+ }
return services;
}
@@ -192,7 +197,9 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
}
public synchronized Collection<ExtensionInfo> getExtensions() {
- if (extensions == null) extensions = new ArrayList<>();
+ if (extensions == null) {
+ extensions = new ArrayList<>();
+ }
return extensions;
}
@@ -212,8 +219,9 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
for (ExtensionInfo extension : extensions) {
Collection<ServiceInfo> services = extension.getServices();
for (ServiceInfo service : services) {
- if (service.getName().equals(serviceName))
+ if (service.getName().equals(serviceName)) {
return extension;
+ }
}
}
//todo: exception?
@@ -239,7 +247,9 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
}
public List<PropertyInfo> getProperties() {
- if (properties == null) properties = new ArrayList<>();
+ if (properties == null) {
+ properties = new ArrayList<>();
+ }
return properties;
}
@@ -266,7 +276,7 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
* @param typeAttributes attributes associated with the type
*/
public synchronized void setConfigTypeAttributes(String type, Map<String, Map<String, String>> typeAttributes) {
- if (this.configTypes == null) {
+ if (configTypes == null) {
configTypes = new HashMap<>();
}
// todo: no exclusion mechanism for stack config types
@@ -506,8 +516,9 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
if (propertyInfo.getFilename().contains(configType) && !propertyInfo.getPropertyTypes().isEmpty()) {
Set<PropertyInfo.PropertyType> types = propertyInfo.getPropertyTypes();
for (PropertyInfo.PropertyType propertyType : types) {
- if (!propertiesTypes.containsKey(propertyType))
+ if (!propertiesTypes.containsKey(propertyType)) {
propertiesTypes.put(propertyType, new HashSet<>());
+ }
propertiesTypes.get(propertyType).add(propertyInfo.getName());
}
}
@@ -628,4 +639,26 @@ public class StackInfo implements Comparable<StackInfo>, Validable {
public Set<String> getServiceNames() {
return getServices().stream().map(ServiceInfo::getName).collect(Collectors.toSet());
}
+
+ /**
+ * Gets the {@link ClassLoader} that can be used to load classes found in JARs
+ * in the stack's library folder.
+ *
+ * @return the class loader for 3rd party JARs supplied by the stack or
+ * {@code null} if there are no libraries for this stack.
+ */
+ public @Nullable ClassLoader getLibraryClassLoader() {
+ return libraryClassLoader;
+ }
+
+ /**
+ * Sets the {@link ClassLoader} that can be used to load classes found in JARs
+ * in the stack's library folder.
+ *
+ * @param libraryClassLoader
+ * the class loader.
+ */
+ public void setLibraryClassLoader(ClassLoader libraryClassLoader) {
+ this.libraryClassLoader = libraryClassLoader;
+ }
}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index a975817..d06e4d0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -1986,7 +1986,6 @@ public class AmbariMetaInfoTest {
private static class TestAmbariMetaInfo extends AmbariMetaInfo {
- MetainfoDAO metaInfoDAO;
AlertDefinitionDAO alertDefinitionDAO;
AlertDefinitionFactory alertDefinitionFactory;
OsFamily osFamily;
@@ -2003,15 +2002,9 @@ public class AmbariMetaInfoTest {
Class<?> c = getClass().getSuperclass();
- // MetainfoDAO
- metaInfoDAO = injector.getInstance(MetainfoDAO.class);
- Field f = c.getDeclaredField("metaInfoDAO");
- f.setAccessible(true);
- f.set(this, metaInfoDAO);
-
// StackManagerFactory
StackManagerFactory stackManagerFactory = injector.getInstance(StackManagerFactory.class);
- f = c.getDeclaredField("stackManagerFactory");
+ Field f = c.getDeclaredField("stackManagerFactory");
f.setAccessible(true);
f.set(this, stackManagerFactory);
@@ -2073,7 +2066,7 @@ public class AmbariMetaInfoTest {
}
public void replayAllMocks() {
- replay(metaInfoDAO, alertDefinitionDAO);
+ replay(alertDefinitionDAO);
}
public class MockModule extends AbstractModule {
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/AutoStartDisabledCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/AutoStartDisabledCheckTest.java
index b3c4f58..8f55d5b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/AutoStartDisabledCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/AutoStartDisabledCheckTest.java
@@ -97,7 +97,7 @@ public class AutoStartDisabledCheckTest {
@Test
public void testIsApplicable() throws Exception {
- UpgradeCheckRequest request = new UpgradeCheckRequest(clusterInformation, null,
+ UpgradeCheckRequest request = new UpgradeCheckRequest(clusterInformation, UpgradeType.ROLLING,
repositoryVersion, m_configMap);
CheckHelper checkHelper = new CheckHelper();
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ClusterCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ClusterCheckTest.java
index 29102a2..786f03a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ClusterCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ClusterCheckTest.java
@@ -242,28 +242,6 @@ public class ClusterCheckTest extends EasyMockSupport {
Assert.assertTrue(m_mockCheckHelper.getApplicableChecks(request, Lists.newArrayList(check)).size() == 1);
}
- /**
- * Tests {@link UpgradeCheckRegistry#isRequired(org.apache.ambari.spi.upgrade.UpgradeCheck, UpgradeType)}
- *
- * @throws Exception
- */
- @Test
- public void testRequired() throws Exception {
- RollingTestCheckImpl rollingCheck = new RollingTestCheckImpl(UpgradeCheckType.SERVICE);
- Assert.assertTrue(UpgradeCheckRegistry.isRequired(rollingCheck, UpgradeType.ROLLING));
- Assert.assertFalse(UpgradeCheckRegistry.isRequired(rollingCheck, UpgradeType.NON_ROLLING));
-
- NotRequiredCheckTest notRequiredCheck = new NotRequiredCheckTest(UpgradeCheckType.SERVICE);
- Assert.assertFalse(UpgradeCheckRegistry.isRequired(notRequiredCheck, UpgradeType.ROLLING));
- Assert.assertFalse(UpgradeCheckRegistry.isRequired(notRequiredCheck, UpgradeType.NON_ROLLING));
- Assert.assertFalse(UpgradeCheckRegistry.isRequired(notRequiredCheck, UpgradeType.HOST_ORDERED));
-
- TestCheckImpl requiredCheck = new TestCheckImpl(UpgradeCheckType.SERVICE);
- Assert.assertTrue(UpgradeCheckRegistry.isRequired(requiredCheck, UpgradeType.ROLLING));
- Assert.assertTrue(UpgradeCheckRegistry.isRequired(requiredCheck, UpgradeType.NON_ROLLING));
- Assert.assertTrue(UpgradeCheckRegistry.isRequired(requiredCheck, UpgradeType.HOST_ORDERED));
- }
-
@UpgradeCheckInfo(
group = UpgradeCheckGroup.DEFAULT,
order = 1.0f,
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
index faaf01f..5448d23 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
@@ -66,7 +66,7 @@ public class UpgradeCheckOrderTest {
Assert.assertEquals(registry, registry2);
// get the check list
- List<UpgradeCheck> checks = registry.getUpgradeChecks();
+ List<UpgradeCheck> checks = registry.getBuiltInUpgradeChecks();
// scan for all checks
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
@@ -77,6 +77,8 @@ public class UpgradeCheckOrderTest {
Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents("org.apache.ambari.server.checks");
// verify they are equal
+ Assert.assertTrue(checks.size() > 0);
+ Assert.assertTrue(beanDefinitions.size() > 0);
Assert.assertEquals(beanDefinitions.size(), checks.size());
UpgradeCheck lastCheck = null;
@@ -85,7 +87,6 @@ public class UpgradeCheckOrderTest {
UpgradeCheckGroup lastGroup = UpgradeCheckGroup.DEFAULT;
if (null != lastCheck) {
-
UpgradeCheckInfo annotation = check.getClass().getAnnotation(UpgradeCheckInfo.class);
UpgradeCheckInfo lastAnnotation = lastCheck.getClass().getAnnotation(UpgradeCheckInfo.class);
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeTypeQualificationTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeTypeQualificationTest.java
new file mode 100644
index 0000000..baa01d3
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeTypeQualificationTest.java
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.checks;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.annotations.UpgradeCheckInfo;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.spi.upgrade.CheckQualification;
+import org.apache.ambari.spi.upgrade.UpgradeCheck;
+import org.apache.ambari.spi.upgrade.UpgradeCheckDescription;
+import org.apache.ambari.spi.upgrade.UpgradeCheckGroup;
+import org.apache.ambari.spi.upgrade.UpgradeCheckRequest;
+import org.apache.ambari.spi.upgrade.UpgradeCheckResult;
+import org.apache.ambari.spi.upgrade.UpgradeCheckType;
+import org.apache.ambari.spi.upgrade.UpgradeType;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+/**
+ * Tests the {@link UpgradeTypeQualification}.
+ */
+public class UpgradeTypeQualificationTest {
+
+ /**
+ * Tests whether the {@link UpgradeCheckInfo} annotation is correctly
+ * analyzed.
+ */
+ @Test
+ public void testRequired() throws Exception {
+ UpgradeCheckRequest rolling = new UpgradeCheckRequest(null, UpgradeType.ROLLING, null, null);
+ UpgradeCheckRequest express = new UpgradeCheckRequest(null, UpgradeType.NON_ROLLING, null, null);
+
+ UpgradeTypeQualification rollingQualification = new UpgradeTypeQualification(RollingTestCheckImpl.class);
+
+ Assert.assertTrue(rollingQualification.isApplicable(rolling));
+ Assert.assertFalse(rollingQualification.isApplicable(express));
+
+ UpgradeTypeQualification notRequiredQualification = new UpgradeTypeQualification(NotRequiredCheckTest.class);
+ Assert.assertTrue(notRequiredQualification.isApplicable(rolling));
+ Assert.assertTrue(notRequiredQualification.isApplicable(express));
+ }
+
+ @UpgradeCheckInfo(
+ group = UpgradeCheckGroup.DEFAULT,
+ order = 1.0f,
+ required = { UpgradeType.ROLLING })
+ private class RollingTestCheckImpl implements UpgradeCheck {
+
+ @Override
+ public Set<String> getApplicableServices() {
+ return null;
+ }
+
+ @Override
+ public List<CheckQualification> getQualifications() {
+ return null;
+ }
+
+ @Override
+ public UpgradeCheckResult perform(UpgradeCheckRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public UpgradeCheckType getType() {
+ return null;
+ }
+
+ @Override
+ public UpgradeCheckDescription getCheckDescription() {
+ return null;
+ }
+ }
+
+ @UpgradeCheckInfo(group = UpgradeCheckGroup.DEFAULT, order = 1.0f)
+ private class NotRequiredCheckTest implements UpgradeCheck {
+ @Override
+ public Set<String> getApplicableServices() {
+ return null;
+ }
+
+ @Override
+ public List<CheckQualification> getQualifications() {
+ return null;
+ }
+
+ @Override
+ public UpgradeCheckResult perform(UpgradeCheckRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public UpgradeCheckType getType() {
+ return null;
+ }
+
+ @Override
+ public UpgradeCheckDescription getCheckDescription() {
+ return null;
+ }
+ }
+
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProviderTest.java
index 7a9fd3f..4f5e298 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProviderTest.java
@@ -18,10 +18,9 @@
package org.apache.ambari.server.controller.internal;
-import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.util.Collections;
@@ -35,42 +34,74 @@ import java.util.Set;
import javax.persistence.EntityManager;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.actionmanager.ActionDBAccessor;
+import org.apache.ambari.server.actionmanager.ActionManager;
+import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
+import org.apache.ambari.server.actionmanager.RequestFactory;
+import org.apache.ambari.server.actionmanager.StageFactory;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.audit.AuditLogger;
import org.apache.ambari.server.checks.UpgradeCheckRegistry;
-import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.checks.UpgradeCheckRegistryProvider;
+import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory;
import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
+import org.apache.ambari.server.controller.KerberosHelperImpl;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.hooks.HookContextFactory;
+import org.apache.ambari.server.hooks.HookService;
+import org.apache.ambari.server.metadata.RoleCommandOrderProvider;
+import org.apache.ambari.server.mpack.MpackManagerFactory;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.sample.checks.SampleServiceCheck;
+import org.apache.ambari.server.scheduler.ExecutionScheduler;
+import org.apache.ambari.server.security.encryption.CredentialStoreService;
+import org.apache.ambari.server.serveraction.kerberos.KerberosConfigDataFileWriterFactory;
+import org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDataFileWriterFactory;
import org.apache.ambari.server.stack.StackManagerFactory;
import org.apache.ambari.server.stack.upgrade.Direction;
import org.apache.ambari.server.stack.upgrade.UpgradePack;
import org.apache.ambari.server.stack.upgrade.UpgradePack.PrerequisiteCheckConfig;
import org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeHelper;
+import org.apache.ambari.server.stageplanner.RoleGraphFactory;
import org.apache.ambari.server.state.CheckHelper;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigFactory;
+import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponentFactory;
import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
+import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.topology.PersistedState;
+import org.apache.ambari.server.topology.TopologyManager;
+import org.apache.ambari.server.topology.tasks.ConfigureClusterTaskFactory;
import org.apache.ambari.spi.RepositoryType;
-import org.apache.ambari.spi.upgrade.UpgradeCheck;
import org.apache.ambari.spi.upgrade.UpgradeCheckStatus;
import org.apache.ambari.spi.upgrade.UpgradeCheckType;
import org.apache.ambari.spi.upgrade.UpgradeType;
+import org.apache.commons.lang3.StringUtils;
+import org.easymock.EasyMockSupport;
import org.junit.Assert;
import org.junit.Test;
+import org.springframework.security.crypto.password.PasswordEncoder;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -82,16 +113,18 @@ import com.google.inject.Provider;
/**
* PreUpgradeCheckResourceProvider tests.
*/
-public class PreUpgradeCheckResourceProviderTest {
+public class PreUpgradeCheckResourceProviderTest extends EasyMockSupport {
+
+ private static final String TEST_SERVICE_CHECK_CLASS_NAME = "org.apache.ambari.server.sample.checks.SampleServiceCheck";
@Test
+ @SuppressWarnings({ "rawtypes", "unchecked" })
public void testGetResources() throws Exception{
Injector injector = createInjector();
AmbariManagementController managementController = injector.getInstance(AmbariManagementController.class);
Clusters clusters = injector.getInstance(Clusters.class);
UpgradeHelper upgradeHelper = injector.getInstance(UpgradeHelper.class);
- Configuration configuration = injector.getInstance(Configuration.class);
RepositoryVersionDAO repoDao = injector.getInstance(RepositoryVersionDAO.class);
RepositoryVersionEntity repo = createNiceMock(RepositoryVersionEntity.class);
@@ -104,8 +137,9 @@ public class PreUpgradeCheckResourceProviderTest {
StackId currentStackId = createNiceMock(StackId.class);
StackId targetStackId = createNiceMock(StackId.class);
- ServiceFactory serviceFactory = createNiceMock(ServiceFactory.class);
- AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class);
+ AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ ambariMetaInfo.init();
+ expectLastCall().anyTimes();
Config actualConfig = createNiceMock(Config.class);
DesiredConfig desiredConfig = createNiceMock(DesiredConfig.class);
@@ -130,7 +164,6 @@ public class PreUpgradeCheckResourceProviderTest {
serviceComponentHosts.add(serviceComponentHost);
expect(cluster.getServiceComponentHosts()).andReturn(serviceComponentHosts).atLeastOnce();
- expect(configuration.isUpgradePrecheckBypass()).andReturn(false).anyTimes();
// set expectations
expect(managementController.getClusters()).andReturn(clusters).anyTimes();
expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
@@ -154,21 +187,28 @@ public class PreUpgradeCheckResourceProviderTest {
expect(repo.getVersion()).andReturn("1.1.0.0").atLeastOnce();
expect(upgradeHelper.suggestUpgradePack("Cluster100", currentStackId, targetStackId, Direction.UPGRADE, UpgradeType.NON_ROLLING, "upgrade_pack11")).andReturn(upgradePack);
- List<UpgradeCheck> upgradeChecksToRun = new LinkedList<>();
List<String> prerequisiteChecks = new LinkedList<>();
- prerequisiteChecks.add("org.apache.ambari.server.sample.checks.SampleServiceCheck");
+ prerequisiteChecks.add(TEST_SERVICE_CHECK_CLASS_NAME);
expect(upgradePack.getPrerequisiteCheckConfig()).andReturn(config);
expect(upgradePack.getPrerequisiteChecks()).andReturn(prerequisiteChecks).anyTimes();
expect(upgradePack.getTarget()).andReturn("1.1.*.*").anyTimes();
+ expect(upgradePack.getOwnerStackId()).andReturn(targetStackId).atLeastOnce();
+ expect(upgradePack.getType()).andReturn(UpgradeType.ROLLING).atLeastOnce();
expect(ambariMetaInfo.getServices("Stack100", "1.0")).andReturn(allServiceInfoMap).anyTimes();
String checks = ClassLoader.getSystemClassLoader().getResource("checks").getPath();
expect(serviceInfo.getChecksFolder()).andReturn(new File(checks));
+ ClassLoader classLoader = createNiceMock(ClassLoader.class);
+ Class clazz = SampleServiceCheck.class;
+ expect(classLoader.loadClass(TEST_SERVICE_CHECK_CLASS_NAME)).andReturn(clazz).atLeastOnce();
+
+ StackInfo stackInfo = createNiceMock(StackInfo.class);
+ expect(ambariMetaInfo.getStack(targetStackId)).andReturn(stackInfo).atLeastOnce();
+ expect(stackInfo.getLibraryClassLoader()).andReturn(classLoader).atLeastOnce();
+
// replay
- replay(managementController, clusters, cluster, service, serviceInfo, repoDao, repo, upgradeHelper,
- ambariMetaInfo, upgradePack, config, currentStackId, targetStackId, serviceFactory,
- configuration, serviceComponentHost, actualConfig, desiredConfig);
+ replayAll();
ResourceProvider provider = getPreUpgradeCheckResourceProvider(managementController, injector);
// create the request
@@ -179,33 +219,40 @@ public class PreUpgradeCheckResourceProviderTest {
.property(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID).equals(UpgradeType.NON_ROLLING).and()
.property(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_TARGET_REPOSITORY_VERSION_ID_ID).equals("1").toPredicate();
-
- System.out.println("PreUpgradeCheckResourceProvider - " + provider);
Set<Resource> resources = Collections.emptySet();
resources = provider.getResources(request, predicate);
- Assert.assertEquals(1, resources.size());
+ // make sure all of the checks ran and were returned in the response; some
+ // of the checks are stripped out b/c they don't define any required upgrade
+ // types. The value being asserted here is a combination of built-in checks
+ // which are required for the upgrade type as well as any provided checks
+ // discovered in the stack
+ Assert.assertEquals(19, resources.size());
+
+ // find the service check provided by the library classloader and verify it ran
+ Resource customUpgradeCheck = null;
for (Resource resource : resources) {
String id = (String) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_ID_PROPERTY_ID);
- Assert.assertEquals("SAMPLE_SERVICE_CHECK", id);
- String description = (String) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CHECK_PROPERTY_ID);
- Assert.assertEquals("Sample service check description.", description);
- UpgradeCheckStatus status = (UpgradeCheckStatus) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_STATUS_PROPERTY_ID);
- Assert.assertEquals(UpgradeCheckStatus.FAIL, status);
- String reason = (String) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_REASON_PROPERTY_ID);
- Assert.assertEquals("Sample service check always fails.", reason);
- UpgradeCheckType checkType = (UpgradeCheckType) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID);
- Assert.assertEquals(UpgradeCheckType.HOST, checkType);
- String clusterName = (String) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID);
- Assert.assertEquals("Cluster100", clusterName);
- UpgradeType upgradeType = (UpgradeType) resource.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID);
- Assert.assertEquals(UpgradeType.NON_ROLLING, upgradeType);
+ if (StringUtils.equals(id, "SAMPLE_SERVICE_CHECK")) {
+ customUpgradeCheck = resource;
+ break;
+ }
}
- // verify
- verify(managementController, clusters, cluster, service, serviceInfo, repoDao, repo, upgradeHelper,
- ambariMetaInfo, upgradePack, config, currentStackId, targetStackId, serviceFactory,
- serviceComponentHost, actualConfig, desiredConfig);
+ assertNotNull(customUpgradeCheck);
+
+ String description = (String) customUpgradeCheck.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CHECK_PROPERTY_ID);
+ Assert.assertEquals("Sample service check description.", description);
+ UpgradeCheckStatus status = (UpgradeCheckStatus) customUpgradeCheck.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_STATUS_PROPERTY_ID);
+ Assert.assertEquals(UpgradeCheckStatus.FAIL, status);
+ String reason = (String) customUpgradeCheck.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_REASON_PROPERTY_ID);
+ Assert.assertEquals("Sample service check always fails.", reason);
+ UpgradeCheckType checkType = (UpgradeCheckType) customUpgradeCheck.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID);
+ Assert.assertEquals(UpgradeCheckType.HOST, checkType);
+ String clusterName = (String) customUpgradeCheck.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID);
+ Assert.assertEquals("Cluster100", clusterName);
+ UpgradeType upgradeType = (UpgradeType) customUpgradeCheck.getPropertyValue(PreUpgradeCheckResourceProvider.UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID);
+ Assert.assertEquals(UpgradeType.NON_ROLLING, upgradeType);
}
/**
@@ -218,53 +265,61 @@ public class PreUpgradeCheckResourceProviderTest {
return provider;
}
- static class TestClustersProvider implements Provider<Clusters> {
- private static Clusters clusters = createNiceMock(Clusters.class);
-
- @Override
- public Clusters get() {
- return clusters;
- }
- }
-
- static class TestConfigurationProvider implements Provider<Configuration> {
- private static Configuration configuration = createNiceMock(Configuration.class);
-
- @Override
- public Configuration get(){
- return configuration;
- }
- }
-
- static class TestUpgradeHelperProvider implements Provider<UpgradeHelper> {
- private static UpgradeHelper upgradeHelper = createNiceMock(UpgradeHelper.class);
-
- @Override
- public UpgradeHelper get() {
- return upgradeHelper;
- }
- }
-
private Injector createInjector() throws Exception {
return Guice.createInjector(new AbstractModule() {
+
@Override
+ @SuppressWarnings("unchecked")
protected void configure() {
- Provider<Clusters> clustersProvider = new TestClustersProvider();
- Provider<UpgradeHelper> upgradeHelperProvider = new TestUpgradeHelperProvider();
+ Clusters clusters = createNiceMock(Clusters.class);
+ Provider<Clusters> clusterProvider = () -> clusters;
+
+ UpgradeHelper upgradeHelper = createNiceMock(UpgradeHelper.class);
+ Provider<UpgradeHelper> upgradeHelperProvider = () -> upgradeHelper;
+
CheckHelper checkHelper = new CheckHelper();
- UpgradeCheckRegistry registry = new UpgradeCheckRegistry();
- bind(Configuration.class).toProvider(TestConfigurationProvider.class);
- bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class));
bind(CheckHelper.class).toInstance(checkHelper);
- bind(Clusters.class).toProvider(TestClustersProvider.class);
- bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class));
- bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
+ bind(Clusters.class).toProvider(clusterProvider);
+ bind(UpgradeCheckRegistry.class).toProvider(UpgradeCheckRegistryProvider.class);
+ bind(UpgradeHelper.class).toProvider(upgradeHelperProvider);
+ bind(KerberosHelper.class).to(KerberosHelperImpl.class);
+ bind(KerberosIdentityDataFileWriterFactory.class).toInstance(createNiceMock(KerberosIdentityDataFileWriterFactory.class));
+ bind(KerberosConfigDataFileWriterFactory.class).toInstance(createNiceMock(KerberosConfigDataFileWriterFactory.class));
+ bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class));
+ bind(ConfigHelper.class).toInstance(createNiceMock(ConfigHelper.class));
+ bind(HostRoleCommandDAO.class).toInstance(createNiceMock(HostRoleCommandDAO.class));
+ bind(ActionManager.class).toInstance(createNiceMock(ActionManager.class));
bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- bind(RepositoryVersionDAO.class).toInstance(createNiceMock(RepositoryVersionDAO.class));
+ bind(ExecutionScheduler.class).toInstance(createNiceMock(ExecutionScheduler.class));
+ bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class));
+ bind(ActionDBAccessor.class).toInstance(createNiceMock(ActionDBAccessor.class));
bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class));
- bind(UpgradeCheckRegistry.class).toInstance(registry);
- bind(UpgradeHelper.class).toProvider(TestUpgradeHelperProvider.class);
+ bind(ConfigFactory.class).toInstance(createNiceMock(ConfigFactory.class));
+ bind(ConfigGroupFactory.class).toInstance(createNiceMock(ConfigGroupFactory.class));
+ bind(CredentialStoreService.class).toInstance(createNiceMock(CredentialStoreService.class));
+ bind(RequestExecutionFactory.class).toInstance(createNiceMock(RequestExecutionFactory.class));
+ bind(RequestFactory.class).toInstance(createNiceMock(RequestFactory.class));
+ bind(RoleCommandOrderProvider.class).toInstance(createNiceMock(RoleCommandOrderProvider.class));
+ bind(RoleGraphFactory.class).toInstance(createNiceMock(RoleGraphFactory.class));
+ bind(AbstractRootServiceResponseFactory.class).toInstance(createNiceMock(AbstractRootServiceResponseFactory.class));
+ bind(ServiceComponentFactory.class).toInstance(createNiceMock(ServiceComponentFactory.class));
+ bind(ServiceComponentHostFactory.class).toInstance(createNiceMock(ServiceComponentHostFactory.class));
+ bind(StageFactory.class).toInstance(createNiceMock(StageFactory.class));
+ bind(HostRoleCommandFactory.class).toInstance(createNiceMock(HostRoleCommandFactory.class));
+ bind(HookContextFactory.class).toInstance(createNiceMock(HookContextFactory.class));
+ bind(HookService.class).toInstance(createNiceMock(HookService.class));
+ bind(PasswordEncoder.class).toInstance(createNiceMock(PasswordEncoder.class));
+ bind(PersistedState.class).toInstance(createNiceMock(PersistedState.class));
+ bind(ConfigureClusterTaskFactory.class).toInstance(createNiceMock(ConfigureClusterTaskFactory.class));
+ bind(TopologyManager.class).toInstance(createNiceMock(TopologyManager.class));
+ bind(AmbariMetaInfo.class).toInstance(createNiceMock(AmbariMetaInfo.class));
+ bind(AlertsDAO.class).toInstance(createNiceMock(AlertsDAO.class));
+ bind(AlertDefinitionDAO.class).toInstance(createNiceMock(AlertDefinitionDAO.class));
+ bind(RepositoryVersionDAO.class).toInstance(createNiceMock(RepositoryVersionDAO.class));
+ bind(MpackManagerFactory.class).toInstance(createNiceMock(MpackManagerFactory.class));
+ Provider<EntityManager> entityManagerProvider = createNiceMock(Provider.class);
+ bind(EntityManager.class).toProvider(entityManagerProvider);
requestStaticInjection(PreUpgradeCheckResourceProvider.class);
}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
index 7de256b..d36a7bc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
@@ -59,9 +59,6 @@ public class InMemoryDefaultTestModule extends AbstractModule {
private static final AtomicReference<Set<BeanDefinition>> foundNotificationBeanDefinitions
= new AtomicReference<>(null);
- private static final AtomicReference<Set<BeanDefinition>> foundUpgradeChecksDefinitions
- = new AtomicReference<>(null);
-
public BeanDefinitionsCachingTestControllerModule(Properties properties) throws Exception {
super(properties);
}
@@ -79,13 +76,6 @@ public class InMemoryDefaultTestModule extends AbstractModule {
foundNotificationBeanDefinitions.compareAndSet(null, Collections.unmodifiableSet(newBeanDefinitions));
return null;
}
-
- @Override
- protected Set<BeanDefinition> registerUpgradeChecks(Set<BeanDefinition> beanDefinitions){
- Set<BeanDefinition> newBeanDefinition = super.registerUpgradeChecks(foundUpgradeChecksDefinitions.get());
- foundUpgradeChecksDefinitions.compareAndSet(null, Collections.unmodifiableSet(newBeanDefinition));
- return null;
- }
}
@Override
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
index f8db131..6413e77 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/CheckHelperTest.java
@@ -20,10 +20,11 @@ package org.apache.ambari.server.state;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
+import org.apache.ambari.annotations.UpgradeCheckInfo;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.checks.ClusterCheck;
import org.apache.ambari.server.checks.MockCheckHelper;
@@ -33,6 +34,7 @@ import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.state.repository.ClusterVersionSummary;
import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.spi.ClusterInformation;
+import org.apache.ambari.spi.RepositoryType;
import org.apache.ambari.spi.RepositoryVersion;
import org.apache.ambari.spi.upgrade.UpgradeCheck;
import org.apache.ambari.spi.upgrade.UpgradeCheckDescription;
@@ -84,7 +86,7 @@ public class CheckHelperTest {
@Mock
private RepositoryVersionDAO repositoryVersionDao;
- final Map<String, Service> m_services = new HashMap<>();
+ final Set<String> m_services = new HashSet<>();
@Before
public void setup() throws Exception {
@@ -94,10 +96,11 @@ public class CheckHelperTest {
m_services.clear();
Mockito.when(m_repositoryVersion.getId()).thenReturn(1L);
+ Mockito.when(m_repositoryVersion.getRepositoryType()).thenReturn(RepositoryType.STANDARD);
Mockito.when(repositoryVersionDao.findByPK(Mockito.anyLong())).thenReturn(m_repositoryVersionEntity);
Mockito.when(m_repositoryVersionEntity.getRepositoryXml()).thenReturn(m_vdfXml);
Mockito.when(m_vdfXml.getClusterSummary(Mockito.any(Cluster.class))).thenReturn(m_clusterVersionSummary);
- Mockito.when(m_clusterVersionSummary.getAvailableServiceNames()).thenReturn(m_services.keySet());
+ Mockito.when(m_clusterVersionSummary.getAvailableServiceNames()).thenReturn(m_services);
}
/**
@@ -106,6 +109,9 @@ public class CheckHelperTest {
@Test
public void testPreUpgradeCheck() throws Exception {
final CheckHelper helper = new CheckHelper();
+ helper.clustersProvider = () -> clusters;
+ helper.repositoryVersionDaoProvider = () -> repositoryVersionDao;
+
Configuration configuration = EasyMock.createNiceMock(Configuration.class);
List<UpgradeCheck> updateChecksRegistry = new ArrayList<>();
@@ -127,15 +133,17 @@ public class CheckHelperTest {
@Test
public void testPreUpgradeCheckNotApplicable() throws Exception {
final Cluster cluster = Mockito.mock(Cluster.class);
- final Service service = Mockito.mock(Service.class);
- m_services.put("KAFKA", service);
+ m_services.add("KAFKA");
Mockito.when(cluster.getServices()).thenReturn(new HashMap<>());
Mockito.when(cluster.getClusterId()).thenReturn(1L);
Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
final CheckHelper helper = new CheckHelper();
+ helper.clustersProvider = () -> clusters;
+ helper.repositoryVersionDaoProvider = () -> repositoryVersionDao;
+
Configuration configuration = EasyMock.createNiceMock(Configuration.class);
List<UpgradeCheck> updateChecksRegistry = new ArrayList<>();
@@ -144,11 +152,14 @@ public class CheckHelperTest {
updateChecksRegistry.add(m_mockCheck);
ClusterInformation clusterInformation = new ClusterInformation("cluster", false, null, null);
- UpgradeCheckRequest request = new UpgradeCheckRequest(clusterInformation, UpgradeType.ROLLING, m_repositoryVersion, null);
+ UpgradeCheckRequest request = new UpgradeCheckRequest(clusterInformation,
+ UpgradeType.NON_ROLLING, m_repositoryVersion, null);
helper.performChecks(request, updateChecksRegistry, configuration);
Assert.assertEquals(null, request.getResult(m_mockUpgradeCheckDescription));
+
+ request = new UpgradeCheckRequest(clusterInformation, UpgradeType.ROLLING, m_repositoryVersion, null);
}
/**
@@ -157,6 +168,9 @@ public class CheckHelperTest {
@Test
public void testPreUpgradeCheckThrowsException() throws Exception {
final CheckHelper helper = new CheckHelper();
+ helper.clustersProvider = () -> clusters;
+ helper.repositoryVersionDaoProvider = () -> repositoryVersionDao;
+
Configuration configuration = EasyMock.createNiceMock(Configuration.class);
List<UpgradeCheck> updateChecksRegistry = new ArrayList<>();
@@ -181,6 +195,9 @@ public class CheckHelperTest {
@Test
public void testPreUpgradeCheckBypassesFailure() throws Exception {
final CheckHelper helper = new CheckHelper();
+ helper.clustersProvider = () -> clusters;
+ helper.repositoryVersionDaoProvider = () -> repositoryVersionDao;
+
Configuration configuration = EasyMock.createNiceMock(Configuration.class);
List<UpgradeCheck> updateChecksRegistry = new ArrayList<>();
@@ -204,7 +221,7 @@ public class CheckHelperTest {
final Cluster cluster = Mockito.mock(Cluster.class);
final Service service = Mockito.mock(Service.class);
- m_services.put("KAFKA", service);
+ m_services.add("KAFKA");
Mockito.when(cluster.getServices()).thenReturn(new HashMap<>());
Mockito.when(cluster.getClusterId()).thenReturn(1L);
@@ -214,6 +231,7 @@ public class CheckHelperTest {
final MockCheckHelper helper = new MockCheckHelper();
helper.m_clusters = clusters;
helper.m_repositoryVersionDAO = repositoryVersionDao;
+ helper.clustersProvider = () -> clusters;
Configuration configuration = EasyMock.createNiceMock(Configuration.class);
List<UpgradeCheck> updateChecksRegistry = new ArrayList<>();
@@ -233,6 +251,8 @@ public class CheckHelperTest {
Assert.assertEquals(UpgradeCheckStatus.FAIL, request.getResult(m_mockUpgradeCheckDescription));
}
+ @UpgradeCheckInfo(
+ required = { UpgradeType.ROLLING })
class MockCheck extends ClusterCheck {
protected MockCheck() {
@@ -252,7 +272,7 @@ public class CheckHelperTest {
*/
@Override
public Set<String> getApplicableServices() {
- return m_services.keySet();
+ return m_services;
}
@Override