AMBARI-7202: Add functionality for Ambari Common Services
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/14c86996 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/14c86996 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/14c86996 Branch: refs/heads/trunk Commit: 14c869961a4bc5cb9ffa041d8ef79ade3ffff3bb Parents: f6248ae Author: Jayush Luniya <jlun...@hortonworks.com> Authored: Wed Dec 10 21:24:53 2014 -0500 Committer: John Speidel <jspei...@hortonworks.com> Committed: Wed Dec 10 21:26:43 2014 -0500 ---------------------------------------------------------------------- ambari-server/conf/unix/ambari.properties | 1 + ambari-server/conf/windows/ambari.properties | 1 + .../server/api/services/AmbariMetaInfo.java | 10 +- .../server/configuration/Configuration.java | 9 + .../apache/ambari/server/stack/BaseModule.java | 28 +- .../ambari/server/stack/ComponentModule.java | 2 +- .../server/stack/ConfigurationModule.java | 2 +- .../apache/ambari/server/stack/ModuleState.java | 29 ++ .../ambari/server/stack/ServiceModule.java | 85 +++- .../server/stack/StackDefinitionModule.java | 17 +- .../ambari/server/stack/StackManager.java | 176 ++++++-- .../apache/ambari/server/stack/StackModule.java | 193 ++++++--- .../server/api/services/AmbariMetaInfoTest.java | 2 +- .../services/KerberosServiceMetaInfoTest.java | 2 +- .../AmbariManagementControllerTest.java | 2 +- .../server/stack/ComponentModuleTest.java | 2 +- .../ambari/server/stack/ServiceModuleTest.java | 2 +- .../stack/StackManagerCommonServicesTest.java | 167 ++++++++ .../server/stack/StackManagerMiscTest.java | 91 +++++ .../ambari/server/stack/StackManagerTest.java | 80 +--- .../HBASE/1.0/configuration/hbase-site.xml | 137 +++++++ .../common-services/HBASE/1.0/metainfo.xml | 121 ++++++ .../HDFS/1.0/configuration/hbase-site.xml | 137 +++++++ .../HDFS/1.0/configuration/hdfs-site.xml | 396 ++++++++++++++++++ .../common-services/HDFS/1.0/metainfo.xml | 133 ++++++ .../common-services/HIVE/1.0/metainfo.xml | 127 ++++++ .../MAPREDUCE/1.0/configuration/hbase-site.xml | 137 +++++++ .../MAPREDUCE/1.0/configuration/hdfs-site.xml | 396 ++++++++++++++++++ .../MAPREDUCE/1.0/configuration/mapred-site.xml | 400 +++++++++++++++++++ .../common-services/MAPREDUCE/1.0/metainfo.xml | 89 +++++ .../PIG/1.0/configuration/pig.properties | 52 +++ .../common-services/PIG/1.0/metainfo.xml | 61 +++ .../common-services/ZOOKEEPER/1.0/metainfo.xml | 72 ++++ .../HDP/0.1/metainfo.xml | 22 + .../HDP/0.1/repos/repoinfo.xml | 57 +++ .../HDP/0.1/services/HDFS/metainfo.xml | 46 +++ .../HDP/0.1/services/MAPREDUCE/metainfo.xml | 23 ++ .../HDP/0.1/services/PIG/metainfo.xml | 26 ++ .../HDP/0.2/metainfo.xml | 22 + .../HDP/0.2/repos/repoinfo.xml | 57 +++ .../HDP/0.2/services/HBASE/metainfo.xml | 26 ++ .../0.2/services/HDFS/configuration/global.xml | 145 +++++++ .../services/HDFS/configuration/hadoop-env.xml | 223 +++++++++++ .../services/HDFS/configuration/hbase-site.xml | 137 +++++++ .../services/HDFS/configuration/hdfs-log4j.xml | 199 +++++++++ .../services/HDFS/configuration/hdfs-site.xml | 396 ++++++++++++++++++ .../HDP/0.2/services/HDFS/metainfo.xml | 30 ++ .../HDP/0.2/services/HIVE/metainfo.xml | 26 ++ .../HDP/0.2/services/MAPREDUCE/metainfo.xml | 23 ++ .../HDP/0.2/services/ZOOKEEPER/metainfo.xml | 26 ++ 50 files changed, 4452 insertions(+), 191 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/conf/unix/ambari.properties ---------------------------------------------------------------------- diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties index 9ef645b..fd1818b 100644 --- a/ambari-server/conf/unix/ambari.properties +++ b/ambari-server/conf/unix/ambari.properties @@ -27,6 +27,7 @@ jce_policy1.6.url=http://public-repo-1.hortonworks.com/ARTIFACTS/jce_policy-6.zi jdk1.7.url=http://public-repo-1.hortonworks.com/ARTIFACTS/jdk-7u67-linux-x64.tar.gz jce_policy1.7.url=http://public-repo-1.hortonworks.com/ARTIFACTS/UnlimitedJCEPolicyJDK7.zip metadata.path=/var/lib/ambari-server/resources/stacks +common.services.path= server.version.file=/var/lib/ambari-server/resources/version webapp.dir=/usr/lib/ambari-server/web bootstrap.dir=/var/run/ambari-server/bootstrap http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/conf/windows/ambari.properties ---------------------------------------------------------------------- diff --git a/ambari-server/conf/windows/ambari.properties b/ambari-server/conf/windows/ambari.properties index fd3a7ba..8939b73 100644 --- a/ambari-server/conf/windows/ambari.properties +++ b/ambari-server/conf/windows/ambari.properties @@ -32,6 +32,7 @@ jdk1.7.67.jcpol-file=UnlimitedJCEPolicyJDK7.zip jdk1.7.67.home=C:\\jdk1.7.0_67 metadata.path=resources\\stacks +common.services.path= server.version.file=version webapp.dir=web bootstrap.dir=bootstrap http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java ---------------------------------------------------------------------- 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 8d404ca..60d4f9b 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 @@ -124,6 +124,7 @@ public class AmbariMetaInfo { private StackManager stackManager; private File stackRoot; + private File commonServicesRoot; private File serverVersionFile; private File customActionRoot; @@ -173,16 +174,21 @@ public class AmbariMetaInfo { @Inject public AmbariMetaInfo(Configuration conf) throws Exception { String stackPath = conf.getMetadataPath(); + String commonServicesPath = conf.getCommonServicesPath(); String serverVersionFilePath = conf.getServerVersionFilePath(); stackRoot = new File(stackPath); + if(commonServicesPath != null && !commonServicesPath.isEmpty()) { + commonServicesRoot = new File(commonServicesPath); + } serverVersionFile = new File(serverVersionFilePath); customActionRoot = new File(conf.getCustomActionDefinitionPath()); os_family = new OsFamily(conf); ALL_SUPPORTED_OS = new ArrayList<String>(os_family.os_list()); } - public AmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception { + public AmbariMetaInfo(File stackRoot, File commonServicesRoot, File serverVersionFile) throws Exception { this.stackRoot = stackRoot; + this.commonServicesRoot = commonServicesRoot; this.serverVersionFile = serverVersionFile; } @@ -196,7 +202,7 @@ public class AmbariMetaInfo { // Need to be initialized before all actions ALL_SUPPORTED_OS = new ArrayList<String>(os_family.os_list()); readServerVersion(); - stackManager = new StackManager(stackRoot, + stackManager = new StackManager(stackRoot,commonServicesRoot, new StackContext(metaInfoDAO, actionMetadata, os_family)); getCustomActionDefinitions(customActionRoot); } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java index da55868..4bbe255 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java @@ -98,6 +98,7 @@ public class Configuration { public static final String SRVR_DISABLED_PROTOCOLS = "security.server.disabled.protocols"; public static final String RESOURCES_DIR_KEY = "resources.dir"; public static final String METADETA_DIR_PATH = "metadata.path"; + public static final String COMMON_SERVICES_DIR_PATH = "common.services.path"; public static final String SERVER_VERSION_FILE = "server.version.file"; public static final String SERVER_VERSION_KEY = "version"; public static final String JAVA_HOME_KEY = "java.home"; @@ -679,6 +680,14 @@ public class Configuration { return properties.getProperty(METADETA_DIR_PATH); } + /** + * Gets ambari common services path + * @return String + */ + public String getCommonServicesPath() { + return properties.getProperty(COMMON_SERVICES_DIR_PATH); + } + public String getServerVersionFilePath() { return properties.getProperty(SERVER_VERSION_FILE); } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/BaseModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/BaseModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/BaseModule.java index b27adea..ef2438f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/BaseModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/BaseModule.java @@ -31,28 +31,46 @@ import java.util.Set; * Provides functionality that is common across multiple modules. */ public abstract class BaseModule<T, I> implements StackDefinitionModule<T, I> { + + /** + * Module visitation state + */ + protected ModuleState moduleState = ModuleState.INIT; + + /** + * Module state. + * Initial state is INIT. + * When resolve is called state is set to VISITED. + * When resolve completes, state is set to RESOLVED. + * + * @return the module's state + */ + public ModuleState getModuleState() { + return moduleState; + } + /** * Merges child modules with the corresponding parent modules. * * @param allStacks collection of all stack module in stack definition + * @param commonServices collection of all common service module in stack definition * @param modules child modules of this module that are to be merged * @param parentModules parent modules which the modules are to be merged with * * @return collection of the merged modules */ protected <T extends StackDefinitionModule<T, ?>> Collection<T> mergeChildModules( - Map<String, StackModule> allStacks, Map<String, T> modules, Map<String, T> parentModules) + Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices, Map<String, T> modules, Map<String, T> parentModules) throws AmbariException { - Set<String> addedModules = new HashSet<String>(); Collection<T> mergedModules = new HashSet<T>(); for (T module : modules.values()) { String id = module.getId(); addedModules.add(id); - if (! module.isDeleted()) { + if (!module.isDeleted()) { if (parentModules.containsKey(id)) { - module.resolve(parentModules.get(id), allStacks); + module.resolve(parentModules.get(id), allStacks, commonServices); } mergedModules.add(module); } @@ -61,7 +79,7 @@ public abstract class BaseModule<T, I> implements StackDefinitionModule<T, I> { // add non-overlapping parent modules for (T parentModule : parentModules.values()) { String id = parentModule.getId(); - if (! addedModules.contains(id)) { + if (!addedModules.contains(id)) { mergedModules.add(parentModule); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java index 0f2a691..f4e9999 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java @@ -47,7 +47,7 @@ public class ComponentModule extends BaseModule<ComponentModule, ComponentInfo> } @Override - public void resolve(ComponentModule parent, Map<String, StackModule> allStacks) { + public void resolve(ComponentModule parent, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) { ComponentInfo parentInfo = parent.getModuleInfo(); if (componentInfo.getCommandScript() == null) { http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationModule.java index ff2e930..fde7b2d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationModule.java @@ -61,7 +61,7 @@ public class ConfigurationModule extends BaseModule<ConfigurationModule, Configu } @Override - public void resolve(ConfigurationModule parent, Map<String, StackModule> allStacks) throws AmbariException { + public void resolve(ConfigurationModule parent, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) throws AmbariException { // merge properties also removes deleted props so should be called even if extension is disabled mergeProperties(parent); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleState.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleState.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleState.java new file mode 100644 index 0000000..74e3a78 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleState.java @@ -0,0 +1,29 @@ +/** + * 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.stack; + +/** + * Module visitation state enum used for cycle detection + */ +public enum ModuleState +{ + INIT, + VISITED, + RESOLVED +} http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java index c783676..d025946 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java @@ -63,6 +63,10 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> { */ private ServiceDirectory serviceDirectory; + /** + * Flag to mark a service as a common service + */ + private boolean isCommonService; /** * Constructor. @@ -72,9 +76,23 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> { * @param serviceDirectory used for all IO interaction with service directory in stack definition */ public ServiceModule(StackContext stackContext, ServiceInfo serviceInfo, ServiceDirectory serviceDirectory) { + this(stackContext, serviceInfo, serviceDirectory, false); + } + + /** + * Constructor. + * + * @param stackContext stack context which provides module access to external functionality + * @param serviceInfo associated service info + * @param serviceDirectory used for all IO interaction with service directory in stack definition + * @param isCommonService flag to mark a service as a common service + */ + public ServiceModule( + StackContext stackContext, ServiceInfo serviceInfo, ServiceDirectory serviceDirectory, boolean isCommonService) { this.serviceInfo = serviceInfo; this.stackContext = stackContext; this.serviceDirectory = serviceDirectory; + this.isCommonService = isCommonService; serviceInfo.setMetricsFile(serviceDirectory.getMetricsFile()); serviceInfo.setAlertsFile(serviceDirectory.getAlertsFile()); @@ -91,7 +109,9 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> { } @Override - public void resolve(ServiceModule parentModule, Map<String, StackModule> allStacks) throws AmbariException { + public void resolve( + ServiceModule parentModule, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { ServiceInfo parent = parentModule.getModuleInfo(); if (serviceInfo.getComment() == null) { @@ -135,8 +155,46 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> { mergeCustomCommands(parent.getCustomCommands(), serviceInfo.getCustomCommands()); mergeConfigDependencies(parent); - mergeComponents(parentModule, allStacks); - mergeConfigurations(parentModule, allStacks); + mergeComponents(parentModule, allStacks, commonServices); + mergeConfigurations(parentModule, allStacks, commonServices); + } + + /** + * Resolve common service + * @param allStacks all stack modules + * @param commonServices common service modules + * + * @throws AmbariException + */ + public void resolveCommonService(Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { + if(!isCommonService) { + throw new AmbariException("Not a common service"); + } + moduleState = ModuleState.VISITED; + String parentString = serviceInfo.getParent(); + if(parentString != null) { + String[] parentToks = parentString.split(StackManager.PATH_DELIMITER); + if(parentToks.length != 3) { + throw new AmbariException("The common service '" + serviceInfo.getName() + serviceInfo.getVersion() + + "' extends an invalid parent: '" + parentString + "'"); + } + if (parentToks[0].equalsIgnoreCase(StackManager.COMMON_SERVICES)) { + String baseServiceKey = parentToks[1] + StackManager.PATH_DELIMITER + parentToks[2]; + ServiceModule baseService = commonServices.get(baseServiceKey); + ModuleState baseModuleState = baseService.getModuleState(); + if (baseModuleState == ModuleState.INIT) { + baseService.resolveCommonService(allStacks, commonServices); + } else if (baseModuleState == ModuleState.VISITED) { + //todo: provide more information to user about cycle + throw new AmbariException("Cycle detected while parsing common service"); + } + resolve(baseService, allStacks, commonServices); + } else { + throw new AmbariException("Common service cannot inherit from a non common service"); + } + } + moduleState = ModuleState.RESOLVED; } @Override @@ -222,15 +280,18 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> { * Merge configurations with the parent configurations. * This will update the child configuration module set as well as the underlying info instances. * - * @param parent parent service module - * @param stacks all stack modules + * @param parent parent service module + * @param allStacks all stack modules + * @param commonServices common service modules */ - private void mergeConfigurations(ServiceModule parent, Map<String, StackModule> stacks) throws AmbariException { + private void mergeConfigurations( + ServiceModule parent, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { serviceInfo.getProperties().clear(); serviceInfo.setAllConfigAttributes(new HashMap<String, Map<String, Map<String, String>>>()); Collection<ConfigurationModule> mergedModules = mergeChildModules( - stacks, configurationModules, parent.configurationModules); + allStacks, commonServices, configurationModules, parent.configurationModules); for (ConfigurationModule module : mergedModules) { configurationModules.put(module.getId(), module); @@ -242,11 +303,17 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> { /** * Merge components with the parent configurations. * This will update the child component module set as well as the underlying info instances. + * + * @param parent parent service module + * @param allStacks all stack modules + * @param commonServices common service modules */ - private void mergeComponents(ServiceModule parent, Map<String, StackModule> stacks) throws AmbariException { + private void mergeComponents( + ServiceModule parent, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { serviceInfo.getComponents().clear(); Collection<ComponentModule> mergedModules = mergeChildModules( - stacks, componentModules, parent.componentModules); + allStacks, commonServices, componentModules, parent.componentModules); for (ComponentModule module : mergedModules) { componentModules.put(module.getId(), module); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionModule.java index cc088e3..f938ba8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionModule.java @@ -34,12 +34,13 @@ public interface StackDefinitionModule <T, I> { /** * Resolve the module state with the specified parent. * - * @param parent the parent that this module will be merged with - * @param allStacks collection of all stack modules in the tree + * @param parent the parent that this module will be merged with + * @param allStacks collection of all stack modules in the tree + * @param commonServices collection of all common service modules in the tree * * @throws AmbariException if resolution fails */ - public void resolve(T parent, Map<String, StackModule> allStacks) throws AmbariException; + public void resolve(T parent, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) throws AmbariException; /** * Obtain the associated module information. @@ -66,4 +67,14 @@ public interface StackDefinitionModule <T, I> { * Lifecycle even which is called when the associated stack has been fully resolved. */ public void finalizeModule(); + + /** + * Module state. + * Initial state is INIT. + * When resolve is called state is set to VISITED. + * When resolve completes, state is set to RESOLVED. + * + * @return the module state + */ + public ModuleState getModuleState(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java index 2a14f51..62a1987 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java @@ -21,7 +21,9 @@ package org.apache.ambari.server.stack; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.StackInfo; +import org.apache.ambari.server.state.stack.ServiceMetainfoXml; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,6 +39,20 @@ import java.util.Map; * stack information. */ public class StackManager { + + /** + * Delimiter used for parent path string + * Example: + * HDP/2.0.6/HDFS + * common-services/HDFS/2.1.0.2.0 + */ + public static String PATH_DELIMITER = "/"; + + /** + * Prefix used for common services parent path string + */ + public static final String COMMON_SERVICES = "common-services"; + /** * Provides access to non-stack server functionality */ @@ -48,48 +64,32 @@ public class StackManager { private final static Logger LOG = LoggerFactory.getLogger(StackManager.class); /** - * Map of stack name to stack info + * Map of stack id to stack info */ private Map<String, StackInfo> stackMap = new HashMap<String, StackInfo>(); - /** * Constructor. + * Initialize stack manager. * - * @param stackRoot stack root directory - * @param stackContext context which provides external functionality + * @param stackRoot stack root directory + * @param commonServicesRoot common services root directory + * @param stackContext context which provides external functionality * * @throws AmbariException if an exception occurs while processing the stacks */ - public StackManager(File stackRoot, StackContext stackContext) throws AmbariException { + public StackManager(File stackRoot, File commonServicesRoot, StackContext stackContext) throws AmbariException { validateStackDirectory(stackRoot); + validateCommonServicesDirectory(commonServicesRoot); + this.stackMap = new HashMap<String, StackInfo>(); this.stackContext = stackContext; - Map<String, StackModule> stackModules = new HashMap<String, StackModule>(); - File[] stackFiles = stackRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER); - for (File stack : stackFiles) { - if (stack.isFile()) { - continue; - } - for (File stackFolder : stack.listFiles(AmbariMetaInfo.FILENAME_FILTER)) { - if (stackFolder.isFile()) { - continue; - } - String stackName = stackFolder.getParentFile().getName(); - String stackVersion = stackFolder.getName(); - StackModule stackModule = new StackModule(new StackDirectory(stackFolder.getPath()),stackContext); - stackModules.put(stackName + stackVersion, stackModule); - stackMap.put(stackName + stackVersion, stackModule.getModuleInfo()); - } - } - - if (stackMap.isEmpty()) { - throw new AmbariException("Unable to find stack definitions under " + - "stackRoot = " + stackRoot.getAbsolutePath()); - } + Map<String, ServiceModule> commonServiceModules = parseCommonServicesDirectory(commonServicesRoot); + Map<String, StackModule> stackModules = parseStackDirectory(stackRoot); - fullyResolveStacks(stackModules); + fullyResolveCommonServices(stackModules, commonServiceModules); + fullyResolveStacks(stackModules, commonServiceModules); } /** @@ -101,7 +101,7 @@ public class StackManager { * If no matching stack exists, null is returned. */ public StackInfo getStack(String name, String version) { - return stackMap.get(name + version); + return stackMap.get(name + StackManager.PATH_DELIMITER + version); } /** @@ -142,13 +142,16 @@ public class StackManager { /** * Fully resolve all stacks. * - * @param stackModules map of stack id which contains name and version to stack module. + * @param stackModules map of stack id which contains name and version to stack module. + * @param commonServiceModules map of common service id which contains name and version to stack module. * @throws AmbariException if unable to resolve all stacks */ - private void fullyResolveStacks(Map<String, StackModule> stackModules) throws AmbariException { + private void fullyResolveStacks( + Map<String, StackModule> stackModules, Map<String, ServiceModule> commonServiceModules) + throws AmbariException { for (StackModule stack : stackModules.values()) { - if (stack.getResolutionState() == StackModule.State.INIT) { - stack.resolve(null, stackModules); + if (stack.getModuleState() == ModuleState.INIT) { + stack.resolve(null, stackModules, commonServiceModules); } } // execute all of the repo tasks in a single thread executor @@ -156,7 +159,46 @@ public class StackManager { } /** + * Fully resolve common services. + * + * @param stackModules map of stack id which contains name and version to stack module. + * @param commonServiceModules map of common service id which contains name and version to common service module. + * @throws AmbariException if unable to resolve all common services + */ + private void fullyResolveCommonServices( + Map<String, StackModule> stackModules, Map<String, ServiceModule> commonServiceModules) + throws AmbariException { + for(ServiceModule commonService : commonServiceModules.values()) { + if (commonService.getModuleState() == ModuleState.INIT) { + commonService.resolveCommonService(stackModules, commonServiceModules); + } + } + } + + /** + * Validate that the specified common services root is a valid directory. + * + * @param commonServicesRoot the common services root directory to validate + * @throws AmbariException if the specified common services root directory is invalid + */ + private void validateCommonServicesDirectory(File commonServicesRoot) throws AmbariException { + if(commonServicesRoot != null) { + String commonServicesRootAbsolutePath = commonServicesRoot.getAbsolutePath(); + if (LOG.isDebugEnabled()) { + LOG.debug("Loading common services information" + + ", commonServicesRoot = " + commonServicesRootAbsolutePath); + } + + if (!commonServicesRoot.isDirectory() && !commonServicesRoot.exists()) + throw new AmbariException("" + Configuration.COMMON_SERVICES_DIR_PATH + + " should be a directory with common services" + + ", commonServicesRoot = " + commonServicesRootAbsolutePath); + } + } + + /** * Validate that the specified stack root is a valid directory. + * * @param stackRoot the stack root directory to validate * @throws AmbariException if the specified stack root directory is invalid */ @@ -172,4 +214,72 @@ public class StackManager { + " should be a directory with stack" + ", stackRoot = " + stackRootAbsPath); } + + /** + * Parse the specified common services root directory + * + * @param commonServicesRoot the common services root directory to parse + * @return map of common service id which contains name and version to common service module. + * @throws AmbariException if unable to parse all common services + */ + private Map<String, ServiceModule> parseCommonServicesDirectory(File commonServicesRoot) throws AmbariException { + Map<String, ServiceModule> commonServiceModules = new HashMap<String, ServiceModule>(); + + if(commonServicesRoot != null) { + File[] commonServiceFiles = commonServicesRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER); + for (File commonService : commonServiceFiles) { + if (commonService.isFile()) { + continue; + } + for (File serviceFolder : commonService.listFiles(AmbariMetaInfo.FILENAME_FILTER)) { + String serviceName = serviceFolder.getParentFile().getName(); + String serviceVersion = serviceFolder.getName(); + ServiceDirectory serviceDirectory = new ServiceDirectory(serviceFolder.getPath()); + ServiceMetainfoXml metaInfoXml = serviceDirectory.getMetaInfoFile(); + for (ServiceInfo serviceInfo : metaInfoXml.getServices()) { + ServiceModule serviceModule = new ServiceModule(stackContext, serviceInfo, serviceDirectory, true); + String commonServiceKey = serviceName + StackManager.PATH_DELIMITER + serviceVersion; + commonServiceModules.put(commonServiceKey, serviceModule); + } + } + } + } + return commonServiceModules; + } + + /** + * Parse the specified stack root directory + * + * @param stackRoot the stack root directory to parse + * @return map of stack id which contains name and version to stack module. + * @throws AmbariException if unable to parse all stacks + */ + private Map<String, StackModule> parseStackDirectory(File stackRoot) throws AmbariException { + Map<String, StackModule> stackModules = new HashMap<String, StackModule>(); + + File[] stackFiles = stackRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER); + for (File stack : stackFiles) { + if (stack.isFile()) { + continue; + } + for (File stackFolder : stack.listFiles(AmbariMetaInfo.FILENAME_FILTER)) { + if (stackFolder.isFile()) { + continue; + } + String stackName = stackFolder.getParentFile().getName(); + String stackVersion = stackFolder.getName(); + + StackModule stackModule = new StackModule(new StackDirectory(stackFolder.getPath()), stackContext); + String stackKey = stackName + StackManager.PATH_DELIMITER + stackVersion; + stackModules.put(stackKey, stackModule); + stackMap.put(stackKey, stackModule.getModuleInfo()); + } + } + + if (stackMap.isEmpty()) { + throw new AmbariException("Unable to find stack definitions under " + + "stackRoot = " + stackRoot.getAbsolutePath()); + } + return stackModules; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java ---------------------------------------------------------------------- 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 ea355c8..0fd8728 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 @@ -71,15 +71,6 @@ import java.util.Map; * */ public class StackModule extends BaseModule<StackModule, StackInfo> { - /** - * Visitation state enum used for cycle detection - */ - public enum State { INIT, VISITED, RESOLVED } - - /** - * Visitation state of the stack - */ - private State resolutionState = State.INIT; /** * Context which provides access to external functionality @@ -136,23 +127,26 @@ public class StackModule extends BaseModule<StackModule, StackInfo> { * same stack hierarchy or may explicitly extend a service in a stack in a different * hierarchy. * - * @param parentModule not used. Each stack determines its own parent since stacks don't - * have containing modules - * @param allStacks all stacks modules contained in the stack definition + * @param parentModule not used. Each stack determines its own parent since stacks don't + * have containing modules + * @param allStacks all stacks modules contained in the stack definition + * @param commonServices all common services specified in the stack definition * * @throws AmbariException if an exception occurs during stack resolution */ @Override - public void resolve(StackModule parentModule, Map<String, StackModule> allStacks) throws AmbariException { - resolutionState = State.VISITED; + public void resolve( + StackModule parentModule, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { + moduleState = ModuleState.VISITED; String parentVersion = stackInfo.getParentStackVersion(); // merge with parent version of same stack definition if (parentVersion != null) { - mergeStackWithParent(allStacks, parentVersion); + mergeStackWithParent(parentVersion, allStacks, commonServices); } - mergeServicesWithExplicitParent(allStacks); + mergeServicesWithExplicitParent(allStacks, commonServices); processRepositories(); - resolutionState = State.RESOLVED; + moduleState = ModuleState.RESOLVED; finalizeModule(); } @@ -188,27 +182,19 @@ public class StackModule extends BaseModule<StackModule, StackInfo> { } /** - * Stack resolution state. - * Initial state is INIT. - * When resolve is called state is set to VISITED. - * When resolve completes, state is set to RESOLVED. - * - * @return the stacks resolution state - */ - public State getResolutionState() { - return resolutionState; - } - - /** * Merge the stack with its parent. * * @param allStacks all stacks in stack definition + * @param commonServices all common services specified in the stack definition * @param parentVersion version of the stacks parent * * @throws AmbariException if an exception occurs merging with the parent */ - private void mergeStackWithParent(Map<String, StackModule> allStacks, String parentVersion) throws AmbariException { - String parentStackKey = stackInfo.getName() + parentVersion; + private void mergeStackWithParent( + String parentVersion, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { + + String parentStackKey = stackInfo.getName() + StackManager.PATH_DELIMITER + parentVersion; StackModule parentStack = allStacks.get(parentStackKey); if (parentStack == null) { @@ -216,27 +202,31 @@ public class StackModule extends BaseModule<StackModule, StackInfo> { "' specifies a parent that doesn't exist"); } - resolveStack(parentStack, allStacks); - mergeConfigurations(parentStack, allStacks); + resolveStack(parentStack, allStacks, commonServices); + mergeConfigurations(parentStack, allStacks, commonServices); mergeRoleCommandOrder(parentStack); if (stackInfo.getStackHooksFolder() == null) { stackInfo.setStackHooksFolder(parentStack.getModuleInfo().getStackHooksFolder()); } - mergeServicesWithParent(allStacks, parentStack); + mergeServicesWithParent(parentStack, allStacks, commonServices); } /** * Merge child services with parent stack. * - * @param stacks all stacks in stack definition - * @param parentStack parent stack module + * @param parentStack parent stack module + * @param allStacks all stacks in stack definition + * @param commonServices all common services specified in the stack definition * * @throws AmbariException if an exception occurs merging the child services with the parent stack */ - private void mergeServicesWithParent(Map<String, StackModule> stacks, StackModule parentStack) throws AmbariException { + private void mergeServicesWithParent( + StackModule parentStack, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { stackInfo.getServices().clear(); - Collection<ServiceModule> mergedModules = mergeChildModules(stacks, serviceModules, parentStack.serviceModules); + Collection<ServiceModule> mergedModules = mergeChildModules( + allStacks, commonServices, serviceModules, parentStack.serviceModules); for (ServiceModule module : mergedModules) { serviceModules.put(module.getId(), module); stackInfo.getServices().add(module.getModuleInfo()); @@ -245,52 +235,129 @@ public class StackModule extends BaseModule<StackModule, StackInfo> { /** * Merge services with their explicitly specified parent if one has been specified. - * - * @param stacks all stacks specified in the stack definition + * @param allStacks all stacks in stack definition + * @param commonServices all common services specified in the stack definition * * @throws AmbariException if an exception occurs while merging child services with their explicit parents */ - private void mergeServicesWithExplicitParent(Map<String, StackModule> stacks) throws AmbariException { + private void mergeServicesWithExplicitParent( + Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) throws AmbariException { for (ServiceModule service : serviceModules.values()) { ServiceInfo serviceInfo = service.getModuleInfo(); String parent = serviceInfo.getParent(); if (parent != null) { - mergeServiceWithExplicitParent(stacks, service, parent); + mergeServiceWithExplicitParent(service, parent, allStacks, commonServices); } } } /** * Merge a service with its explicitly specified parent. - * @param stacks all stacks specified in the stack definition - * @param service the service to merge - * @param parent the explicitly specified parent service + * @param service the service to merge + * @param parent the explicitly specified parent service + * @param allStacks all stacks specified in the stack definition + * @param commonServices all common services specified in the stack definition * * @throws AmbariException if an exception occurs merging a service with its explicit parent */ - private void mergeServiceWithExplicitParent(Map<String, StackModule> stacks, ServiceModule service, String parent) + private void mergeServiceWithExplicitParent( + ServiceModule service, String parent, Map<String, StackModule> allStacks, + Map<String, ServiceModule> commonServices) + throws AmbariException { + if(isCommonServiceParent(parent)) { + mergeServiceWithCommonServiceParent(service, parent, allStacks,commonServices); + } else { + mergeServiceWithStackServiceParent(service, parent, allStacks, commonServices); + } + } + + /** + * Check if parent is common service + * @param parent Parent string + * @return true: if parent is common service, false otherwise + */ + private boolean isCommonServiceParent(String parent) { + return parent != null + && !parent.isEmpty() + && parent.split(StackManager.PATH_DELIMITER)[0].equalsIgnoreCase(StackManager.COMMON_SERVICES); + } + + /** + * Merge a service with its explicitly specified common service as parent. + * Parent: common-services/<serviceName>/<serviceVersion> + * Common Services Lookup Key: <serviceName>/<serviceVersion> + * Example: + * Parent: common-services/HDFS/2.1.0.2.0 + * Key: HDFS/2.1.0.2.0 + * + * @param service the service to merge + * @param parent the explicitly specified common service as parent + * @param allStacks all stacks specified in the stack definition + * @param commonServices all common services specified in the stack definition + * @throws AmbariException + */ + private void mergeServiceWithCommonServiceParent( + ServiceModule service, String parent, Map<String, StackModule> allStacks, + Map<String, ServiceModule> commonServices) throws AmbariException { + ServiceInfo serviceInfo = service.getModuleInfo(); + String[] parentToks = parent.split(StackManager.PATH_DELIMITER); + if(parentToks.length != 3 || !parentToks[0].equalsIgnoreCase(StackManager.COMMON_SERVICES)) { + throw new AmbariException("The service '" + serviceInfo.getName() + "' in stack '" + stackInfo.getName() + ":" + + stackInfo.getVersion() + "' extends an invalid parent: '" + parent + "'"); + } + + String baseServiceKey = parentToks[1] + StackManager.PATH_DELIMITER + parentToks[2]; + ServiceModule baseService = commonServices.get(baseServiceKey); + if (baseService == null) { + throw new AmbariException("The service '" + serviceInfo.getName() + "' in stack '" + stackInfo.getName() + ":" + + stackInfo.getVersion() + "' extends a non-existent service: '" + parent + "'"); + } + service.resolve(baseService, allStacks, commonServices); + } + /** + * Merge a service with its explicitly specified stack service as parent. + * Parent: <stackName>/<stackVersion>/<serviceName> + * Stack Lookup Key: <stackName>/<stackVersion> + * Example: + * Parent: HDP/2.0.6/HDFS + * Key: HDP/2.0.6 + * + * @param service the service to merge + * @param parent the explicitly specified stack service as parent + * @param allStacks all stacks specified in the stack definition + * @param commonServices all common services specified in the stack definition + * @throws AmbariException + */ + private void mergeServiceWithStackServiceParent( + ServiceModule service, String parent, Map<String, StackModule> allStacks, + Map<String, ServiceModule> commonServices) + throws AmbariException { ServiceInfo serviceInfo = service.getModuleInfo(); - String[] parentToks = parent.split("/"); - String baseStackKey = parentToks[0] + parentToks[1]; - StackModule baseStack = stacks.get(baseStackKey); + String[] parentToks = parent.split(StackManager.PATH_DELIMITER); + if(parentToks.length != 3 || parentToks[0].equalsIgnoreCase(StackManager.COMMON_SERVICES)) { + throw new AmbariException("The service '" + serviceInfo.getName() + "' in stack '" + stackInfo.getName() + ":" + + stackInfo.getVersion() + "' extends an invalid parent: '" + parent + "'"); + } + + String baseStackKey = parentToks[0] + StackManager.PATH_DELIMITER + parentToks[1]; + StackModule baseStack = allStacks.get(baseStackKey); if (baseStack == null) { throw new AmbariException("The service '" + serviceInfo.getName() + "' in stack '" + stackInfo.getName() + ":" + stackInfo.getVersion() + "' extends a service in a non-existent stack: '" + baseStackKey + "'"); } - resolveStack(baseStack, stacks); + resolveStack(baseStack, allStacks, commonServices); ServiceModule baseService = baseStack.serviceModules.get(parentToks[2]); if (baseService == null) { throw new AmbariException("The service '" + serviceInfo.getName() + "' in stack '" + stackInfo.getName() + ":" + stackInfo.getVersion() + "' extends a non-existent service: '" + parent + "'"); } - service.resolve(baseService, stacks); + service.resolve(baseService, allStacks, commonServices); } - /** * Populate the stack module and info from the stack definition. */ @@ -378,14 +445,17 @@ public class StackModule extends BaseModule<StackModule, StackInfo> { * Merge configurations with the parent configurations. * * @param parent parent stack module - * @param stacks all stack modules + * @param allStacks all stacks in stack definition + * @param commonServices all common services specified in the stack definition */ - private void mergeConfigurations(StackModule parent, Map<String, StackModule> stacks) throws AmbariException { + private void mergeConfigurations( + StackModule parent, Map<String,StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { stackInfo.getProperties().clear(); stackInfo.setAllConfigAttributes(new HashMap<String, Map<String, Map<String, String>>>()); Collection<ConfigurationModule> mergedModules = mergeChildModules( - stacks, configurationModules, parent.configurationModules); + allStacks, commonServices, configurationModules, parent.configurationModules); for (ConfigurationModule module : mergedModules) { configurationModules.put(module.getId(), module); stackInfo.getProperties().addAll(module.getModuleInfo().getProperties()); @@ -397,13 +467,16 @@ public class StackModule extends BaseModule<StackModule, StackInfo> { * Resolve another stack module. * * @param stackToBeResolved stack module to be resolved - * @param stacks all stack modules in stack definition + * @param allStacks all stack modules in stack definition + * @param commonServices all common services specified in the stack definition * @throws AmbariException if unable to resolve the stack */ - private void resolveStack(StackModule stackToBeResolved, Map<String, StackModule> stacks) throws AmbariException { - if (stackToBeResolved.getResolutionState() == State.INIT) { - stackToBeResolved.resolve(null, stacks); - } else if (stackToBeResolved.getResolutionState() == State.VISITED) { + private void resolveStack( + StackModule stackToBeResolved, Map<String, StackModule> allStacks, Map<String, ServiceModule> commonServices) + throws AmbariException { + if (stackToBeResolved.getModuleState() == ModuleState.INIT) { + stackToBeResolved.resolve(null, allStacks, commonServices); + } else if (stackToBeResolved.getModuleState() == ModuleState.VISITED) { //todo: provide more information to user about cycle throw new AmbariException("Cycle detected while parsing stack definition"); } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java ---------------------------------------------------------------------- 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 98d2645..734f4b9 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 @@ -1735,7 +1735,7 @@ public class AmbariMetaInfoTest { OsFamily osFamily; public TestAmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception { - super(stackRoot, serverVersionFile); + super(stackRoot, null, serverVersionFile); // MetainfoDAO metaInfoDAO = createNiceMock(MetainfoDAO.class); Class<?> c = getClass().getSuperclass(); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java index 7ecd833..538bbb5 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java @@ -217,7 +217,7 @@ public class KerberosServiceMetaInfoTest { OsFamily osFamily; public TestAmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception { - super(stackRoot, serverVersionFile); + super(stackRoot, null, serverVersionFile); // MetainfoDAO metaInfoDAO = createNiceMock(MetainfoDAO.class); Class<?> c = getClass().getSuperclass(); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java index 2a804e5..4db6738 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java @@ -8087,7 +8087,7 @@ public class AmbariManagementControllerTest { assertEquals(original, repo.getDefaultBaseUrl()); // verify change with new meta info - AmbariMetaInfo ami = new AmbariMetaInfo(new File("src/test/resources/stacks"), new File("target/version")); + AmbariMetaInfo ami = new AmbariMetaInfo(new File("src/test/resources/stacks"), null, new File("target/version")); injector.injectMembers(ami); ami.init(); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java index 8181cbc..42d6944 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java @@ -394,7 +394,7 @@ public class ComponentModuleTest { ComponentModule component = new ComponentModule(info); ComponentModule parentComponent = new ComponentModule(parentInfo); - component.resolve(parentComponent, Collections.<String, StackModule>emptyMap()); + component.resolve(parentComponent, Collections.<String, StackModule>emptyMap(), Collections.<String, ServiceModule>emptyMap()); return component; } http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java index 5262c77..b6b7190 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java @@ -976,7 +976,7 @@ public class ServiceModuleTest { } private void resolveService(ServiceModule service, ServiceModule parent) throws AmbariException { - service.resolve(parent, Collections.<String, StackModule>emptyMap()); + service.resolve(parent, Collections.<String, StackModule>emptyMap(), Collections.<String, ServiceModule>emptyMap()); // during runtime this would be called by the Stack module when it's resolve completed service.finalizeModule(); parent.finalizeModule(); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerCommonServicesTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerCommonServicesTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerCommonServicesTest.java new file mode 100644 index 0000000..7b5168c --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerCommonServicesTest.java @@ -0,0 +1,167 @@ +/** + * 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.stack; + +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.metadata.ActionMetadata; +import org.apache.ambari.server.orm.dao.MetainfoDAO; +import org.apache.ambari.server.state.*; +import org.apache.ambari.server.state.stack.OsFamily; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.util.*; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; + +/** + * StackManager unit tests. + */ +public class StackManagerCommonServicesTest { + + private static StackManager stackManager; + private static MetainfoDAO dao; + private static ActionMetadata actionMetadata; + private static OsFamily osFamily; + + @BeforeClass + public static void initStack() throws Exception{ + stackManager = createTestStackManager(); + } + + public static StackManager createTestStackManager() throws Exception { + String stack = ClassLoader.getSystemClassLoader().getResource("stacks_with_common_services").getPath(); + String commonServices = ClassLoader.getSystemClassLoader().getResource("common-services").getPath(); + return createTestStackManager(stack, commonServices); + } + + public static StackManager createTestStackManager(String stackRoot, String commonServicesRoot) throws Exception { + try { + //todo: dao , actionMetaData expectations + dao = createNiceMock(MetainfoDAO.class); + actionMetadata = createNiceMock(ActionMetadata.class); + Configuration config = createNiceMock(Configuration.class); + expect(config.getSharedResourcesDirPath()).andReturn( + ClassLoader.getSystemClassLoader().getResource("").getPath()).anyTimes(); + replay(config); + osFamily = new OsFamily(config); + + replay(dao, actionMetadata); + StackManager stackManager = new StackManager( + new File(stackRoot), new File(commonServicesRoot), new StackContext(dao, actionMetadata, osFamily)); + return stackManager; + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetStacks_count() throws Exception { + Collection<StackInfo> stacks = stackManager.getStacks(); + assertEquals(2, stacks.size()); + } + + @Test + public void testGetStack_name__count() { + Collection<StackInfo> stacks = stackManager.getStacks("HDP"); + assertEquals(2, stacks.size()); + } + + @Test + public void testGetStack_basic() { + StackInfo stack = stackManager.getStack("HDP", "0.1"); + assertNotNull(stack); + assertEquals("HDP", stack.getName()); + assertEquals("0.1", stack.getVersion()); + + + Collection<ServiceInfo> services = stack.getServices(); + assertEquals(3, services.size()); + + Map<String, ServiceInfo> serviceMap = new HashMap<String, ServiceInfo>(); + for (ServiceInfo service : services) { + serviceMap.put(service.getName(), service); + } + ServiceInfo hdfsService = serviceMap.get("HDFS"); + assertNotNull(hdfsService); + List<ComponentInfo> components = hdfsService.getComponents(); + assertEquals(6, components.size()); + List<PropertyInfo> properties = hdfsService.getProperties(); + assertEquals(62, properties.size()); + + // test a couple of the properties for filename + boolean hdfsPropFound = false; + boolean hbasePropFound = false; + for (PropertyInfo p : properties) { + if (p.getName().equals("hbase.regionserver.msginterval")) { + assertEquals("hbase-site.xml", p.getFilename()); + hbasePropFound = true; + } else if (p.getName().equals("dfs.name.dir")) { + assertEquals("hdfs-site.xml", p.getFilename()); + hdfsPropFound = true; + } + } + assertTrue(hbasePropFound); + assertTrue(hdfsPropFound); + + ServiceInfo mrService = serviceMap.get("MAPREDUCE"); + assertNotNull(mrService); + components = mrService.getComponents(); + assertEquals(3, components.size()); + + ServiceInfo pigService = serviceMap.get("PIG"); + assertNotNull(pigService); + assertEquals("PIG", pigService.getName()); + assertEquals("1.0", pigService.getVersion()); + assertEquals("This is comment for PIG service", pigService.getComment()); + components = pigService.getComponents(); + assertEquals(1, components.size()); + CommandScriptDefinition commandScript = pigService.getCommandScript(); + assertEquals("scripts/service_check.py", commandScript.getScript()); + assertEquals(CommandScriptDefinition.Type.PYTHON, commandScript.getScriptType()); + assertEquals(300, commandScript.getTimeout()); + List<String> configDependencies = pigService.getConfigDependencies(); + assertEquals(1, configDependencies.size()); + assertEquals("global", configDependencies.get(0)); + assertEquals("global", pigService.getConfigDependenciesWithComponents().get(0)); + ComponentInfo client = pigService.getClientComponent(); + assertNotNull(client); + assertEquals("PIG", client.getName()); + assertEquals("0+", client.getCardinality()); + assertEquals("CLIENT", client.getCategory()); + assertEquals("configuration", pigService.getConfigDir()); + assertEquals("2.0", pigService.getSchemaVersion()); + Map<String, ServiceOsSpecific> osInfoMap = pigService.getOsSpecifics(); + assertEquals(1, osInfoMap.size()); + ServiceOsSpecific osSpecific = osInfoMap.get("centos6"); + assertNotNull(osSpecific); + assertEquals("centos6", osSpecific.getOsFamily()); + assertNull(osSpecific.getRepo()); + List<ServiceOsSpecific.Package> packages = osSpecific.getPackages(); + assertEquals(1, packages.size()); + ServiceOsSpecific.Package pkg = packages.get(0); + assertEquals("pig", pkg.getName()); + + assertEquals(pigService.getParent(), "common-services/PIG/1.0"); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerMiscTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerMiscTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerMiscTest.java new file mode 100644 index 0000000..26d7826 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerMiscTest.java @@ -0,0 +1,91 @@ +/** + * 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.stack; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.metadata.ActionMetadata; +import org.apache.ambari.server.orm.dao.MetainfoDAO; +import org.apache.ambari.server.state.StackInfo; +import org.apache.ambari.server.state.stack.OsFamily; +import org.junit.Test; + +import java.io.File; +import java.util.Collection; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +/** + * StackManager Misc unit tests. + */ +public class StackManagerMiscTest { + + @Test + public void testCycleDetection() throws Exception { + MetainfoDAO dao = createNiceMock(MetainfoDAO.class); + ActionMetadata actionMetadata = createNiceMock(ActionMetadata.class); + OsFamily osFamily = createNiceMock(OsFamily.class); + replay(actionMetadata); + try { + String stacksCycle1 = ClassLoader.getSystemClassLoader().getResource("stacks_with_cycle").getPath(); + StackManager stackManager = new StackManager(new File(stacksCycle1), null, + new StackContext(dao, actionMetadata, osFamily)); + fail("Expected exception due to cyclic stack"); + } catch (AmbariException e) { + // expected + assertEquals("Cycle detected while parsing stack definition", e.getMessage()); + } + try { + String stacksCycle2 = ClassLoader.getSystemClassLoader().getResource("stacks_with_cycle2").getPath(); + StackManager stackManager = new StackManager(new File(stacksCycle2), null, + new StackContext(dao, actionMetadata, osFamily)); + fail("Expected exception due to cyclic stack"); + } catch (AmbariException e) { + // expected + assertEquals("Cycle detected while parsing stack definition", e.getMessage()); + } + } + + /** + * This test ensures the service status check is added into the action metadata when + * the stack has no parent and is the only stack in the stack family + */ + @Test + public void testGetServiceInfoFromSingleStack() throws Exception { + MetainfoDAO dao = createNiceMock(MetainfoDAO.class); + ActionMetadata actionMetadata = createNiceMock(ActionMetadata.class); + OsFamily osFamily = createNiceMock(OsFamily.class); + + // ensure that service check is added for HDFS + actionMetadata.addServiceCheckAction("HDFS"); + replay(dao, actionMetadata, osFamily); + String singleStack = ClassLoader.getSystemClassLoader().getResource("single_stack").getPath(); + + StackManager stackManager = new StackManager( + new File(singleStack.replace(StackManager.PATH_DELIMITER, File.separator)), + null, + new StackContext(dao, actionMetadata, osFamily)); + + Collection<StackInfo> stacks = stackManager.getStacks(); + assertEquals(1, stacks.size()); + assertNotNull(stacks.iterator().next().getService("HDFS")); + + verify(dao, actionMetadata, osFamily); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java index 9d75643..f5c2938 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java @@ -63,10 +63,7 @@ public class StackManagerTest { } public static StackManager createTestStackManager() throws Exception { - String stack = "./src/test/resources/stacks/"; - if (System.getProperty("os.name").contains("Windows")) { - stack = ClassLoader.getSystemClassLoader().getResource("stacks").getPath(); - } + String stack = ClassLoader.getSystemClassLoader().getResource("stacks").getPath(); return createTestStackManager(stack); } @@ -76,17 +73,15 @@ public class StackManagerTest { dao = createNiceMock(MetainfoDAO.class); actionMetadata = createNiceMock(ActionMetadata.class); Configuration config = createNiceMock(Configuration.class); - if (System.getProperty("os.name").contains("Windows")) { - expect(config.getSharedResourcesDirPath()).andReturn(ClassLoader.getSystemClassLoader().getResource("").getPath()).anyTimes(); - } - else { - expect(config.getSharedResourcesDirPath()).andReturn("./src/test/resources").anyTimes(); - } + expect(config.getSharedResourcesDirPath()).andReturn( + ClassLoader.getSystemClassLoader().getResource("").getPath()).anyTimes(); replay(config); osFamily = new OsFamily(config); replay(dao, actionMetadata); - return new StackManager(new File(stackRoot), new StackContext(dao, actionMetadata, osFamily)); + StackManager stackManager = new StackManager( + new File(stackRoot), null, new StackContext(dao, actionMetadata, osFamily)); + return stackManager; } catch (Exception e) { e.printStackTrace(); throw e; @@ -154,7 +149,6 @@ public class StackManagerTest { assertNotNull(pigService); assertEquals("PIG", pigService.getName()); assertEquals("1.0", pigService.getVersion()); - assertNull(pigService.getParent()); assertEquals("This is comment for PIG service", pigService.getComment()); components = pigService.getComponents(); assertEquals(1, components.size()); @@ -183,6 +177,8 @@ public class StackManagerTest { assertEquals(1, packages.size()); ServiceOsSpecific.Package pkg = packages.get(0); assertEquals("pig", pkg.getName()); + + assertNull(pigService.getParent()); } @Test @@ -519,38 +515,6 @@ public class StackManagerTest { } @Test - public void testCycleDetection() throws Exception { - ActionMetadata actionMetadata = createNiceMock(ActionMetadata.class); - OsFamily osFamily = createNiceMock(OsFamily.class); - replay(actionMetadata); - try { - String stacksCycle1 = "./src/test/resources/stacks_with_cycle/"; - if (System.getProperty("os.name").contains("Windows")) { - stacksCycle1 = ClassLoader.getSystemClassLoader().getResource("stacks_with_cycle").getPath(); - } - new StackManager(new File(stacksCycle1), - new StackContext(null, actionMetadata, osFamily)); - fail("Expected exception due to cyclic stack"); - } catch (AmbariException e) { - // expected - assertEquals("Cycle detected while parsing stack definition", e.getMessage()); - } - - try { - String stacksCycle2 = "./src/test/resources/stacks_with_cycle2/"; - if (System.getProperty("os.name").contains("Windows")) { - stacksCycle2 = ClassLoader.getSystemClassLoader().getResource("stacks_with_cycle2").getPath(); - } - new StackManager(new File(stacksCycle2), - new StackContext(null, actionMetadata, osFamily)); - fail("Expected exception due to cyclic stack"); - } catch (AmbariException e) { - // expected - assertEquals("Cycle detected while parsing stack definition", e.getMessage()); - } - } - - @Test public void testExcludedConfigTypes() { StackInfo stack = stackManager.getStack("HDP", "2.0.8"); ServiceInfo service = stack.getService("HBASE"); @@ -589,34 +553,6 @@ public class StackManagerTest { assertNotNull(hdfsService.getMetricsFile()); } - /** - * This test ensures the service status check is added into the action metadata when - * the stack has no parent and is the only stack in the stack family - */ - @Test - public void testGetServiceInfoFromSingleStack() throws Exception { - dao = createNiceMock(MetainfoDAO.class); - actionMetadata = createNiceMock(ActionMetadata.class); - osFamily = createNiceMock(OsFamily.class); - - // ensure that service check is added for HDFS - actionMetadata.addServiceCheckAction("HDFS"); - replay(dao, actionMetadata, osFamily); - String singleStack = "./src/test/resources/single_stack"; - if (System.getProperty("os.name").contains("Windows")) { - singleStack = ClassLoader.getSystemClassLoader().getResource("single_stack").getPath(); - } - StackManager stackManager = new StackManager( - new File(singleStack.replace("/", File.separator)), - new StackContext(dao, actionMetadata, osFamily)); - - Collection<StackInfo> stacks = stackManager.getStacks(); - assertEquals(1, stacks.size()); - assertNotNull(stacks.iterator().next().getService("HDFS")); - - verify(dao, actionMetadata, osFamily); - } - @Test public void testMergeRoleCommandOrder() throws Exception { StackInfo stack = stackManager.getStack("HDP", "2.1.1"); http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/resources/common-services/HBASE/1.0/configuration/hbase-site.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/common-services/HBASE/1.0/configuration/hbase-site.xml b/ambari-server/src/test/resources/common-services/HBASE/1.0/configuration/hbase-site.xml new file mode 100644 index 0000000..5024e85 --- /dev/null +++ b/ambari-server/src/test/resources/common-services/HBASE/1.0/configuration/hbase-site.xml @@ -0,0 +1,137 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<!-- +/** + * Copyright 2007 The Apache Software Foundation + * + * 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. + */ +--> +<configuration> + <property> + <name>hbase.regionserver.msginterval</name> + <value>1000</value> + <description>Interval between messages from the RegionServer to HMaster + in milliseconds. Default is 15. Set this value low if you want unit + tests to be responsive. + </description> + </property> + <property> + <name>hbase.client.pause</name> + <value>5000</value> + <description>General client pause value. Used mostly as value to wait + before running a retry of a failed get, region lookup, etc.</description> + </property> + <property> + <name>hbase.master.meta.thread.rescanfrequency</name> + <value>10000</value> + <description>How long the HMaster sleeps (in milliseconds) between scans of + the root and meta tables. + </description> + </property> + <property> + <name>hbase.server.thread.wakefrequency</name> + <value>1000</value> + <description>Time to sleep in between searches for work (in milliseconds). + Used as sleep interval by service threads such as META scanner and log roller. + </description> + </property> + <property> + <name>hbase.regionserver.handler.count</name> + <value>5</value> + <description>Count of RPC Server instances spun up on RegionServers + Same property is used by the HMaster for count of master handlers. + Default is 10. + </description> + </property> + <property> + <name>hbase.master.lease.period</name> + <value>6000</value> + <description>Length of time the master will wait before timing out a region + server lease. Since region servers report in every second (see above), this + value has been reduced so that the master will notice a dead region server + sooner. The default is 30 seconds. + </description> + </property> + <property> + <name>hbase.master.info.port</name> + <value>-1</value> + <description>The port for the hbase master web UI + Set to -1 if you do not want the info server to run. + </description> + </property> + <property> + <name>hbase.regionserver.info.port</name> + <value>-1</value> + <description>The port for the hbase regionserver web UI + Set to -1 if you do not want the info server to run. + </description> + </property> + <property> + <name>hbase.regionserver.info.port.auto</name> + <value>true</value> + <description>Info server auto port bind. Enables automatic port + search if hbase.regionserver.info.port is already in use. + Enabled for testing to run multiple tests on one machine. + </description> + </property> + <property> + <name>hbase.master.lease.thread.wakefrequency</name> + <value>3000</value> + <description>The interval between checks for expired region server leases. + This value has been reduced due to the other reduced values above so that + the master will notice a dead region server sooner. The default is 15 seconds. + </description> + </property> + <property> + <name>hbase.regionserver.optionalcacheflushinterval</name> + <value>10000</value> + <description> + Amount of time to wait since the last time a region was flushed before + invoking an optional cache flush. Default 60,000. + </description> + </property> + <property> + <name>hbase.regionserver.safemode</name> + <value>false</value> + <description> + Turn on/off safe mode in region server. Always on for production, always off + for tests. + </description> + </property> + <property> + <name>hbase.hregion.max.filesize</name> + <value>67108864</value> + <description> + Maximum desired file size for an HRegion. If filesize exceeds + value + (value / 2), the HRegion is split in two. Default: 256M. + + Keep the maximum filesize small so we split more often in tests. + </description> + </property> + <property> + <name>hadoop.log.dir</name> + <value>${user.dir}/../logs</value> + </property> + <property> + <name>hbase.zookeeper.property.clientPort</name> + <value>21818</value> + <description>Property from ZooKeeper's config zoo.cfg. + The port at which the clients will connect. + </description> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/ambari/blob/14c86996/ambari-server/src/test/resources/common-services/HBASE/1.0/metainfo.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/common-services/HBASE/1.0/metainfo.xml b/ambari-server/src/test/resources/common-services/HBASE/1.0/metainfo.xml new file mode 100644 index 0000000..9646d63 --- /dev/null +++ b/ambari-server/src/test/resources/common-services/HBASE/1.0/metainfo.xml @@ -0,0 +1,121 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<metainfo> + <schemaVersion>2.0</schemaVersion> + <services> + <service> + <name>HBASE</name> + <comment>This is comment for HBASE service</comment> + <version>1.0</version> + + <components> + <component> + <name>HBASE_MASTER</name> + <category>MASTER</category> + <cardinality>1</cardinality> + <dependencies> + <dependency> + <name>HDFS/HDFS_CLIENT</name> + <scope>host</scope> + <auto-deploy> + <enabled>true</enabled> + </auto-deploy> + </dependency> + <dependency> + <name>ZOOKEEPER/ZOOKEEPER_SERVER</name> + <scope>cluster</scope> + <auto-deploy> + <enabled>true</enabled> + <co-locate>HBASE/HBASE_MASTER</co-locate> + </auto-deploy> + </dependency> + </dependencies> + <commandScript> + <script>scripts/hbase_master.py</script> + <scriptType>PYTHON</scriptType> + <timeout>600</timeout> + </commandScript> + <customCommands> + <customCommand> + <name>DECOMMISSION</name> + <commandScript> + <script>scripts/hbase_master.py</script> + <scriptType>PYTHON</scriptType> + <timeout>600</timeout> + </commandScript> + </customCommand> + </customCommands> + </component> + + <component> + <name>HBASE_REGIONSERVER</name> + <category>SLAVE</category> + <cardinality>1+</cardinality> + <commandScript> + <script>scripts/hbase_regionserver.py</script> + <scriptType>PYTHON</scriptType> + </commandScript> + <customCommands> + <customCommand> + <name>DECOMMISSION</name> + <commandScript> + <script>scripts/hbase_regionserver.py</script> + <scriptType>PYTHON</scriptType> + <timeout>600</timeout> + </commandScript> + </customCommand> + </customCommands> + </component> + + <component> + <name>HBASE_CLIENT</name> + <category>CLIENT</category> + <cardinality>0+</cardinality> + <commandScript> + <script>scripts/hbase_client.py</script> + <scriptType>PYTHON</scriptType> + </commandScript> + </component> + </components> + + <osSpecifics> + <osSpecific> + <osFamily>centos6</osFamily> + <packages> + <package> + <name>hbase</name> + </package> + </packages> + </osSpecific> + </osSpecifics> + + <commandScript> + <script>scripts/service_check.py</script> + <scriptType>PYTHON</scriptType> + <timeout>300</timeout> + </commandScript> + + <configuration-dependencies> + <config-type>global</config-type> + <config-type>hbase-policy</config-type> + <config-type>hbase-site</config-type> + </configuration-dependencies> + + </service> + </services> +</metainfo>