You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2013/11/26 21:57:49 UTC
[8/8] git commit: AMBARI-3548. Changes to stacks definitions to allow
custom services support (needed by an ambari-agent) (dlysnichenko)
AMBARI-3548. Changes to stacks definitions to allow custom services support (needed by an ambari-agent) (dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/cc49fb9e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/cc49fb9e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/cc49fb9e
Branch: refs/heads/trunk
Commit: cc49fb9e651cb647e20c7187d66b674d81d2c185
Parents: 8d1da2d
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Tue Nov 26 22:55:53 2013 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Tue Nov 26 22:55:53 2013 +0200
----------------------------------------------------------------------
.../ambari_agent/CustomServiceOrchestrator.py | 2 +-
.../src/main/python/ambari_agent/FileCache.py | 3 +-
.../TestCustomServiceOrchestrator.py | 2 +-
.../test/python/ambari_agent/TestFileCache.py | 3 +-
.../org/apache/ambari/server/RoleCommand.java | 1 +
.../server/actionmanager/ActionScheduler.java | 4 +-
.../ambari/server/actionmanager/HostAction.java | 104 -
.../server/actionmanager/HostRoleCommand.java | 1 -
.../ambari/server/actionmanager/Stage.java | 5 +
.../ambari/server/agent/ExecutionCommand.java | 30 +
.../server/api/services/AmbariMetaInfo.java | 25 +-
.../server/api/util/StackExtensionHelper.java | 207 +-
.../controller/AmbariActionExecutionHelper.java | 6 +-
.../AmbariCustomCommandExecutionHelper.java | 256 +-
.../AmbariCustomCommandExecutionHelperImpl.java | 471 ++
.../controller/AmbariManagementController.java | 41 +
.../AmbariManagementControllerImpl.java | 238 +-
.../server/controller/ControllerModule.java | 1 +
.../server/metadata/RoleCommandOrder.java | 24 +-
.../server/state/CommandScriptDefinition.java | 44 +
.../ambari/server/state/ComponentInfo.java | 29 +-
.../server/state/CustomCommandDefinition.java | 39 +
.../apache/ambari/server/state/ServiceInfo.java | 124 +-
.../ambari/server/state/ServiceOsSpecific.java | 122 +
.../state/stack/ServiceMetainfoV2Xml.java | 51 +
.../apache/ambari/server/utils/StageUtils.java | 19 +-
.../src/main/resources/role_command_order.json | 36 +-
.../stacks/HDP/2.0.6/role_command_order.json | 36 +-
.../stacks/HDP/2.0.8/role_command_order.json | 36 +-
.../resources/stacks/HDP/2.0._/metainfo.xml | 22 +
.../stacks/HDP/2.0._/repos/repoinfo.xml | 75 +
.../stacks/HDP/2.0._/role_command_order.json | 100 +
.../HDP/2.0._/services/GANGLIA/metainfo.xml | 36 +
.../services/HBASE/configuration/global.xml | 160 +
.../HBASE/configuration/hbase-policy.xml | 53 +
.../services/HBASE/configuration/hbase-site.xml | 356 +
.../HDP/2.0._/services/HBASE/metainfo.xml | 38 +-
.../HBASE/package/scripts/service_check.py | 2 +-
.../HDP/2.0._/services/HCATALOG/metainfo.xml | 30 +
.../services/HDFS/configuration/core-site.xml | 167 +
.../services/HDFS/configuration/global.xml | 192 +
.../HDFS/configuration/hadoop-policy.xml | 134 +
.../services/HDFS/configuration/hdfs-site.xml | 484 ++
.../stacks/HDP/2.0._/services/HDFS/metainfo.xml | 60 +
.../stacks/HDP/2.0._/services/HDFS/metrics.json | 7790 ++++++++++++++++++
.../services/HIVE/configuration/hive-site.xml | 260 +
.../stacks/HDP/2.0._/services/HIVE/metainfo.xml | 45 +
.../configuration/container-executor.cfg | 20 +
.../MAPREDUCE2/configuration/core-site.xml | 20 +
.../MAPREDUCE2/configuration/global.xml | 44 +
.../configuration/mapred-queue-acls.xml | 39 +
.../MAPREDUCE2/configuration/mapred-site.xml | 381 +
.../HDP/2.0._/services/MAPREDUCE2/metainfo.xml | 37 +
.../HDP/2.0._/services/MAPREDUCE2/metrics.json | 383 +
.../HDP/2.0._/services/NAGIOS/metainfo.xml | 30 +
.../services/OOZIE/configuration/oozie-site.xml | 313 +
.../HDP/2.0._/services/OOZIE/metainfo.xml | 38 +
.../services/PIG/configuration/pig.properties | 52 +
.../stacks/HDP/2.0._/services/PIG/metainfo.xml | 30 +
.../HDP/2.0._/services/SQOOP/metainfo.xml | 30 +
.../WEBHCAT/configuration/webhcat-site.xml | 126 +
.../HDP/2.0._/services/WEBHCAT/metainfo.xml | 31 +
.../YARN/configuration/capacity-scheduler.xml | 120 +
.../YARN/configuration/container-executor.cfg | 20 +
.../services/YARN/configuration/core-site.xml | 20 +
.../services/YARN/configuration/global.xml | 64 +
.../services/YARN/configuration/yarn-site.xml | 326 +
.../stacks/HDP/2.0._/services/YARN/metainfo.xml | 42 +
.../stacks/HDP/2.0._/services/YARN/metrics.json | 2494 ++++++
.../services/ZOOKEEPER/configuration/global.xml | 75 +
.../HDP/2.0._/services/ZOOKEEPER/metainfo.xml | 35 +
.../server/api/services/AmbariMetaInfoTest.java | 2 +
.../api/util/StackExtensionHelperTest.java | 161 +
.../AmbariManagementControllerTest.java | 10 +-
.../ambari/server/metadata/RoleGraphTest.java | 6 +-
.../stacks/HDP/2.0.6/role_command_order.json | 36 +-
.../resources/stacks/HDP/2.0.7/metainfo.xml | 24 +
.../stacks/HDP/2.0.7/repos/repoinfo.xml | 61 +
.../stacks/HDP/2.0.7/role_command_order.json | 100 +
.../services/HBASE/configuration/global.xml | 160 +
.../HBASE/configuration/hbase-policy.xml | 53 +
.../services/HBASE/configuration/hbase-site.xml | 356 +
.../HDP/2.0.7/services/HBASE/metainfo.xml | 116 +
.../HDP/2.0.7/services/HBASE/scripts/hbase.py | 1 +
.../services/HBASE/scripts/hbase_client.py | 1 +
.../services/HBASE/scripts/hbase_master.py | 1 +
.../HBASE/scripts/hbase_regionserver.py | 1 +
.../services/YARN/configuration/yarn-site.xml | 60 +
.../stacks/HDP/2.0.7/services/YARN/metainfo.xml | 45 +
89 files changed, 17219 insertions(+), 709 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
index b568335..6c86858 100644
--- a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
+++ b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
@@ -84,7 +84,7 @@ class CustomServiceOrchestrator():
"""
Incapsulates logic of script location determination.
"""
- path = os.path.join(base_dir, "package", script)
+ path = os.path.join(base_dir, script)
if not os.path.exists(path):
message = "Script {0} does not exist".format(path)
raise AgentException(message)
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-agent/src/main/python/ambari_agent/FileCache.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/FileCache.py b/ambari-agent/src/main/python/ambari_agent/FileCache.py
index c02f217..27c4030 100644
--- a/ambari-agent/src/main/python/ambari_agent/FileCache.py
+++ b/ambari-agent/src/main/python/ambari_agent/FileCache.py
@@ -46,7 +46,8 @@ class FileCache():
Returns a base directory for service
"""
metadata_path = os.path.join(self.cache_dir, "stacks", str(stack_name),
- str(stack_version), "services", str(service))
+ str(stack_version), "services", str(service),
+ "package")
if not os.path.isdir(metadata_path):
# TODO: Metadata downloading will be implemented at Phase 2
# As of now, all stack definitions are packaged and distributed with
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py b/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
index b9aab2a..724dd5f 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
@@ -82,7 +82,7 @@ class TestCustomServiceOrchestrator(TestCase):
# Testing existing path
exists_mock.return_value = True
path = orchestrator.\
- resolve_script_path("/HBASE", "scripts/hbase_master.py", "PYTHON")
+ resolve_script_path("/HBASE/package", "scripts/hbase_master.py", "PYTHON")
self.assertEqual("/HBASE/package/scripts/hbase_master.py", path)
# Testing not existing path
exists_mock.return_value = False
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestFileCache.py b/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
index 8426012..eb30e0c 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
@@ -58,7 +58,8 @@ class TestFileCache(TestCase):
isdir_mock.return_value = True
base = fileCache.get_service_base_dir("HDP", "2.0.7",
"HBASE", "REGION_SERVER")
- self.assertEqual(base, "/var/lib/ambari-agent/cache/stacks/HDP/2.0.7/services/HBASE")
+ self.assertEqual(base, "/var/lib/ambari-agent/cache/stacks/HDP/2.0.7/"
+ "services/HBASE/package")
def tearDown(self):
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
index ad006ec..94013c2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
@@ -25,5 +25,6 @@ public enum RoleCommand {
EXECUTE,
ABORT,
UPGRADE,
+ SERVICE_CHECK,
ACTIONEXECUTE
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
index 9a8d708..29a4904 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
@@ -193,7 +193,7 @@ class ActionScheduler implements Runnable {
try {
long now = System.currentTimeMillis();
String hostName = cmd.getHostname();
- String roleName = cmd.getRole().toString();
+ String roleName = cmd.getRole();
s.setStartTime(hostName, roleName, now);
s.setLastAttemptTime(hostName, roleName, now);
@@ -323,7 +323,7 @@ class ActionScheduler implements Runnable {
Host hostObj = fsmObject.getHost(host);
for(ExecutionCommandWrapper wrapper : commandWrappers) {
ExecutionCommand c = wrapper.getExecutionCommand();
- String roleStr = c.getRole().toString();
+ String roleStr = c.getRole();
HostRoleStatus status = s.getHostRoleStatus(host, roleStr);
if (timeOutActionNeeded(status, s, hostObj, roleStr, now,
taskTimeout)) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostAction.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostAction.java
deleted file mode 100644
index 2327d07..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostAction.java
+++ /dev/null
@@ -1,104 +0,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.
- */
-package org.apache.ambari.server.actionmanager;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.ambari.server.agent.ExecutionCommand;
-import org.apache.ambari.server.utils.StageUtils;
-
-/**
- * Encapsulates entire task for a host for a stage or action. This class
- * contains all the information to generate an
- * {@link org.apache.ambari.server.agent.ExecutionCommand} that will be
- * scheduled for a host.
- */
-public class HostAction {
- private final String host;
- private List<HostRoleCommand> roles;
- private long startTime = -1;
- private long lastAttemptTime = -1;
- private short attemptCount = 0;
-
- /**
- * This object will be serialized and sent to the agent.
- */
- private ExecutionCommand commandToHost;
-
- public String getManifest() {
- //generate manifest
- return null;
- }
-
- public HostAction(String host) {
- this.host = host;
- roles = new ArrayList<HostRoleCommand>();
- commandToHost = new ExecutionCommand();
- commandToHost.setHostname(host);
- }
-
- public HostAction(HostAction ha) {
- this.host = ha.host;
- this.roles = ha.roles;
- this.startTime = ha.startTime;
- this.lastAttemptTime = ha.lastAttemptTime;
- this.attemptCount = ha.attemptCount;
- this.commandToHost = ha.commandToHost;
- }
-
- public void addHostRoleCommand(HostRoleCommand cmd) {
- roles.add(cmd);
- }
-
- public List<HostRoleCommand> getRoleCommands() {
- return roles;
- }
-
- public long getStartTime() {
- return startTime;
- }
-
- public long getLastAttemptTime() {
- return this.lastAttemptTime;
- }
-
- public void setLastAttemptTime(long t) {
- this.lastAttemptTime = t;
- }
-
- public void incrementAttemptCount() {
- this.attemptCount ++;
- }
-
- public short getAttemptCount() {
- return this.attemptCount;
- }
-
- public ExecutionCommand getCommandToHost() {
- return this.commandToHost;
- }
-
- public synchronized void setCommandId(long requestId, long stageId) {
- commandToHost.setCommandId(StageUtils.getActionId(requestId, stageId));
- }
-
- public void setStartTime(long startTime) {
- this.startTime = startTime;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
index 21ec077..b797a7b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
@@ -35,7 +35,6 @@ import com.google.inject.Injector;
* particular role which action manager needs. It doesn't capture actual
* command and parameters, but just the stuff enough for action manager to
* track the request.
- * For the actual command refer {@link HostAction#commandToHost}
*/
public class HostRoleCommand {
private static final Logger log = LoggerFactory.getLogger(HostRoleCommand.class);
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
index cee8812..264e5d7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
@@ -231,6 +231,11 @@ public class Stage {
execCmdList.add(wrapper);
}
+
+ /**
+ * Creates server-side execution command. As of now, it seems to
+ * be used only for server upgrade
+ */
public synchronized void addServerActionCommand(
String actionName, Role role, RoleCommand command, String clusterName,
ServiceComponentHostUpgradeEvent event, String hostName) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index c72c14b..0909020 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -40,6 +40,8 @@ public class ExecutionCommand extends AgentCommand {
public ExecutionCommand() {
super(AgentCommandType.EXECUTION_COMMAND);
}
+
+
private String clusterName;
private long taskId;
private String commandId;
@@ -227,4 +229,32 @@ public class ExecutionCommand extends AgentCommand {
return configurationTags;
}
+
+ /**
+ * Contains key name strings. These strings are used inside maps
+ * incapsulated inside command.
+ */
+ public static interface KeyNames {
+
+ String SCHEMA_VERSION = "schema_version";
+ String COMMAND_TIMEOUT = "command_timeout";
+ String SCRIPT = "script";
+ String SCRIPT_TYPE = "script_type";
+ String SERVICE_METADATA_FOLDER = "service_metadata_folder";
+ String STACK_NAME = "stack_name";
+ String STACK_VERSION = "stack_version";
+ String SERVICE_REPO_INFO = "service_repo_info";
+ String PACKAGE_LIST = "package_list";
+ String JDK_LOCATION = "jdk_location";
+ String MYSQL_JDBC_URL = "mysql_jdbc_url";
+ String ORACLE_JDBC_URL = "oracle_jdbc_url";
+ String DB_DRIVER_FILENAME = "db_driver_filename";
+ String REPO_INFO = "repo_info";
+ String DB_NAME = "db_name";
+ String SERVICE_CHECK = "SERVICE_CHECK"; // TODO: is it standart command? maybe add it to RoleCommand enum?
+
+ String COMMAND_TIMEOUT_DEFAULT = "600"; // TODO: Will be replaced by proper initialization in another jira
+
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/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 942be70..2305d5e 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
@@ -85,11 +85,27 @@ public class AmbariMetaInfo {
public static final String SERVICE_METRIC_FILE_NAME = "metrics.json";
+ /**
+ * This string is used in placeholder in places that are common for
+ * all operating systems or in situations where os type is not important.
+ */
+ public static final String ANY_OS = "any";
+
+ /**
+ * Value for legacy xml files that don't contain schema property
+ */
+ public static final String SCHEMA_VERSION_LEGACY = "1.0";
+
+ /**
+ * Version of XML files with support of custom services and custom commands
+ */
+ public static final String SCHEMA_VERSION_2 = "2.0";
+
+
public static final FilenameFilter FILENAME_FILTER = new FilenameFilter() {
@Override
public boolean accept(File dir, String s) {
- if (s.equals(".svn") || s.equals(".git")
- || s.endsWith("_")) // Temporary hack: ignore such names
+ if (s.equals(".svn") || s.equals(".git"))
return false;
return true;
}
@@ -554,6 +570,10 @@ public class AmbariMetaInfo {
return propertyResult;
}
+
+ /**
+ * Lists operatingsystems supported by stack
+ */
public Set<OperatingSystemInfo> getOperatingSystems(String stackName, String version)
throws AmbariException {
@@ -613,6 +633,7 @@ public class AmbariMetaInfo {
StackExtensionHelper stackExtensionHelper = new StackExtensionHelper
(stackRoot);
+ stackExtensionHelper.fillInfo();
List<StackInfo> stacks = stackExtensionHelper.getAllAvailableStacks();
if (stacks.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
index 6307db3..0883ad4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.api.util;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -29,18 +30,22 @@ import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.PropertyInfo;
-import org.apache.ambari.server.state.ServiceInfo;
-import org.apache.ambari.server.state.StackInfo;
-import org.apache.ambari.server.state.stack.ConfigurationXml;
-import org.apache.ambari.server.state.stack.RepositoryXml;
-import org.apache.ambari.server.state.stack.ServiceMetainfoXml;
-import org.apache.ambari.server.state.stack.StackMetainfoXml;
+import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.state.stack.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
/**
* Helper methods for providing stack extension behavior -
@@ -52,25 +57,40 @@ public class StackExtensionHelper {
.getLogger(StackExtensionHelper.class);
private final Map<String, StackInfo> stackVersionMap = new HashMap<String,
StackInfo>();
- private final Map<String, List<StackInfo>> stackParentsMap;
+ private Map<String, List<StackInfo>> stackParentsMap = null;
private static final Map<Class<?>, JAXBContext> _jaxbContexts =
new HashMap<Class<?>, JAXBContext> ();
static {
try {
- // two classes define the top-level element "metainfo", so we need 2 contexts.
+ // three classes define the top-level element "metainfo", so we need 3 contexts.
JAXBContext ctx = JAXBContext.newInstance(StackMetainfoXml.class, RepositoryXml.class, ConfigurationXml.class);
_jaxbContexts.put(StackMetainfoXml.class, ctx);
_jaxbContexts.put(RepositoryXml.class, ctx);
_jaxbContexts.put(ConfigurationXml.class, ctx);
_jaxbContexts.put(ServiceMetainfoXml.class, JAXBContext.newInstance(ServiceMetainfoXml.class));
+ _jaxbContexts.put(ServiceMetainfoV2Xml.class, JAXBContext.newInstance(ServiceMetainfoV2Xml.class));
} catch (JAXBException e) {
throw new RuntimeException (e);
}
- }
-
- public StackExtensionHelper(File stackRoot) throws Exception {
+ }
+
+ /**
+ * Note: constructor does not perform inialisation now. After instance
+ * creation, you have to call fillInfo() manually
+ */
+ public StackExtensionHelper(File stackRoot) {
this.stackRoot = stackRoot;
+ }
+
+
+ /**
+ * Must be manually called after creation of StackExtensionHelper instance
+ */
+ public void fillInfo() throws Exception {
+ if (stackParentsMap != null) {
+ throw new AmbariException("fillInfo() method has already been called");
+ }
File[] stackFiles = stackRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER);
for (File stack : stackFiles) {
if (stack.isFile()) {
@@ -85,11 +105,13 @@ public class StackExtensionHelper {
stackVersionMap.put(stackName + stackVersion, getStackInfo(stackFolder));
}
}
- this.stackParentsMap = getParentStacksInOrder(stackVersionMap.values());
+ stackParentsMap = getParentStacksInOrder(stackVersionMap.values());
}
+
private ServiceInfo mergeServices(ServiceInfo parentService,
ServiceInfo childService) {
+ // TODO: Allow extending stack with custom services
ServiceInfo mergedServiceInfo = new ServiceInfo();
mergedServiceInfo.setName(childService.getName());
mergedServiceInfo.setComment(childService.getComment());
@@ -186,7 +208,9 @@ public class StackExtensionHelper {
return new ArrayList<ServiceInfo>(serviceInfoMap.values());
}
- private void populateServicesForStack(StackInfo stackInfo) {
+ void populateServicesForStack(StackInfo stackInfo) throws
+ ParserConfigurationException, SAXException,
+ XPathExpressionException, IOException, JAXBException {
List<ServiceInfo> services = new ArrayList<ServiceInfo>();
File servicesFolder = new File(stackRoot.getAbsolutePath() + File
.separator + stackInfo.getName() + File.separator + stackInfo.getVersion()
@@ -196,50 +220,76 @@ public class StackExtensionHelper {
"-" + stackInfo.getVersion());
} else {
- File[] servicesFolders = servicesFolder.listFiles(AmbariMetaInfo
- .FILENAME_FILTER);
- if (servicesFolders != null) {
+ try {
+ File[] servicesFolders = servicesFolder.listFiles(AmbariMetaInfo
+ .FILENAME_FILTER);
+ if (servicesFolders == null) {
+ String message = String.format("No service folders found at %s",
+ servicesFolder.getAbsolutePath());
+ throw new AmbariException(message);
+ }
+ // Iterate over service folders
for (File serviceFolder : servicesFolders) {
if (!serviceFolder.isDirectory())
continue;
-
- // Get information about service
- ServiceInfo serviceInfo = new ServiceInfo();
- serviceInfo.setName(serviceFolder.getName());
+ // Get metainfo schema format version
File metainfoFile = new File(serviceFolder.getAbsolutePath()
- + File.separator + AmbariMetaInfo.SERVICE_METAINFO_FILE_NAME);
-
- setMetaInfo(metainfoFile, serviceInfo);
-
+ + File.separator + AmbariMetaInfo.SERVICE_METAINFO_FILE_NAME);
// get metrics file, if it exists
File metricsJson = new File(serviceFolder.getAbsolutePath()
- + File.separator + AmbariMetaInfo.SERVICE_METRIC_FILE_NAME);
- if (metricsJson.exists())
- serviceInfo.setMetricsFile(metricsJson);
-
- // Add now to be removed while iterating extension graph
- services.add(serviceInfo);
-
- // Get all properties from all "configs/*-site.xml" files
- File serviceConfigFolder = new File(serviceFolder.getAbsolutePath()
- + File.separator + AmbariMetaInfo.SERVICE_CONFIG_FOLDER_NAME);
- File[] configFiles = serviceConfigFolder.listFiles
- (AmbariMetaInfo.FILENAME_FILTER);
- if (configFiles != null) {
- for (File config : configFiles) {
- if (config.getName().endsWith
- (AmbariMetaInfo.SERVICE_CONFIG_FILE_NAME_POSTFIX)) {
- serviceInfo.getProperties().addAll(getProperties(config));
- }
+ + File.separator + AmbariMetaInfo.SERVICE_METRIC_FILE_NAME);
+ String version = getSchemaVersion(metainfoFile);
+ if (AmbariMetaInfo.SCHEMA_VERSION_LEGACY.equals(version)) {
+ // Get information about service
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.setSchemaVersion(AmbariMetaInfo.SCHEMA_VERSION_LEGACY);
+ serviceInfo.setName(serviceFolder.getName());
+ ServiceMetainfoXml smx = unmarshal(ServiceMetainfoXml.class, metainfoFile);
+ serviceInfo.setComment(smx.getComment());
+ serviceInfo.setUser(smx.getUser());
+ serviceInfo.setVersion(smx.getVersion());
+ serviceInfo.setDeleted(smx.isDeleted());
+ serviceInfo.setConfigDependencies(smx.getConfigDependencies());
+ serviceInfo.getComponents().addAll(smx.getComponents());
+
+ if (metricsJson.exists())
+ serviceInfo.setMetricsFile(metricsJson);
+
+ // Get all properties from all "configs/*-site.xml" files
+ setPropertiesFromConfigs(serviceFolder, serviceInfo);
+
+ // Add now to be removed while iterating extension graph
+ services.add(serviceInfo);
+ } else { //Reading v2 service metainfo (may contain multiple services)
+ // Get services from metadata
+ ServiceMetainfoV2Xml smiv2x =
+ unmarshal(ServiceMetainfoV2Xml.class, metainfoFile);
+ List<ServiceInfo> serviceInfos = smiv2x.getServices();
+ for (ServiceInfo serviceInfo : serviceInfos) {
+ serviceInfo.setSchemaVersion(AmbariMetaInfo.SCHEMA_VERSION_2);
+ serviceInfo.setServiceMetadataFolder(serviceFolder.getName());
+ // TODO: allow repository overriding when extending stack
+
+ if (metricsJson.exists())
+ serviceInfo.setMetricsFile(metricsJson);
+
+ // Get all properties from all "configs/*-site.xml" files
+ setPropertiesFromConfigs(serviceFolder, serviceInfo);
+
+ // Add now to be removed while iterating extension graph
+ services.add(serviceInfo);
}
}
}
+ } catch (Exception e) {
+ LOG.error("Error while parsing metainfo.xml for a service", e);
}
}
stackInfo.getServices().addAll(services);
}
+
public List<StackInfo> getAllAvailableStacks() {
return new ArrayList<StackInfo>(stackVersionMap.values());
}
@@ -271,6 +321,36 @@ public class StackExtensionHelper {
return parentStacksMap;
}
+
+ /**
+ * Determines schema version of a given metainfo file
+ * @param stackMetainfoFile xml file
+ */
+ String getSchemaVersion(File stackMetainfoFile) throws IOException,
+ ParserConfigurationException, SAXException, XPathExpressionException {
+ // Using XPath to get a single value from an metainfo file
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(stackMetainfoFile);
+ XPathFactory xPathfactory = XPathFactory.newInstance();
+ XPath xpath = xPathfactory.newXPath();
+ XPathExpression schemaPath = xpath.compile("/metainfo/schemaVersion[1]");
+
+ String value = schemaPath.evaluate(doc).trim();
+ if ( "".equals(value) || // If schemaVersion is not defined
+ AmbariMetaInfo.SCHEMA_VERSION_LEGACY.equals(value)) {
+ return AmbariMetaInfo.SCHEMA_VERSION_LEGACY;
+ } else if (AmbariMetaInfo.SCHEMA_VERSION_2.equals(value)) {
+ return AmbariMetaInfo.SCHEMA_VERSION_2;
+ } else {
+ String message = String.format("Unknown schema version %s at file " +
+ "%s", value, stackMetainfoFile.getAbsolutePath());
+ throw new AmbariException(message);
+ }
+
+ }
+
+
private StackInfo getStackInfo(File stackVersionFolder) throws JAXBException {
StackInfo stackInfo = new StackInfo();
@@ -308,22 +388,6 @@ public class StackExtensionHelper {
return stackInfo;
}
- private void setMetaInfo(File metainfoFile, ServiceInfo serviceInfo) {
- try {
- ServiceMetainfoXml smx = unmarshal(ServiceMetainfoXml.class, metainfoFile);
-
- serviceInfo.setComment(smx.getComment());
- serviceInfo.setUser(smx.getUser());
- serviceInfo.setVersion(smx.getVersion());
- serviceInfo.setDeleted(smx.isDeleted());
- serviceInfo.setConfigDependencies(smx.getConfigDependencies());
-
- serviceInfo.getComponents().addAll(smx.getComponents());
- } catch (Exception e) {
- LOG.error("Error while parsing metainfo.xml for a service", e);
- }
-
- }
private List<PropertyInfo> getProperties(File propertyFile) {
@@ -340,13 +404,32 @@ public class StackExtensionHelper {
pi.setFilename(propertyFile.getName());
list.add(pi);
}
-
return list;
} catch (Exception e) {
LOG.error("Could not load configuration for " + propertyFile, e);
return null;
}
}
+
+
+ /**
+ * Get all properties from all "configs/*-site.xml" files
+ */
+ void setPropertiesFromConfigs(File serviceFolder, ServiceInfo serviceInfo) {
+ File serviceConfigFolder = new File(serviceFolder.getAbsolutePath()
+ + File.separator + AmbariMetaInfo.SERVICE_CONFIG_FOLDER_NAME);
+ File[] configFiles = serviceConfigFolder.listFiles
+ (AmbariMetaInfo.FILENAME_FILTER);
+ if (configFiles != null) {
+ for (File config : configFiles) {
+ if (config.getName().endsWith
+ (AmbariMetaInfo.SERVICE_CONFIG_FILE_NAME_POSTFIX)) {
+ serviceInfo.getProperties().addAll(getProperties(config));
+ }
+ }
+ }
+ }
+
public static <T> T unmarshal(Class<T> clz, File file) throws JAXBException {
Unmarshaller u = _jaxbContexts.get(clz).createUnmarshaller();
@@ -354,4 +437,4 @@ public class StackExtensionHelper {
return clz.cast(u.unmarshal(file));
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
index 632b11d..a008780 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
@@ -51,7 +51,7 @@ import java.util.TreeMap;
*/
public class AmbariActionExecutionHelper {
private final static Logger LOG =
- LoggerFactory.getLogger(AmbariCustomCommandExecutionHelper.class);
+ LoggerFactory.getLogger(AmbariActionExecutionHelper.class);
private ActionMetadata actionMetadata;
private Clusters clusters;
private AmbariManagementControllerImpl amcImpl;
@@ -275,6 +275,10 @@ public class AmbariActionExecutionHelper {
ExecutionCommand execCmd = stage.getExecutionCommandWrapper(hostName,
actionContext.getActionName()).getExecutionCommand();
+ /*
+ * TODO Execution command field population should be (partially?)
+ * combined with the same code at createHostAction()
+ */
execCmd.setConfigurations(configurations);
execCmd.setConfigurationTags(configTags);
execCmd.setHostLevelParams(hostLevelParams);
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index fa7522b..6165f59 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -1,239 +1,37 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package org.apache.ambari.server.controller;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
import org.apache.ambari.server.actionmanager.Stage;
-import org.apache.ambari.server.agent.ExecutionCommand;
-import org.apache.ambari.server.configuration.Configuration;
-import org.apache.ambari.server.metadata.ActionMetadata;
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.ConfigHelper;
-import org.apache.ambari.server.state.ServiceComponent;
import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent;
-import org.apache.ambari.server.utils.StageUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Helper class containing logic to process custom command execution requests
- */
-public class AmbariCustomCommandExecutionHelper {
- private final static Logger LOG =
- LoggerFactory.getLogger(AmbariCustomCommandExecutionHelper.class);
- private ActionMetadata actionMetadata;
- private Clusters clusters;
- private AmbariManagementControllerImpl amcImpl;
-
- public AmbariCustomCommandExecutionHelper(ActionMetadata actionMetadata, Clusters clusters,
- AmbariManagementControllerImpl amcImpl) {
- this.amcImpl = amcImpl;
- this.actionMetadata = actionMetadata;
- this.clusters = clusters;
- }
-
- public void validateCustomCommand(ExecuteActionRequest actionRequest) throws AmbariException {
- if (actionRequest.getServiceName() == null
- || actionRequest.getServiceName().isEmpty()
- || actionRequest.getCommandName() == null
- || actionRequest.getCommandName().isEmpty()) {
- throw new AmbariException("Invalid request : " + "cluster="
- + actionRequest.getClusterName() + ", service="
- + actionRequest.getServiceName() + ", command="
- + actionRequest.getCommandName());
- }
-
- LOG.info("Received a command execution request"
- + ", clusterName=" + actionRequest.getClusterName()
- + ", serviceName=" + actionRequest.getServiceName()
- + ", request=" + actionRequest.toString());
-
- if (!isValidCommand(actionRequest.getCommandName(), actionRequest.getServiceName())) {
- throw new AmbariException(
- "Unsupported action " + actionRequest.getCommandName() + " for " + actionRequest.getServiceName());
- }
- }
-
- private Boolean isValidCommand(String command, String service) {
- List<String> actions = actionMetadata.getActions(service);
- if (actions == null || actions.size() == 0) {
- return false;
- }
-
- if (!actions.contains(command)) {
- return false;
- }
-
- return true;
- }
-
- public void addAction(ExecuteActionRequest actionRequest, Stage stage,
- Configuration configuration, HostsMap hostsMap, Map<String, String> hostLevelParams)
- throws AmbariException {
- if (actionRequest.getCommandName().contains("SERVICE_CHECK")) {
- addServiceCheckAction(actionRequest, stage, configuration, hostsMap, hostLevelParams);
- } else if (actionRequest.getCommandName().equals("DECOMMISSION_DATANODE")) {
- addDecommissionDatanodeAction(actionRequest, stage, hostLevelParams);
- } else {
- throw new AmbariException("Unsupported action " + actionRequest.getCommandName());
- }
- }
-
- private void addServiceCheckAction(ExecuteActionRequest actionRequest, Stage stage,
- Configuration configuration, HostsMap hostsMap,
- Map<String, String> hostLevelParams)
- throws AmbariException {
- String clusterName = actionRequest.getClusterName();
- String componentName = actionMetadata.getClient(actionRequest
- .getServiceName());
-
- String hostName;
- if (componentName != null) {
- Map<String, ServiceComponentHost> components = clusters
- .getCluster(clusterName).getService(actionRequest.getServiceName())
- .getServiceComponent(componentName).getServiceComponentHosts();
-
- if (components.isEmpty()) {
- throw new AmbariException("Hosts not found, component="
- + componentName + ", service=" + actionRequest.getServiceName()
- + ", cluster=" + clusterName);
- }
- hostName = amcImpl.getHealthyHost(components.keySet());
- } else {
- Map<String, ServiceComponent> components = clusters
- .getCluster(clusterName).getService(actionRequest.getServiceName())
- .getServiceComponents();
-
- if (components.isEmpty()) {
- throw new AmbariException("Components not found, service="
- + actionRequest.getServiceName() + ", cluster=" + clusterName);
- }
-
- ServiceComponent serviceComponent = components.values().iterator()
- .next();
-
- if (serviceComponent.getServiceComponentHosts().isEmpty()) {
- throw new AmbariException("Hosts not found, component="
- + serviceComponent.getName() + ", service="
- + actionRequest.getServiceName() + ", cluster=" + clusterName);
- }
-
- hostName = serviceComponent.getServiceComponentHosts().keySet()
- .iterator().next();
- }
-
- stage.addHostRoleExecutionCommand(hostName, Role.valueOf(actionRequest
- .getCommandName()), RoleCommand.EXECUTE,
- new ServiceComponentHostOpInProgressEvent(componentName, hostName,
- System.currentTimeMillis()), clusterName, actionRequest
- .getServiceName());
-
- stage.getExecutionCommandWrapper(hostName, actionRequest.getCommandName()).getExecutionCommand()
- .setRoleParams(actionRequest.getParameters());
-
- Cluster cluster = clusters.getCluster(clusterName);
-
- // [ type -> [ key, value ] ]
- Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
- Map<String, Map<String, String>> configTags = amcImpl.findConfigurationTagsWithOverrides(cluster, hostName);
-
- ExecutionCommand execCmd = stage.getExecutionCommandWrapper(hostName,
- actionRequest.getCommandName()).getExecutionCommand();
-
- execCmd.setConfigurations(configurations);
- execCmd.setConfigurationTags(configTags);
- execCmd.setHostLevelParams(hostLevelParams);
-
- // Generate cluster host info
- execCmd.setClusterHostInfo(
- StageUtils.getClusterHostInfo(clusters.getHostsForCluster(clusterName), cluster, hostsMap, configuration));
- }
-
- private void addDecommissionDatanodeAction(ExecuteActionRequest decommissionRequest, Stage stage,
- Map<String, String> hostLevelParams)
- throws AmbariException {
- String hdfsExcludeFileType = "hdfs-exclude-file";
- // Find hdfs admin host, just decommission from namenode.
- String clusterName = decommissionRequest.getClusterName();
- Cluster cluster = clusters.getCluster(clusterName);
- String serviceName = decommissionRequest.getServiceName();
- String namenodeHost = clusters.getCluster(clusterName)
- .getService(serviceName).getServiceComponent(Role.NAMENODE.toString())
- .getServiceComponentHosts().keySet().iterator().next();
-
- String excludeFileTag = null;
- if (decommissionRequest.getParameters() != null
- && (decommissionRequest.getParameters().get("excludeFileTag") != null)) {
- excludeFileTag = decommissionRequest.getParameters()
- .get("excludeFileTag");
- }
-
- if (excludeFileTag == null) {
- throw new AmbariException("No exclude file specified"
- + " when decommissioning datanodes. Provide parameter excludeFileTag with the tag for config type "
- + hdfsExcludeFileType);
- }
-
- Config config = clusters.getCluster(clusterName).getConfig(
- hdfsExcludeFileType, excludeFileTag);
- if (config == null) {
- throw new AmbariException("Decommissioning datanodes requires the cluster to be associated with config type " +
- hdfsExcludeFileType + " with a list of datanodes to be decommissioned (\"datanodes\" : list).");
- }
-
- LOG.info("Decommissioning data nodes: " + config.getProperties().get("datanodes") +
- " " + hdfsExcludeFileType + " tag: " + excludeFileTag);
-
- Map<String, Map<String, String>> configurations =
- new TreeMap<String, Map<String, String>>();
-
-
- Map<String, Map<String, String>> configTags = amcImpl.findConfigurationTagsWithOverrides(cluster, namenodeHost);
-
- // Add the tag for hdfs-exclude-file
- Map<String, String> excludeTags = new HashMap<String, String>();
- excludeTags.put(ConfigHelper.CLUSTER_DEFAULT_TAG, config.getVersionTag());
- configTags.put(hdfsExcludeFileType, excludeTags);
-
- stage.addHostRoleExecutionCommand(
- namenodeHost,
- Role.DECOMMISSION_DATANODE,
- RoleCommand.EXECUTE,
- new ServiceComponentHostOpInProgressEvent(Role.DECOMMISSION_DATANODE
- .toString(), namenodeHost, System.currentTimeMillis()),
- clusterName, serviceName);
-
- ExecutionCommand execCmd = stage.getExecutionCommandWrapper(namenodeHost,
- Role.DECOMMISSION_DATANODE.toString()).getExecutionCommand();
- execCmd.setConfigurations(configurations);
- execCmd.setConfigurationTags(configTags);
- execCmd.setHostLevelParams(hostLevelParams);
- }
-}
\ No newline at end of file
+public interface AmbariCustomCommandExecutionHelper {
+ void validateCustomCommand(ExecuteActionRequest actionRequest) throws AmbariException;
+
+ void addAction(ExecuteActionRequest actionRequest, Stage stage,
+ HostsMap hostsMap, Map<String, String> hostLevelParams)
+ throws AmbariException;
+
+ void addServiceCheckActionImpl(Stage stage,
+ String hostname, String smokeTestRole,
+ long nowTimestamp,
+ String serviceName,
+ String componentName,
+ Map<String, String> roleParameters,
+ HostsMap hostsMap,
+ Map<String, String> hostLevelParams)
+ throws AmbariException;
+
+ void createHostAction(Cluster cluster,
+ Stage stage, ServiceComponentHost scHost,
+ Map<String, Map<String, String>> configurations,
+ Map<String, Map<String, String>> configTags,
+ RoleCommand roleCommand,
+ Map<String, String> commandParams,
+ ServiceComponentHostEvent event)
+ throws AmbariException;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
new file mode 100644
index 0000000..cd5f6fb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperImpl.java
@@ -0,0 +1,471 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.actionmanager.Stage;
+import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.metadata.ActionMetadata;
+import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent;
+import org.apache.ambari.server.utils.StageUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
+
+
+/**
+ * Helper class containing logic to process custom command execution requests
+ */
+@Singleton
+public class AmbariCustomCommandExecutionHelperImpl implements AmbariCustomCommandExecutionHelper {
+ private final static Logger LOG =
+ LoggerFactory.getLogger(AmbariCustomCommandExecutionHelperImpl.class);
+
+ @Inject
+ private ActionMetadata actionMetadata;
+ @Inject
+ private Clusters clusters;
+ @Inject
+ private AmbariManagementController amc;
+ @Inject
+ private Gson gson;
+ @Inject
+ private Configuration configs;
+ @Inject
+ private AmbariMetaInfo ambariMetaInfo;
+ @Inject
+ private ConfigHelper configHelper;
+
+
+ @Override
+ public void validateCustomCommand(ExecuteActionRequest actionRequest) throws AmbariException {
+ if (actionRequest.getServiceName() == null
+ || actionRequest.getServiceName().isEmpty()
+ || actionRequest.getCommandName() == null
+ || actionRequest.getCommandName().isEmpty()) {
+ throw new AmbariException("Invalid request : " + "cluster="
+ + actionRequest.getClusterName() + ", service="
+ + actionRequest.getServiceName() + ", command="
+ + actionRequest.getCommandName());
+ }
+
+ LOG.info("Received a command execution request"
+ + ", clusterName=" + actionRequest.getClusterName()
+ + ", serviceName=" + actionRequest.getServiceName()
+ + ", request=" + actionRequest.toString());
+
+ if (!isValidCommand(actionRequest.getCommandName(), actionRequest.getServiceName())) {
+ throw new AmbariException(
+ "Unsupported action " + actionRequest.getCommandName() + " for " + actionRequest.getServiceName());
+ }
+ }
+
+ private Boolean isValidCommand(String command, String service) {
+ List<String> actions = actionMetadata.getActions(service);
+ if (actions == null || actions.size() == 0) {
+ return false;
+ }
+
+ if (!actions.contains(command)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void addAction(ExecuteActionRequest actionRequest, Stage stage,
+ HostsMap hostsMap, Map<String, String> hostLevelParams)
+ throws AmbariException {
+ if (actionRequest.getCommandName().contains("SERVICE_CHECK")) {
+ addServiceCheckAction(actionRequest, stage, hostsMap, hostLevelParams);
+ } else if (actionRequest.getCommandName().equals("DECOMMISSION_DATANODE")) {
+ addDecommissionDatanodeAction(actionRequest, stage, hostLevelParams);
+ } else {
+ throw new AmbariException("Unsupported action " + actionRequest.getCommandName());
+ }
+ }
+
+ private void addServiceCheckAction(ExecuteActionRequest actionRequest, Stage stage,
+ HostsMap hostsMap,
+ Map<String, String> hostLevelParams)
+ throws AmbariException {
+ String clusterName = actionRequest.getClusterName();
+ String componentName = actionMetadata.getClient(actionRequest
+ .getServiceName());
+ String serviceName = actionRequest.getServiceName();
+ String smokeTestRole = actionRequest.getCommandName();
+ long nowTimestamp = System.currentTimeMillis();
+ Map<String, String> roleParameters = actionRequest.getParameters();
+
+ String hostName;
+ if (componentName != null) {
+ Map<String, ServiceComponentHost> components = clusters
+ .getCluster(clusterName).getService(actionRequest.getServiceName())
+ .getServiceComponent(componentName).getServiceComponentHosts();
+
+ if (components.isEmpty()) {
+ throw new AmbariException("Hosts not found, component="
+ + componentName + ", service=" + actionRequest.getServiceName()
+ + ", cluster=" + clusterName);
+ }
+ hostName = amc.getHealthyHost(components.keySet());
+ } else {
+ Map<String, ServiceComponent> components = clusters
+ .getCluster(clusterName).getService(actionRequest.getServiceName())
+ .getServiceComponents();
+
+ if (components.isEmpty()) {
+ throw new AmbariException("Components not found, service="
+ + actionRequest.getServiceName() + ", cluster=" + clusterName);
+ }
+
+ ServiceComponent serviceComponent = components.values().iterator()
+ .next();
+
+ if (serviceComponent.getServiceComponentHosts().isEmpty()) {
+ throw new AmbariException("Hosts not found, component="
+ + serviceComponent.getName() + ", service="
+ + actionRequest.getServiceName() + ", cluster=" + clusterName);
+ }
+
+ hostName = serviceComponent.getServiceComponentHosts().keySet()
+ .iterator().next();
+ }
+
+
+ addServiceCheckActionImpl(stage, hostName, smokeTestRole, nowTimestamp,
+ serviceName, componentName, roleParameters, hostsMap,
+ hostLevelParams);
+ }
+
+
+
+ /**
+ * Creates and populates service check EXECUTION_COMMAND for host.
+ * Not all EXECUTION_COMMAND parameters are populated here because they
+ * are not needed by service check.
+ */
+ @Override
+ public void addServiceCheckActionImpl(Stage stage,
+ String hostname, String smokeTestRole,
+ long nowTimestamp,
+ String serviceName,
+ String componentName,
+ Map<String, String> roleParameters,
+ HostsMap hostsMap,
+ Map<String, String> hostLevelParams)
+ throws AmbariException{
+
+ String clusterName = stage.getClusterName();
+ Cluster cluster = clusters.getCluster(clusterName);
+ StackId stackId = cluster.getDesiredStackVersion();
+ AmbariMetaInfo ambariMetaInfo = amc.getAmbariMetaInfo();
+ ServiceInfo serviceInfo =
+ ambariMetaInfo.getServiceInfo(stackId.getStackName(),
+ stackId.getStackVersion(), serviceName);
+
+
+ stage.addHostRoleExecutionCommand(hostname,
+ Role.valueOf(smokeTestRole),
+ RoleCommand.SERVICE_CHECK,
+ new ServiceComponentHostOpInProgressEvent(componentName, hostname,
+ nowTimestamp), cluster.getClusterName(), serviceName);
+
+ // [ type -> [ key, value ] ]
+ Map<String, Map<String, String>> configurations =
+ new TreeMap<String, Map<String, String>>();
+ Map<String, Map<String, String>> configTags =
+ amc.findConfigurationTagsWithOverrides(cluster, hostname);
+
+ ExecutionCommand execCmd = stage.getExecutionCommandWrapper(hostname,
+ smokeTestRole).getExecutionCommand();
+
+ execCmd.setConfigurations(configurations);
+ execCmd.setConfigurationTags(configTags);
+
+ // Generate cluster host info
+ execCmd.setClusterHostInfo(
+ StageUtils.getClusterHostInfo(clusters.getHostsForCluster(clusterName), cluster, hostsMap, configs));
+
+ if (hostLevelParams == null) {
+ hostLevelParams = new TreeMap<String, String>();
+ }
+ hostLevelParams.put(JDK_LOCATION, amc.getJdkResourceUrl());
+ hostLevelParams.put(STACK_NAME, stackId.getStackName());
+ hostLevelParams.put(STACK_VERSION,stackId.getStackVersion());
+ execCmd.setHostLevelParams(hostLevelParams);
+
+ Map<String,String> commandParams = new TreeMap<String, String>();
+ commandParams.put(SCHEMA_VERSION, serviceInfo.getSchemaVersion());
+
+ String commandTimeout = COMMAND_TIMEOUT_DEFAULT;
+
+
+ if (serviceInfo.getSchemaVersion().equals(AmbariMetaInfo.SCHEMA_VERSION_2)) {
+ // Service check command is not custom command
+ CommandScriptDefinition script = serviceInfo.getCommandScript();
+ if (script != null) {
+ commandParams.put(SCRIPT, script.getScript());
+ commandParams.put(SCRIPT_TYPE, script.getScriptType().toString());
+ commandTimeout = String.valueOf(script.getTimeout());
+ } else {
+ String message = String.format("Service %s has not command script " +
+ "defined. It is not possible to run service check" +
+ " for this service", serviceName);
+ throw new AmbariException(message);
+ }
+ // We don't need package/repo infomation to perform service check
+ }
+ commandParams.put(COMMAND_TIMEOUT, commandTimeout);
+
+ commandParams.put(SERVICE_METADATA_FOLDER,
+ serviceInfo.getServiceMetadataFolder());
+
+ execCmd.setCommandParams(commandParams);
+
+ if (roleParameters != null) { // If defined
+ execCmd.setRoleParams(roleParameters);
+ }
+
+ }
+
+ private void addDecommissionDatanodeAction(ExecuteActionRequest decommissionRequest, Stage stage,
+ Map<String, String> hostLevelParams)
+ throws AmbariException {
+ String hdfsExcludeFileType = "hdfs-exclude-file";
+ // Find hdfs admin host, just decommission from namenode.
+ String clusterName = decommissionRequest.getClusterName();
+ Cluster cluster = clusters.getCluster(clusterName);
+ String serviceName = decommissionRequest.getServiceName();
+ String namenodeHost = clusters.getCluster(clusterName)
+ .getService(serviceName).getServiceComponent(Role.NAMENODE.toString())
+ .getServiceComponentHosts().keySet().iterator().next();
+
+ String excludeFileTag = null;
+ if (decommissionRequest.getParameters() != null
+ && (decommissionRequest.getParameters().get("excludeFileTag") != null)) {
+ excludeFileTag = decommissionRequest.getParameters()
+ .get("excludeFileTag");
+ }
+
+ if (excludeFileTag == null) {
+ throw new AmbariException("No exclude file specified"
+ + " when decommissioning datanodes. Provide parameter excludeFileTag with the tag for config type "
+ + hdfsExcludeFileType);
+ }
+
+ Config config = clusters.getCluster(clusterName).getConfig(
+ hdfsExcludeFileType, excludeFileTag);
+ if (config == null) {
+ throw new AmbariException("Decommissioning datanodes requires the cluster to be associated with config type " +
+ hdfsExcludeFileType + " with a list of datanodes to be decommissioned (\"datanodes\" : list).");
+ }
+
+ LOG.info("Decommissioning data nodes: " + config.getProperties().get("datanodes") +
+ " " + hdfsExcludeFileType + " tag: " + excludeFileTag);
+
+ Map<String, Map<String, String>> configurations =
+ new TreeMap<String, Map<String, String>>();
+
+
+ Map<String, Map<String, String>> configTags = amc.findConfigurationTagsWithOverrides(cluster, namenodeHost);
+
+ // Add the tag for hdfs-exclude-file
+ Map<String, String> excludeTags = new HashMap<String, String>();
+ excludeTags.put(ConfigHelper.CLUSTER_DEFAULT_TAG, config.getVersionTag());
+ configTags.put(hdfsExcludeFileType, excludeTags);
+
+ stage.addHostRoleExecutionCommand(
+ namenodeHost,
+ Role.DECOMMISSION_DATANODE,
+ RoleCommand.EXECUTE,
+ new ServiceComponentHostOpInProgressEvent(Role.DECOMMISSION_DATANODE
+ .toString(), namenodeHost, System.currentTimeMillis()),
+ clusterName, serviceName);
+
+ ExecutionCommand execCmd = stage.getExecutionCommandWrapper(namenodeHost,
+ Role.DECOMMISSION_DATANODE.toString()).getExecutionCommand();
+
+ execCmd.setConfigurations(configurations);
+ execCmd.setConfigurationTags(configTags);
+ /*
+ TODO: When migrating to custom services, datanode decommision
+ probably will be implemented as a custom action; that's why
+ we have no schema version 2 command parameters here
+ */
+ execCmd.setHostLevelParams(hostLevelParams);
+ }
+
+
+ /**
+ * Creates and populates an EXECUTION_COMMAND for host
+ */
+ @Override
+ public void createHostAction(Cluster cluster,
+ Stage stage, ServiceComponentHost scHost,
+ Map<String, Map<String, String>> configurations,
+ Map<String, Map<String, String>> configTags,
+ RoleCommand roleCommand,
+ Map<String, String> commandParams,
+ ServiceComponentHostEvent event)
+ throws AmbariException {
+
+ stage.addHostRoleExecutionCommand(scHost.getHostName(), Role.valueOf(scHost
+ .getServiceComponentName()), roleCommand,
+ event, scHost.getClusterName(),
+ scHost.getServiceName());
+ String serviceName = scHost.getServiceName();
+ String componentName = event.getServiceComponentName();
+ String hostname = scHost.getHostName();
+ String osType = clusters.getHost(hostname).getOsType();
+ StackId stackId = cluster.getDesiredStackVersion();
+ ServiceInfo serviceInfo = ambariMetaInfo.getServiceInfo(stackId.getStackName(),
+ stackId.getStackVersion(), serviceName);
+ ComponentInfo componentInfo = ambariMetaInfo.getComponent(
+ stackId.getStackName(), stackId.getStackVersion(),
+ serviceName, componentName);
+
+ ExecutionCommand execCmd = stage.getExecutionCommandWrapper(scHost.getHostName(),
+ scHost.getServiceComponentName()).getExecutionCommand();
+
+ Host host = clusters.getHost(scHost.getHostName());
+
+ // Hack - Remove passwords from configs
+ if (event.getServiceComponentName().equals(Role.HIVE_CLIENT.toString())) {
+ configHelper.applyCustomConfig(configurations, Configuration.HIVE_CONFIG_TAG,
+ Configuration.HIVE_METASTORE_PASSWORD_PROPERTY, "", true);
+ }
+
+ execCmd.setConfigurations(configurations);
+ execCmd.setConfigurationTags(configTags);
+ if (commandParams == null) { // if not defined
+ commandParams = new TreeMap<String, String>();
+ }
+ commandParams.put(SCHEMA_VERSION, serviceInfo.getSchemaVersion());
+
+
+ // Get command script info for custom command/custom action
+ /*
+ * TODO: Custom actions are not supported yet, that's why we just pass
+ * component main commandScript to agent. This script is only used for
+ * default commads like INSTALL/STOP/START/CONFIGURE
+ */
+ String commandTimeout = ExecutionCommand.KeyNames.COMMAND_TIMEOUT_DEFAULT;
+ CommandScriptDefinition script = componentInfo.getCommandScript();
+ if (serviceInfo.getSchemaVersion().equals(AmbariMetaInfo.SCHEMA_VERSION_2)) {
+ if (script != null) {
+ commandParams.put(SCRIPT, script.getScript());
+ commandParams.put(SCRIPT_TYPE, script.getScriptType().toString());
+ commandTimeout = String.valueOf(script.getTimeout());
+ } else {
+ String message = String.format("Component %s of service %s has not " +
+ "command script defined", componentName, serviceName);
+ throw new AmbariException(message);
+ }
+ }
+ commandParams.put(COMMAND_TIMEOUT, commandTimeout);
+ commandParams.put(SERVICE_METADATA_FOLDER,
+ serviceInfo.getServiceMetadataFolder());
+
+ execCmd.setCommandParams(commandParams);
+
+ Map<String, List<RepositoryInfo>> repos = ambariMetaInfo.getRepository(
+ stackId.getStackName(), stackId.getStackVersion());
+ String repoInfo = "";
+ if (!repos.containsKey(host.getOsType())) {
+ // FIXME should this be an error?
+ LOG.warn("Could not retrieve repo information for host"
+ + ", hostname=" + scHost.getHostName()
+ + ", clusterName=" + cluster.getClusterName()
+ + ", stackInfo=" + stackId.getStackId());
+ } else {
+ repoInfo = gson.toJson(repos.get(host.getOsType()));
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Sending repo information to agent"
+ + ", hostname=" + scHost.getHostName()
+ + ", clusterName=" + cluster.getClusterName()
+ + ", stackInfo=" + stackId.getStackId()
+ + ", repoInfo=" + repoInfo);
+ }
+
+ Map<String, String> hostParams = new TreeMap<String, String>();
+ // TODO: Move parameter population to org.apache.ambari.server.controller.AmbariManagementControllerImpl.createAction()
+ hostParams.put(REPO_INFO, repoInfo);
+ hostParams.put(JDK_LOCATION, amc.getJdkResourceUrl());
+ hostParams.put(STACK_NAME, stackId.getStackName());
+ hostParams.put(STACK_VERSION, stackId.getStackVersion());
+ hostParams.put(DB_NAME, amc.getServerDB());
+ hostParams.put(MYSQL_JDBC_URL, amc.getMysqljdbcUrl());
+ hostParams.put(ORACLE_JDBC_URL, amc.getOjdbcUrl());
+
+ // Write down os specific info for the service
+ ServiceOsSpecific anyOs = null;
+ if (serviceInfo.getOsSpecifics().containsKey(AmbariMetaInfo.ANY_OS)) {
+ anyOs = serviceInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS);
+ }
+ ServiceOsSpecific hostOs = null;
+ if (serviceInfo.getOsSpecifics().containsKey(osType)) {
+ hostOs = serviceInfo.getOsSpecifics().get(osType);
+ // Choose repo that is relevant for host
+ ServiceOsSpecific.Repo serviceRepo= hostOs.getRepo();
+ if (serviceRepo != null) {
+ String serviceRepoInfo = gson.toJson(serviceInfo);
+ hostParams.put(SERVICE_REPO_INFO, serviceRepoInfo);
+ }
+ }
+ // Build package list that is relevant for host
+ List<ServiceOsSpecific.Package> packages =
+ new ArrayList<ServiceOsSpecific.Package>();
+ if (anyOs != null) {
+ packages.addAll(anyOs.getPackages());
+ }
+
+ if (hostOs != null) {
+ packages.addAll(hostOs.getPackages());
+ }
+ String packageList = gson.toJson(packages);
+ hostParams.put(PACKAGE_LIST, packageList);
+
+ if (configs.getServerDBName().equalsIgnoreCase(Configuration
+ .ORACLE_DB_NAME)) {
+ hostParams.put(DB_DRIVER_FILENAME, configs.getOjdbcJarName());
+ } else if (configs.getServerDBName().equalsIgnoreCase(Configuration
+ .MYSQL_DB_NAME)) {
+ hostParams.put(DB_DRIVER_FILENAME, configs.getMySQLJarName());
+ }
+ execCmd.setHostLevelParams(hostParams);
+
+ Map<String, String> roleParams = new TreeMap<String, String>();
+ execCmd.setRoleParams(roleParams);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 67b2475..1dd461e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -441,5 +441,46 @@ public interface AmbariManagementController {
Map<String, Map<State, List<ServiceComponentHost>>> changedHosts,
Collection<ServiceComponentHost> ignoredHosts,
boolean runSmokeTest, boolean reconfigureClients) throws AmbariException;
+
+
+ /**
+ * Getter for the url of JDK, stored at server resources folder
+ */
+ public String getJdkResourceUrl();
+
+ /**
+ * Getter for the name of server database
+ */
+ public String getServerDB();
+
+ /**
+ * Getter for the url of Oracle JDBC driver, stored at server resources folder
+ */
+ public String getOjdbcUrl();
+
+ /**
+ * Getter for the url of MySQL JDBC driver, stored at server resources folder
+ */
+ public String getMysqljdbcUrl();
+
+ /**
+ * Return a healthy host if found otherwise any random host
+ * @throws AmbariException
+ */
+ public String getHealthyHost(Set<String> hostList) throws AmbariException;
+
+
+ /**
+ * Find configuration tags with applied overrides
+ *
+ * @param cluster the cluster
+ * @param hostName the host name
+ *
+ * @return the configuration tags
+ *
+ * @throws AmbariException if configuration tags can not be obtained
+ */
+ public Map<String, Map<String,String>> findConfigurationTagsWithOverrides(
+ Cluster cluster, String hostName) throws AmbariException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 257c189..1a33f28 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -18,11 +18,21 @@
package org.apache.ambari.server.controller;
-import com.google.gson.Gson;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.DuplicateResourceException;
@@ -39,7 +49,6 @@ import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.actionmanager.HostRoleCommand;
import org.apache.ambari.server.actionmanager.Stage;
import org.apache.ambari.server.actionmanager.StageFactory;
-import org.apache.ambari.server.agent.ExecutionCommand;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.URLStreamProvider;
@@ -49,33 +58,11 @@ import org.apache.ambari.server.security.authorization.AuthorizationHelper;
import org.apache.ambari.server.security.authorization.User;
import org.apache.ambari.server.security.authorization.Users;
import org.apache.ambari.server.stageplanner.RoleGraph;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigFactory;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.HostState;
-import org.apache.ambari.server.state.OperatingSystemInfo;
-import org.apache.ambari.server.state.PropertyInfo;
-import org.apache.ambari.server.state.RepositoryInfo;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceComponentFactory;
-import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import org.apache.ambari.server.state.ServiceComponentHostFactory;
-import org.apache.ambari.server.state.ServiceFactory;
-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.State;
+import org.apache.ambari.server.state.*;
import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostMaintenanceEvent;
-import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostRestoreEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent;
@@ -86,20 +73,13 @@ import org.apache.commons.lang.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
@Singleton
public class AmbariManagementControllerImpl implements
@@ -166,7 +146,8 @@ public class AmbariManagementControllerImpl implements
final private String serverDB;
final private String mysqljdbcUrl;
- final private AmbariCustomCommandExecutionHelper customCommandExecutionHelper;
+ @Inject
+ private AmbariCustomCommandExecutionHelper customCommandExecutionHelper;
final private AmbariActionExecutionHelper actionExecutionHelper;
@Inject
@@ -204,8 +185,6 @@ public class AmbariManagementControllerImpl implements
this.serverDB = null;
}
- this.customCommandExecutionHelper = new AmbariCustomCommandExecutionHelper(
- this.actionMetadata, this.clusters, this);
this.actionExecutionHelper = new AmbariActionExecutionHelper(
this.actionMetadata, this.clusters, this);
}
@@ -548,76 +527,6 @@ public class AmbariManagementControllerImpl implements
return stageFactory.createNew(requestId, logDir, cluster.getClusterName(), requestContext, clusterHostInfo);
}
- private void createHostAction(Cluster cluster,
- Stage stage, ServiceComponentHost scHost,
- Map<String, Map<String, String>> configurations,
- Map<String, Map<String, String>> configTags,
- RoleCommand command,
- Map<String, String> commandParams,
- ServiceComponentHostEvent event) throws AmbariException {
-
- stage.addHostRoleExecutionCommand(scHost.getHostName(), Role.valueOf(scHost
- .getServiceComponentName()), command,
- event, scHost.getClusterName(),
- scHost.getServiceName());
- ExecutionCommand execCmd = stage.getExecutionCommandWrapper(scHost.getHostName(),
- scHost.getServiceComponentName()).getExecutionCommand();
-
- Host host = clusters.getHost(scHost.getHostName());
-
- // Hack - Remove passwords from configs
- if (event.getServiceComponentName().equals(Role.HIVE_CLIENT.toString())) {
- configHelper.applyCustomConfig(configurations, Configuration.HIVE_CONFIG_TAG,
- Configuration.HIVE_METASTORE_PASSWORD_PROPERTY, "", true);
- }
-
- execCmd.setConfigurations(configurations);
- execCmd.setConfigurationTags(configTags);
- execCmd.setCommandParams(commandParams);
-
- // send stack info to agent
- StackId stackId = scHost.getDesiredStackVersion();
- Map<String, List<RepositoryInfo>> repos = ambariMetaInfo.getRepository(
- stackId.getStackName(), stackId.getStackVersion());
- String repoInfo = "";
- if (!repos.containsKey(host.getOsType())) {
- // FIXME should this be an error?
- LOG.warn("Could not retrieve repo information for host"
- + ", hostname=" + scHost.getHostName()
- + ", clusterName=" + cluster.getClusterName()
- + ", stackInfo=" + stackId.getStackId());
- } else {
- repoInfo = gson.toJson(repos.get(host.getOsType()));
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Sending repo information to agent"
- + ", hostname=" + scHost.getHostName()
- + ", clusterName=" + cluster.getClusterName()
- + ", stackInfo=" + stackId.getStackId()
- + ", repoInfo=" + repoInfo);
- }
-
- Map<String, String> params = new TreeMap<String, String>();
- params.put("repo_info", repoInfo);
- params.put("jdk_location", jdkResourceUrl);
- params.put("stack_version", stackId.getStackVersion());
- params.put("db_name", serverDB);
- params.put("mysql_jdbc_url" , mysqljdbcUrl);
- params.put("oracle_jdbc_url", ojdbcUrl);
-
- if (configs.getServerDBName().equalsIgnoreCase(Configuration
- .ORACLE_DB_NAME)) {
- params.put("db_driver_filename", configs.getOjdbcJarName());
- } else if (configs.getServerDBName().equalsIgnoreCase(Configuration
- .MYSQL_DB_NAME)) {
- params.put("db_driver_filename", configs.getMySQLJarName());
- }
- execCmd.setHostLevelParams(params);
-
- Map<String, String> roleParams = new TreeMap<String, String>();
- execCmd.setRoleParams(roleParams);
- }
private synchronized Set<ClusterResponse> getClusters(ClusterRequest request)
throws AmbariException {
@@ -1090,18 +999,9 @@ public class AmbariManagementControllerImpl implements
}
}
- /**
- * Find configuration tags with applied overrides
- *
- * @param cluster the cluster
- * @param hostName the host name
- *
- * @return the configuration tags
- *
- * @throws AmbariException if configuration tags can not be obtained
- */
- protected Map<String, Map<String,String>> findConfigurationTagsWithOverrides(
- Cluster cluster, String hostName) throws AmbariException {
+ @Override
+ public Map<String, Map<String,String>> findConfigurationTagsWithOverrides(
+ Cluster cluster, String hostName) throws AmbariException {
return configHelper.getEffectiveDesiredTags(cluster, hostName);
}
@@ -1303,15 +1203,15 @@ public class AmbariManagementControllerImpl implements
}
}
- createHostAction(cluster, stage, scHost, configurations, configTags,
- roleCommand, requestParameters, event);
+ customCommandExecutionHelper.createHostAction(cluster, stage, scHost,
+ configurations, configTags,
+ roleCommand, requestParameters, event);
}
}
}
- for (String serviceName : smokeTestServices) {
+ for (String serviceName : smokeTestServices) { // Creates smoke test commands
Service s = cluster.getService(serviceName);
-
// find service component host
String clientHost = getClientHostForRunningAction(cluster, s);
String smokeTestRole =
@@ -1326,39 +1226,10 @@ public class AmbariManagementControllerImpl implements
+ ", serviceCheckRole=" + smokeTestRole);
continue;
}
-
- stage.addHostRoleExecutionCommand(clientHost,
- Role.valueOf(smokeTestRole),
- RoleCommand.EXECUTE,
- new ServiceComponentHostOpInProgressEvent(null, clientHost,
- nowTimestamp), cluster.getClusterName(), serviceName);
-
- // [ type -> [ key, value ] ]
- Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String,String>>();
- Map<String, Map<String, String>> configTags =
- findConfigurationTagsWithOverrides(cluster, clientHost);
-
- stage.getExecutionCommandWrapper(clientHost,
- smokeTestRole).getExecutionCommand()
- .setConfigurations(configurations);
-
- stage.getExecutionCommandWrapper(clientHost,
- smokeTestRole).getExecutionCommand()
- .setConfigurationTags(configTags);
-
- // Generate cluster host info
- stage.getExecutionCommandWrapper(clientHost, smokeTestRole)
- .getExecutionCommand()
- .setClusterHostInfo(StageUtils.getClusterHostInfo(
- clusters.getHostsForCluster(cluster.getClusterName()), cluster, hostsMap,
- injector.getInstance(Configuration.class)));
-
- Map<String,String> hostParams = new HashMap<String, String>();
- hostParams.put("stack_version", cluster.getDesiredStackVersion().getStackVersion());
- // smoke tests need stack version
- stage.getExecutionCommandWrapper(clientHost,
- smokeTestRole).getExecutionCommand()
- .setHostLevelParams(hostParams);
+ Configuration configuration = injector.getInstance(Configuration.class);
+ customCommandExecutionHelper.addServiceCheckActionImpl(stage, clientHost,
+ smokeTestRole, nowTimestamp, serviceName,
+ null, null, hostsMap, null);
}
@@ -2064,8 +1935,9 @@ public class AmbariManagementControllerImpl implements
return null;
}
- protected String getHealthyHost(Set<String> hostList) throws AmbariException {
- // Return a healthy host if found otherwise any random host
+
+ @Override
+ public String getHealthyHost(Set<String> hostList) throws AmbariException {
String hostName = null;
for (String candidateHostName : hostList) {
hostName = candidateHostName;
@@ -2081,7 +1953,6 @@ public class AmbariManagementControllerImpl implements
public RequestStatusResponse createAction(ExecuteActionRequest actionRequest, Map<String, String> requestProperties)
throws AmbariException {
String clusterName;
- Configuration configuration = injector.getInstance(Configuration.class);
String requestContext = "";
if (requestProperties != null) {
@@ -2109,7 +1980,7 @@ public class AmbariManagementControllerImpl implements
Map<String, List<String>> clusterHostInfo = StageUtils.getClusterHostInfo(
clusters.getHostsForCluster(cluster.getClusterName()), cluster, hostsMap,
- injector.getInstance(Configuration.class));
+ configs);
String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);
Stage stage = createNewStage(cluster, actionManager.getNextRequestId(), requestContext, clusterHostInfoJson);
@@ -2117,13 +1988,14 @@ public class AmbariManagementControllerImpl implements
stage.setStageId(0);
Map<String, String> params = new TreeMap<String, String>();
- params.put("jdk_location", this.jdkResourceUrl);
- params.put("stack_version", cluster.getDesiredStackVersion().getStackVersion());
+ // TODO : Update parameter population to be done only here
+ params.put(JDK_LOCATION, this.jdkResourceUrl);
+ params.put(STACK_VERSION, cluster.getDesiredStackVersion().getStackVersion());
if (actionRequest.isCommand()) {
- customCommandExecutionHelper.addAction(actionRequest, stage, configuration, hostsMap, params);
+ customCommandExecutionHelper.addAction(actionRequest, stage, hostsMap, params);
} else {
- actionExecutionHelper.addAction(actionExecContext, stage, configuration, hostsMap, params);
+ actionExecutionHelper.addAction(actionExecContext, stage, configs, hostsMap, params);
}
RoleCommandOrder rco = this.getRoleCommandOrder(cluster);
@@ -2645,4 +2517,24 @@ public class AmbariManagementControllerImpl implements
public ActionManager getActionManager() {
return actionManager;
}
+
+ @Override
+ public String getJdkResourceUrl() {
+ return jdkResourceUrl;
+ }
+
+ @Override
+ public String getServerDB() {
+ return serverDB;
+ }
+
+ @Override
+ public String getOjdbcUrl() {
+ return ojdbcUrl;
+ }
+
+ @Override
+ public String getMysqljdbcUrl() {
+ return mysqljdbcUrl;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc49fb9e/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
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 0859322..7d60bab 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
@@ -97,6 +97,7 @@ public class ControllerModule extends AbstractModule {
bind(Gson.class).in(Scopes.SINGLETON);
bind(Clusters.class).to(ClustersImpl.class);
+ bind(AmbariCustomCommandExecutionHelper.class).to(AmbariCustomCommandExecutionHelperImpl.class);
bind(ActionDBAccessor.class).to(ActionDBAccessorImpl.class);
bind(CustomActionDBAccessor.class).to(CustomActionDBAccessorImpl.class);
bindConstant().annotatedWith(Names.named("schedulerSleeptime")).to(10000L);