You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sm...@apache.org on 2014/01/22 20:26:23 UTC
[2/2] git commit: AMBARI-4365. Action definitions should be provided
as declarative resources - read from XML files
AMBARI-4365. Action definitions should be provided as declarative resources - read from XML files
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8e8a9a47
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8e8a9a47
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8e8a9a47
Branch: refs/heads/trunk
Commit: 8e8a9a47fd5d9afb0fcc4bd41b283c409d5bc355
Parents: 241f059
Author: Sumit Mohanty <sm...@hortonworks.com>
Authored: Wed Jan 22 09:42:45 2014 -0800
Committer: Sumit Mohanty <sm...@hortonworks.com>
Committed: Wed Jan 22 11:14:09 2014 -0800
----------------------------------------------------------------------
ambari-server/conf/unix/ambari.properties | 1 +
ambari-server/pom.xml | 8 +
.../server/actionmanager/ActionDefinition.java | 138 -----------
.../server/actionmanager/ActionManager.java | 35 +--
.../actionmanager/CustomActionDBAccessor.java | 82 -------
.../CustomActionDBAccessorImpl.java | 230 -------------------
.../server/api/services/AmbariMetaInfo.java | 78 +++++--
.../server/configuration/Configuration.java | 165 ++++++-------
.../server/controller/ActionResponse.java | 11 -
.../controller/AmbariActionExecutionHelper.java | 19 +-
.../server/controller/ControllerModule.java | 62 +++--
.../internal/ActionResourceProvider.java | 144 +-----------
.../server/customactions/ActionDefinition.java | 132 +++++++++++
.../customactions/ActionDefinitionManager.java | 202 ++++++++++++++++
.../customactions/ActionDefinitionSpec.java | 139 +++++++++++
.../customactions/ActionDefinitionXml.java | 42 ++++
.../server/orm/dao/ActionDefinitionDAO.java | 71 ------
.../server/orm/entities/ActionEntity.java | 162 -------------
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 1 -
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 1 -
.../resources/Ambari-DDL-Postgres-CREATE.sql | 7 -
.../system_action_definitions.xml | 32 +++
.../custom_actions/ambari_hdfs_rebalance.py | 58 -----
.../custom_actions/ambari_hdfs_rebalancer.py | 58 +++++
.../upgrade/ddl/Ambari-DDL-Oracle-UPGRADE.sql | 1 -
.../ddl/Ambari-DDL-Postgres-UPGRADE-1.3.0.sql | 5 -
.../actionmanager/TestActionDBAccessorImpl.java | 4 +-
.../server/actionmanager/TestActionManager.java | 6 +-
.../actionmanager/TestActionScheduler.java | 10 +-
.../TestCustomActionDBAccessorImpl.java | 124 ----------
.../server/agent/TestHeartbeatHandler.java | 5 +-
.../AmbariManagementControllerTest.java | 160 ++-----------
.../internal/ActionResourceProviderTest.java | 213 ++---------------
.../ActionDefinitionManagerTest.java | 73 ++++++
.../server/orm/dao/ActionDefinitionDAOTest.java | 137 -----------
.../cust_action_definitions1.xml | 55 +++++
.../cust_action_definitions2.txt | 18 ++
.../cust_action_definitions3.xml | 21 ++
.../system_action_definitions.xml | 32 +++
39 files changed, 1057 insertions(+), 1685 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index 978cdc6..74eed1b 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -18,6 +18,7 @@
security.server.keys_dir = /var/lib/ambari-server/keys
resources.dir = /var/lib/ambari-server/resources
+custom.action.definitions = /var/lib/ambari-server/resources/custom_action_definitions
jdk1.6.url=http://public-repo-1.hortonworks.com/ARTIFACTS/jdk-6u31-linux-x64.bin
jce_policy1.6.url=http://public-repo-1.hortonworks.com/ARTIFACTS/jce_policy-6.zip
jdk1.7.url=http://www.reucon.com/cdn/java/jdk-7u45-linux-x64.tar.gz
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index 2972e94..b494b7b 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -426,6 +426,14 @@
</source>
</sources>
</mapping>
+ <mapping>
+ <directory>/var/lib/ambari-server/resources/custom_action_definitions</directory>
+ <sources>
+ <source>
+ <location>src/main/resources/custom_action_definitions</location>
+ </source>
+ </sources>
+ </mapping>
</mappings>
</configuration>
</plugin>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDefinition.java
deleted file mode 100644
index fdd57dd..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDefinition.java
+++ /dev/null
@@ -1,138 +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 org.apache.ambari.server.orm.entities.ActionEntity;
-
-/**
- * The resource describing the definition of an action
- */
-public class ActionDefinition {
- private String actionName;
- private ActionType actionType;
- private String inputs;
- private String targetService;
- private String targetComponent;
- private String description;
- private TargetHostType targetType;
- private Short defaultTimeout;
-
- /**
- * Create an instance of ActionDefinition
- * @param actionName The name of the action
- * @param actionType The type fo the action
- * @param inputs Expected input of the action
- * @param targetService Target service type (e.g. HDFS)
- * @param targetComponent Target component type (e.g. DATANODE)
- * @param description Short description of the action
- * @param targetType Selection criteria for target hosts
- * @param defaultTimeout The timeout value for this action when executed
- */
- public ActionDefinition(String actionName, ActionType actionType, String inputs,
- String targetService, String targetComponent, String description,
- TargetHostType targetType, Short defaultTimeout) {
- setActionName(actionName);
- setActionType(actionType);
- setInputs(inputs);
- setTargetService(targetService);
- setTargetComponent(targetComponent);
- setDescription(description);
- setTargetType(targetType);
- setDefaultTimeout(defaultTimeout);
- }
-
- /**
- * Create an instance of ActionDefinition
- * @param entity The entity corresponding to the action
- */
- public ActionDefinition(ActionEntity entity) {
- setActionName(entity.getActionName());
- setActionType(entity.getActionType());
- setInputs(entity.getInputs());
- setTargetService(entity.getTargetService());
- setTargetComponent(entity.getTargetComponent());
- setDescription(entity.getDescription());
- setTargetType(entity.getTargetType());
- setDefaultTimeout(entity.getDefaultTimeout());
- }
-
- public String getActionName() {
- return actionName;
- }
-
- public void setActionName(String actionName) {
- this.actionName = actionName;
- }
-
- public ActionType getActionType() {
- return actionType;
- }
-
- public void setActionType(ActionType actionType) {
- this.actionType = actionType;
- }
-
- public String getInputs() {
- return inputs;
- }
-
- public void setInputs(String inputs) {
- this.inputs = inputs;
- }
-
- public String getTargetService() {
- return targetService;
- }
-
- public void setTargetService(String targetService) {
- this.targetService = targetService;
- }
-
- public String getTargetComponent() {
- return targetComponent;
- }
-
- public void setTargetComponent(String targetComponent) {
- this.targetComponent = targetComponent;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public TargetHostType getTargetType() {
- return targetType;
- }
-
- public void setTargetType(TargetHostType targetType) {
- this.targetType = targetType;
- }
-
- public Short getDefaultTimeout() {
- return defaultTimeout;
- }
-
- public void setDefaultTimeout(Short defaultTimeout) {
- this.defaultTimeout = defaultTimeout;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
index 8e6fb13..3788d75 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
@@ -50,7 +50,6 @@ public class ActionManager {
private final ActionDBAccessor db;
private final ActionQueue actionQueue;
private final AtomicLong requestCounter;
- private final CustomActionDBAccessor cdb;
private final RequestFactory requestFactory;
@@ -58,7 +57,7 @@ public class ActionManager {
public ActionManager(@Named("schedulerSleeptime") long schedulerSleepTime,
@Named("actionTimeout") long actionTimeout,
ActionQueue aq, Clusters fsm, ActionDBAccessor db, HostsMap hostsMap,
- ServerActionManager serverActionManager, UnitOfWork unitOfWork, CustomActionDBAccessor cdb,
+ ServerActionManager serverActionManager, UnitOfWork unitOfWork,
RequestFactory requestFactory, Configuration configuration) {
this.actionQueue = aq;
this.db = db;
@@ -66,7 +65,6 @@ public class ActionManager {
actionQueue, fsm, 2, hostsMap, serverActionManager, unitOfWork, configuration);
requestCounter = new AtomicLong(
db.getLastPersistedRequestIdWhenInitialized());
- this.cdb = cdb;
this.requestFactory = requestFactory;
}
@@ -207,35 +205,4 @@ public class ActionManager {
public String getRequestContext(long requestId) {
return db.getRequestContext(requestId);
}
-
- /** CRUD operations of Action resources **/
-
- public ActionDefinition getActionDefinition(String actionName)
- throws AmbariException {
- return cdb.getActionDefinition(actionName);
- }
-
- public List<ActionDefinition> getAllActionDefinition()
- throws AmbariException {
- return cdb.getActionDefinitions();
- }
-
- public void deleteActionDefinition(String actionName)
- throws AmbariException {
- cdb.deleteActionDefinition(actionName);
- }
-
- public void updateActionDefinition(String actionName, ActionType actionType, String description,
- TargetHostType targetType, Short defaultTimeout)
- throws AmbariException {
- cdb.updateActionDefinition(actionName, actionType, description, targetType, defaultTimeout);
- }
-
- public void createActionDefinition(String actionName, ActionType actionType, String inputs, String description,
- String serviceType, String componentType, TargetHostType targetType,
- Short defaultTimeout)
- throws AmbariException {
- cdb.createActionDefinition(actionName, actionType, inputs, description, targetType, serviceType,
- componentType, defaultTimeout);
- }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessor.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessor.java
deleted file mode 100644
index b861e76..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessor.java
+++ /dev/null
@@ -1,82 +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 org.apache.ambari.server.AmbariException;
-
-import java.util.List;
-
-/**
- * The DB accessor implementation for Action definitions
- */
-public interface CustomActionDBAccessor {
-
- /**
- * Given an actionName, get the Action resource
- *
- * @param actionName name of the action
- * @return
- * @throws AmbariException
- */
- public ActionDefinition getActionDefinition(String actionName) throws AmbariException;
-
- /**
- * Get all action definition resources
- *
- * @return
- */
- public List<ActionDefinition> getActionDefinitions();
-
- /**
- * Create an action definition resource
- *
- * @param actionName name of the action
- * @param actionType type of the action
- * @param inputs inputs required by the action
- * @param description a short description of the action
- * @param targetType the host target type
- * @param serviceType the service type on which the action must be executed
- * @param componentType the component type on which the action must be executed
- * @param defaultTimeout the default timeout for this action
- * @throws AmbariException
- */
- public void createActionDefinition(String actionName, ActionType actionType, String inputs, String description,
- TargetHostType targetType, String serviceType, String componentType,
- Short defaultTimeout) throws AmbariException;
-
- /**
- * Update an action definition
- *
- * @param actionName name of the action
- * @param actionType type of the action
- * @param description a short description of the action
- * @param targetType the host target type
- * @param defaultTimeout the default timeout for this action
- * @throws AmbariException
- */
- public void updateActionDefinition(String actionName, ActionType actionType, String description,
- TargetHostType targetType, Short defaultTimeout) throws AmbariException;
-
- /**
- * Delete an action definition
- *
- * @param actionName
- * @throws AmbariException
- */
- public void deleteActionDefinition(String actionName) throws AmbariException;
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessorImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessorImpl.java
deleted file mode 100644
index 38bc371..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/CustomActionDBAccessorImpl.java
+++ /dev/null
@@ -1,230 +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 com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.orm.dao.ActionDefinitionDAO;
-import org.apache.ambari.server.orm.entities.ActionEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An implementation of DB accessor for Custom Action
- */
-@Singleton
-public class CustomActionDBAccessorImpl implements CustomActionDBAccessor {
- public static final Short MIN_TIMEOUT = 60;
- private static final Logger LOG = LoggerFactory.getLogger(CustomActionDBAccessorImpl.class);
- private static final Short MAX_TIMEOUT = 600;
- @Inject
- private ActionDefinitionDAO actionDefinitionDAO;
-
- @Inject
- public CustomActionDBAccessorImpl(Injector injector) {
- injector.injectMembers(this);
- }
-
- /**
- * Given an actionName, get the Action resource
- *
- * @param actionName name of the action
- * @return
- * @throws AmbariException
- */
- @Override
- public ActionDefinition getActionDefinition(String actionName) {
- ActionEntity action =
- actionDefinitionDAO.findByPK(actionName);
- if (action != null) {
- return new ActionDefinition(action);
- }
-
- return null;
- }
-
- /**
- * Get all action definition resources
- *
- * @return
- */
- @Override
- public List<ActionDefinition> getActionDefinitions() {
- List<ActionDefinition> result = new ArrayList<ActionDefinition>();
- List<ActionEntity> entities = actionDefinitionDAO.findAll();
- for (ActionEntity entity : entities) {
- result.add(new ActionDefinition(entity));
- }
- return result;
- }
-
- /**
- * Create an action definition resource
- *
- * @param actionName name of the action
- * @param actionType type of the action
- * @param inputs inputs required by the action
- * @param description a short description of the action
- * @param targetType the host target type
- * @param serviceType the service type on which the action must be executed
- * @param componentType the component type on which the action must be executed
- * @param defaultTimeout the default timeout for this action
- * @throws AmbariException
- */
- @Override
- @Transactional
- public void createActionDefinition(String actionName, ActionType actionType, String inputs, String description,
- TargetHostType targetType, String serviceType, String componentType,
- Short defaultTimeout)
- throws AmbariException {
- validateCreateInput(actionName, actionType, inputs, description, defaultTimeout,
- targetType, serviceType, componentType);
- ActionEntity entity =
- actionDefinitionDAO.findByPK(actionName);
- if (entity == null) {
- entity = new ActionEntity();
- entity.setActionName(actionName);
- entity.setActionType(actionType);
- entity.setInputs(inputs);
- entity.setTargetService(serviceType);
- entity.setTargetComponent(componentType);
- entity.setDescription(description);
- entity.setTargetType(targetType);
- entity.setDefaultTimeout(defaultTimeout);
- actionDefinitionDAO.merge(entity);
- } else {
- throw new AmbariException("Action definition " + actionName + " already exists");
- }
- }
-
- /**
- * Update an action definition
- *
- * @param actionName name of the action
- * @param actionType type of the action
- * @param description a short description of the action
- * @param targetType the host target type
- * @param defaultTimeout the default timeout for this action
- * @throws AmbariException
- */
- @Override
- @Transactional
- public void updateActionDefinition(String actionName, ActionType actionType, String description,
- TargetHostType targetType, Short defaultTimeout)
- throws AmbariException {
- ActionEntity entity = actionDefinitionDAO.findByPK(actionName);
- if (entity != null) {
- if (actionType != null) {
- if (actionType == ActionType.SYSTEM_DISABLED) {
- throw new AmbariException("Action type cannot be " + actionType);
- }
- entity.setActionType(actionType);
- }
- if (description != null) {
- if (description.isEmpty()) {
- throw new AmbariException("Action description cannot be empty");
- }
- entity.setDescription(description);
- }
- if (targetType != null) {
- entity.setTargetType(targetType);
- }
- if (defaultTimeout != null) {
- if (defaultTimeout < MIN_TIMEOUT || defaultTimeout > MAX_TIMEOUT) {
- throw new AmbariException("Default timeout should be between " + MIN_TIMEOUT + " and " + MAX_TIMEOUT);
- }
- entity.setDefaultTimeout(defaultTimeout);
- }
- actionDefinitionDAO.merge(entity);
- } else {
- throw new AmbariException("Action definition " + actionName + " does not exist");
- }
- }
-
- /**
- * Delete an action definition
- *
- * @param actionName
- * @throws AmbariException
- */
- @Override
- public void deleteActionDefinition(String actionName)
- throws AmbariException {
- validateActionName(actionName);
- ActionDefinition ad = getActionDefinition(actionName);
- if (ad != null) {
- actionDefinitionDAO.removeByPK(actionName);
- }
- }
-
- private void validateCreateInput(String actionName, ActionType actionType, String inputs,
- String description, Short defaultTimeout,
- TargetHostType targetType, String serviceType, String componentType)
- throws AmbariException {
-
- validateActionName(actionName);
-
- if (defaultTimeout < MIN_TIMEOUT || defaultTimeout > MAX_TIMEOUT) {
- throw new AmbariException("Default timeout should be between " + MIN_TIMEOUT + " and " + MAX_TIMEOUT);
- }
-
- if (actionType == ActionType.SYSTEM_DISABLED) {
- throw new AmbariException("Action type cannot be " + actionType);
- }
-
- if (description == null || description.isEmpty()) {
- throw new AmbariException("Action description cannot be empty");
- }
-
- if (actionType == null || actionType == ActionType.SYSTEM_DISABLED) {
- throw new AmbariException("Action type cannot be " + actionType);
- }
-
- if (serviceType == null || serviceType.isEmpty()) {
- if (componentType != null && !componentType.isEmpty()) {
- throw new AmbariException("Target component cannot be specified unless target service is specified");
- }
- }
-
- if (inputs != null && !inputs.isEmpty()) {
- String[] parameters = inputs.split(",");
- for (String parameter : parameters) {
- if (parameter.trim().isEmpty()) {
- throw new AmbariException("Empty parameter cannot be specified as an input parameter");
- }
- }
- }
- }
-
- private void validateActionName(String actionName)
- throws AmbariException {
- if (actionName == null || actionName.isEmpty()) {
- throw new AmbariException("Action name cannot be empty");
- }
- String trimmedName = actionName.replaceAll("\\s+", "");
- if (actionName.length() > trimmedName.length()) {
- throw new AmbariException("Action name cannot contain white spaces");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/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 56bd5e9..78131f2 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
@@ -39,6 +39,8 @@ import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.StackAccessException;
import org.apache.ambari.server.api.util.StackExtensionHelper;
import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.customactions.ActionDefinition;
+import org.apache.ambari.server.customactions.ActionDefinitionManager;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.entities.MetainfoEntity;
import org.apache.ambari.server.state.ComponentInfo;
@@ -67,57 +69,52 @@ import com.google.inject.Singleton;
@Singleton
public class AmbariMetaInfo {
- private final static Logger LOG = LoggerFactory.getLogger(AmbariMetaInfo.class);
-
public static final String STACK_METAINFO_FILE_NAME = "metainfo.xml";
public static final String SERVICES_FOLDER_NAME = "services";
public static final String SERVICE_METAINFO_FILE_NAME = "metainfo.xml";
public static final String SERVICE_CONFIG_FOLDER_NAME = "configuration";
public static final String SERVICE_CONFIG_FILE_NAME_POSTFIX = ".xml";
public static final String RCO_FILE_NAME = "role_command_order.json";
- private static final String REPOSITORY_FILE_NAME = "repoinfo.xml";
- private static final String REPOSITORY_FOLDER_NAME = "repos";
- private static final String REPOSITORY_XML_PROPERTY_BASEURL = "baseurl";
- // all the supported OS'es
- private static final List<String> ALL_SUPPORTED_OS = Arrays.asList(
- "centos5", "redhat5", "centos6", "redhat6", "oraclelinux5",
- "oraclelinux6", "suse11", "sles11", "ubuntu12");
-
public static final String SERVICE_METRIC_FILE_NAME = "metrics.json";
- private final static String HOOKS_DIR = "hooks";
-
/**
* 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.equals(HOOKS_DIR)) // Hooks dir is not a service
+ s.equals(HOOKS_DIR)) // Hooks dir is not a service
+ {
return false;
+ }
return true;
}
};
-
+ private final static Logger LOG = LoggerFactory.getLogger(AmbariMetaInfo.class);
+ private static final String REPOSITORY_FILE_NAME = "repoinfo.xml";
+ private static final String REPOSITORY_FOLDER_NAME = "repos";
+ private static final String REPOSITORY_XML_PROPERTY_BASEURL = "baseurl";
+ // all the supported OS'es
+ private static final List<String> ALL_SUPPORTED_OS = Arrays.asList(
+ "centos5", "redhat5", "centos6", "redhat6", "oraclelinux5",
+ "oraclelinux6", "suse11", "sles11", "ubuntu12");
+ private final static String HOOKS_DIR = "hooks";
+ private final ActionDefinitionManager adManager = new ActionDefinitionManager();
private String serverVersion = "undefined";
private List<StackInfo> stacksResult = new ArrayList<StackInfo>();
private File stackRoot;
private File serverVersionFile;
-
+ private File customActionRoot;
@Inject
private MetainfoDAO metainfoDAO;
@@ -133,6 +130,7 @@ public class AmbariMetaInfo {
String serverVersionFilePath = conf.getServerVersionFilePath();
this.stackRoot = new File(stackPath);
this.serverVersionFile = new File(serverVersionFilePath);
+ this.customActionRoot = new File(conf.getCustomActionDefinitionPath());
}
public AmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception {
@@ -150,6 +148,7 @@ public class AmbariMetaInfo {
stacksResult = new ArrayList<StackInfo>();
readServerVersion();
getConfigurationInformation(stackRoot);
+ getCustomActionDefinitions(customActionRoot);
}
/**
@@ -464,11 +463,11 @@ public class AmbariMetaInfo {
}
public List<ServiceInfo> getSupportedServices(String stackName, String version) throws AmbariException {
- List<ServiceInfo> servicesResulr = null;
+ List<ServiceInfo> servicesResult = null;
StackInfo stack = getStackInfo(stackName, version);
if (stack != null)
- servicesResulr = stack.getServices();
- return servicesResulr;
+ servicesResult = stack.getServices();
+ return servicesResult;
}
public List<StackInfo> getSupportedStacks() {
@@ -622,6 +621,41 @@ public class AmbariMetaInfo {
serverVersion = new Scanner(versionFile).useDelimiter("\\Z").next();
}
+ private void getCustomActionDefinitions(File customActionDefinitionRoot) throws JAXBException, AmbariException {
+ if (customActionDefinitionRoot != null) {
+ LOG.debug("Loading custom action definitions from "
+ + customActionDefinitionRoot.getAbsolutePath());
+
+ if (customActionDefinitionRoot.exists() && customActionDefinitionRoot.isDirectory()) {
+ adManager.readCustomActionDefinitions(customActionDefinitionRoot);
+ } else {
+ LOG.debug("No action definitions found at " + customActionDefinitionRoot.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Get all action definitions
+ */
+ public List<ActionDefinition> getAllActionDefinition(){
+ return adManager.getAllActionDefinition();
+ }
+
+ /**
+ * Get action definitions based on the supplied name
+ */
+ public ActionDefinition getActionDefinition(String name){
+ return adManager.getActionDefinition(name);
+ }
+
+
+ /**
+ * Used for test purposes
+ */
+ public void addActionDefinition(ActionDefinition ad) throws AmbariException {
+ adManager.addActionDefinition(ad);
+ }
+
private void getConfigurationInformation(File stackRoot) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug("Loading stack information"
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/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 7c8bbdf..b070d98 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
@@ -52,7 +52,7 @@ public class Configuration {
public static final String BOOTSTRAP_DIR_DEFAULT = "/var/run/ambari-server/bootstrap";
public static final String WEBAPP_DIR = "webapp.dir";
public static final String BOOTSTRAP_SCRIPT = "bootstrap.script";
- public static final String BOOTSTRAP_SCRIPT_DEFAULT = "/usr/bin/ambari_bootstrap";
+ public static final String BOOTSTRAP_SCRIPT_DEFAULT = "/usr/bin/ambari_bootstrap";
public static final String BOOTSTRAP_SETUP_AGENT_SCRIPT = "bootstrap.setup_agent.script";
public static final String BOOTSTRAP_SETUP_AGENT_PASSWORD = "bootstrap.setup_agent.password";
public static final String BOOTSTRAP_MASTER_HOSTNAME = "bootstrap.master_host_name";
@@ -81,7 +81,6 @@ public class Configuration {
public static final String JAVA_HOME_KEY = "java.home";
public static final String JDK_NAME_KEY = "jdk.name";
public static final String JCE_NAME_KEY = "jce.name";
-
public static final String CLIENT_SECURITY_KEY = "client.security";
public static final String CLIENT_API_PORT_KEY = "client.api.port";
public static final String CLIENT_API_SSL_PORT_KEY = "client.api.ssl.port";
@@ -96,7 +95,6 @@ public class Configuration {
public static final String POSTGRES_DB_NAME = "postgres";
public static final String ORACLE_DB_NAME = "oracle";
public static final String MYSQL_DB_NAME = "mysql";
-
public static final String OJDBC_JAR_NAME_KEY = "db.oracle.jdbc.name";
public static final String OJDBC_JAR_NAME_DEFAULT = "ojdbc6.jar";
public static final String MYSQL_JAR_NAME_KEY = "db.mysql.jdbc.name";
@@ -128,99 +126,119 @@ public class Configuration {
"authorization.ldap.adminGroupMappingRules";
public static final String LDAP_GROUP_SEARCH_FILTER_KEY =
"authorization.ldap.groupSearchFilter";
-
public static final String USER_ROLE_NAME_KEY =
"authorization.userRoleName";
public static final String ADMIN_ROLE_NAME_KEY =
"authorization.adminRoleName";
-
public static final String SERVER_EC_CACHE_SIZE = "server.ecCacheSize";
- private static final long SERVER_EC_CACHE_SIZE_DEFAULT = 10000L;
-
public static final String SERVER_PERSISTENCE_TYPE_KEY = "server.persistence.type";
public static final String SERVER_JDBC_USER_NAME_KEY = "server.jdbc.user.name";
public static final String SERVER_JDBC_USER_PASSWD_KEY = "server.jdbc.user.passwd";
public static final String SERVER_JDBC_DRIVER_KEY = "server.jdbc.driver";
public static final String SERVER_JDBC_URL_KEY = "server.jdbc.url";
public static final String SERVER_JDBC_PROPERTIES_PREFIX = "server.jdbc.properties.";
-
-// public static final String SERVER_RCA_PERSISTENCE_TYPE_KEY = "server.rca.persistence.type";
+ // public static final String SERVER_RCA_PERSISTENCE_TYPE_KEY = "server.rca.persistence.type";
public static final String SERVER_JDBC_RCA_USER_NAME_KEY = "server.jdbc.rca.user.name";
public static final String SERVER_JDBC_RCA_USER_PASSWD_KEY = "server.jdbc.rca.user.passwd";
public static final String SERVER_JDBC_RCA_DRIVER_KEY = "server.jdbc.rca.driver";
public static final String SERVER_JDBC_RCA_URL_KEY = "server.jdbc.rca.url";
-
public static final String SERVER_JDBC_GENERATE_TABLES_KEY = "server.jdbc.generateTables";
-
public static final String JDBC_UNIT_NAME = "ambari-server";
-
public static final String JDBC_LOCAL_URL = "jdbc:postgresql://localhost/";
public static final String JDBC_LOCAL_DRIVER = "org.postgresql.Driver";
-
public static final String JDBC_IN_MEMORY_URL = "jdbc:derby:memory:myDB/ambari;create=true";
public static final String JDBC_IN_MEMROY_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
-
public static final String HOSTNAME_MACRO = "{hostname}";
public static final String JDBC_RCA_LOCAL_URL = "jdbc:postgresql://" + HOSTNAME_MACRO + "/ambarirca";
public static final String JDBC_RCA_LOCAL_DRIVER = "org.postgresql.Driver";
-
- private static final String SERVER_JDBC_USER_NAME_DEFAULT = "ambari-server";
- private static final String SERVER_JDBC_USER_PASSWD_DEFAULT = "bigdata";
-
- private static final String SERVER_JDBC_RCA_USER_NAME_DEFAULT = "mapred";
- private static final String SERVER_JDBC_RCA_USER_PASSWD_DEFAULT = "mapred";
-
public static final String OS_VERSION_KEY =
"server.os_type";
-
public static final String SRVR_HOSTS_MAPPING =
"server.hosts.mapping";
-
// Command parameter names
public static final String UPGRADE_FROM_STACK = "source_stack_version";
public static final String UPGRADE_TO_STACK = "target_stack_version";
-
public static final String SSL_TRUSTSTORE_PATH_KEY = "ssl.trustStore.path";
public static final String SSL_TRUSTSTORE_PASSWORD_KEY = "ssl.trustStore.password";
public static final String SSL_TRUSTSTORE_TYPE_KEY = "ssl.trustStore.type";
public static final String JAVAX_SSL_TRUSTSTORE = "javax.net.ssl.trustStore";
public static final String JAVAX_SSL_TRUSTSTORE_PASSWORD = "javax.net.ssl.trustStorePassword";
public static final String JAVAX_SSL_TRUSTSTORE_TYPE = "javax.net.ssl.trustStoreType";
-
public static final String GANGLIA_HTTPS_KEY = "ganglia.https";
- public static final String NAGIOS_HTTPS_KEY = "nagios.https";
-
- private static final String SRVR_TWO_WAY_SSL_DEFAULT = "false";
+ public static final String NAGIOS_HTTPS_KEY = "nagios.https";
public static final String SRVR_TWO_WAY_SSL_PORT_DEFAULT = "8441";
public static final String SRVR_ONE_WAY_SSL_PORT_DEFAULT = "8440";
- private static final String SRVR_KSTR_DIR_DEFAULT = ".";
public static final String SRVR_CRT_NAME_DEFAULT = "ca.crt";
public static final String SRVR_KEY_NAME_DEFAULT = "ca.key";
public static final String KSTR_NAME_DEFAULT = "keystore.p12";
-
public static final String CLIENT_API_SSL_KSTR_NAME_DEFAULT = "https.keystore.p12";
public static final String CLIENT_API_SSL_CRT_PASS_FILE_NAME_DEFAULT = "https.pass.txt";
public static final String CLIENT_API_SSL_KEY_NAME_DEFAULT = "https.key";
public static final String CLIENT_API_SSL_CRT_NAME_DEFAULT = "https.crt";
+ public static final String GLOBAL_CONFIG_TAG = "global";
+ public static final String RCA_ENABLED_PROPERTY = "rca_enabled";
+ public static final String HIVE_CONFIG_TAG = "hive-site";
+ public static final String HIVE_METASTORE_PASSWORD_PROPERTY =
+ "javax.jdo.option.ConnectionPassword";
+ public static final String MASTER_KEY_PERSISTED = "security.master" +
+ ".key.ispersisted";
+ public static final String MASTER_KEY_LOCATION = "security.master.key" +
+ ".location";
+ public static final String MASTER_KEY_ENV_PROP =
+ "AMBARI_SECURITY_MASTER_KEY";
+ public static final String MASTER_KEY_FILENAME_DEFAULT = "master";
+ /**
+ * Key for repo validation suffixes.
+ */
+ public static final String REPO_SUFFIX_KEY = "repo.validation.suffixes";
+ public static final String EXECUTION_SCHEDULER_CLUSTERED =
+ "server.execution.scheduler.isClustered";
+ public static final String EXECUTION_SCHEDULER_THREADS =
+ "server.execution.scheduler.maxThreads";
+ public static final String EXECUTION_SCHEDULER_CONNECTIONS =
+ "server.execution.scheduler.maxDbConnections";
+ public static final String EXECUTION_SCHEDULER_MISFIRE_TOLERATION =
+ "server.execution.scheduler.misfire.toleration.minutes";
+ public static final String EXECUTION_SCHEDULER_START_DELAY =
+ "server.execution.scheduler.start.delay.seconds";
+ public static final String DEFAULT_SCHEDULER_THREAD_COUNT = "5";
+ public static final String DEFAULT_SCHEDULER_MAX_CONNECTIONS = "5";
+ public static final String DEFAULT_EXECUTION_SCHEDULER_MISFIRE_TOLERATION = "480";
+ public static final String DEFAULT_SCHEDULER_START_DELAY_SECONDS = "120";
+ /**
+ * This key defines whether stages of parallel requests are executed in
+ * parallel or sequentally. Only stages from different requests
+ * running on not interfering host sets may be executed in parallel.
+ */
+ public static final String PARALLEL_STAGE_EXECUTION_KEY =
+ "server.stages.parallel";
+ public static final String AGENT_TASK_TIMEOUT_KEY = "agent.task.timeout";
+ public static final String AGENT_TASK_TIMEOUT_DEFAULT = "600";
- private static final String API_CSRF_PREVENTION_DEFAULT = "true";
+ public static final String CUSTOM_ACTION_DEFINITION_KEY = "custom.action.definitions";
+ private static final String CUSTOM_ACTION_DEFINITION_DEF_VALUE =
+ "/var/lib/ambari-server/resources/custom_action_definitions";
- private static final String SRVR_CRT_PASS_FILE_DEFAULT ="pass.txt";
+ private static final long SERVER_EC_CACHE_SIZE_DEFAULT = 10000L;
+ private static final String SERVER_JDBC_USER_NAME_DEFAULT = "ambari-server";
+ private static final String SERVER_JDBC_USER_PASSWD_DEFAULT = "bigdata";
+ private static final String SERVER_JDBC_RCA_USER_NAME_DEFAULT = "mapred";
+ private static final String SERVER_JDBC_RCA_USER_PASSWD_DEFAULT = "mapred";
+ private static final String SRVR_TWO_WAY_SSL_DEFAULT = "false";
+ private static final String SRVR_KSTR_DIR_DEFAULT = ".";
+ private static final String API_CSRF_PREVENTION_DEFAULT = "true";
+ private static final String SRVR_CRT_PASS_FILE_DEFAULT = "pass.txt";
private static final String SRVR_CRT_PASS_LEN_DEFAULT = "50";
private static final String PASSPHRASE_ENV_DEFAULT = "AMBARI_PASSPHRASE";
private static final String RESOURCES_DIR_DEFAULT =
"/var/share/ambari/resources/";
-
- private static final String ANONYMOUS_AUDIT_NAME_KEY = "anonymous.audit.name";
-
+ private static final String ANONYMOUS_AUDIT_NAME_KEY = "anonymous.audit.name";
private static final String CLIENT_SECURITY_DEFAULT = "local";
private static final int CLIENT_API_PORT_DEFAULT = 8080;
private static final int CLIENT_API_SSL_PORT_DEFAULT = 8443;
-
private static final String USER_ROLE_NAME_DEFAULT = "user";
private static final String ADMIN_ROLE_NAME_DEFAULT = "admin";
private static final String LDAP_BIND_ANONYMOUSLY_DEFAULT = "true";
-
//TODO For embedded server only - should be removed later
private static final String LDAP_PRIMARY_URL_DEFAULT = "localhost:33389";
private static final String LDAP_BASE_DN_DEFAULT = "dc=ambari,dc=apache,dc=org";
@@ -233,75 +251,22 @@ public class Configuration {
private static final String LDAP_ADMIN_GROUP_MAPPING_RULES_DEFAULT =
"Ambari Administrators";
private static final String LDAP_GROUP_SEARCH_FILTER_DEFAULT = "";
-
//TODO for development purposes only, should be changed to 'false'
private static final String SERVER_PERSISTENCE_TYPE_DEFAULT = "local";
-
private static final String SERVER_CONNECTION_MAX_IDLE_TIME =
- "server.connection.max.idle.millis";
-
- public static final String GLOBAL_CONFIG_TAG = "global";
- public static final String RCA_ENABLED_PROPERTY = "rca_enabled";
- public static final String HIVE_CONFIG_TAG = "hive-site";
- public static final String HIVE_METASTORE_PASSWORD_PROPERTY =
- "javax.jdo.option.ConnectionPassword";
-
- public static final String MASTER_KEY_PERSISTED = "security.master" +
- ".key.ispersisted";
- public static final String MASTER_KEY_LOCATION = "security.master.key" +
- ".location";
- public static final String MASTER_KEY_ENV_PROP =
- "AMBARI_SECURITY_MASTER_KEY";
- public static final String MASTER_KEY_FILENAME_DEFAULT = "master";
-
- /**
- * Key for repo validation suffixes.
- */
- public static final String REPO_SUFFIX_KEY = "repo.validation.suffixes";
+ "server.connection.max.idle.millis";
/**
* Default for repo validation suffixes.
*/
private static final String REPO_SUFFIX_DEFAULT = "/repodata/repomd.xml";
-
- public static final String EXECUTION_SCHEDULER_CLUSTERED =
- "server.execution.scheduler.isClustered";
- public static final String EXECUTION_SCHEDULER_THREADS =
- "server.execution.scheduler.maxThreads";
- public static final String EXECUTION_SCHEDULER_CONNECTIONS =
- "server.execution.scheduler.maxDbConnections";
- public static final String EXECUTION_SCHEDULER_MISFIRE_TOLERATION =
- "server.execution.scheduler.misfire.toleration.minutes";
- public static final String EXECUTION_SCHEDULER_START_DELAY =
- "server.execution.scheduler.start.delay.seconds";
-
- public static final String DEFAULT_SCHEDULER_THREAD_COUNT = "5";
- public static final String DEFAULT_SCHEDULER_MAX_CONNECTIONS = "5";
- public static final String DEFAULT_EXECUTION_SCHEDULER_MISFIRE_TOLERATION = "480";
- public static final String DEFAULT_SCHEDULER_START_DELAY_SECONDS = "120";
-
-
- /**
- * This key defines whether stages of parallel requests are executed in
- * parallel or sequentally. Only stages from different requests
- * running on not interfering host sets may be executed in parallel.
- */
- public static final String PARALLEL_STAGE_EXECUTION_KEY =
- "server.stages.parallel";
private static final String PARALLEL_STAGE_EXECUTION_DEFAULT = "true";
-
- public static final String AGENT_TASK_TIMEOUT_KEY = "agent.task.timeout";
- public static final String AGENT_TASK_TIMEOUT_DEFAULT = "600";
-
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
-
private Properties properties;
-
private Map<String, String> configsMap;
-
private CredentialProvider credentialProvider = null;
private volatile boolean credentialProviderInitialized = false;
- private Map<String,String> customDbProperties = null;
+ private Map<String, String> customDbProperties = null;
public Configuration() {
this(readConfigFile());
@@ -929,18 +894,26 @@ public class Configuration {
return "true".equalsIgnoreCase(configsMap.get(PARALLEL_STAGE_EXECUTION_KEY));
}
+ public String getCustomActionDefinitionPath() {
+ String value = configsMap.get(CUSTOM_ACTION_DEFINITION_KEY);
+ if (value == null) {
+ value = CUSTOM_ACTION_DEFINITION_DEF_VALUE;
+ }
+ return value;
+ }
+
/**
* @return default task timeout in seconds (string representation). This value
- * is used at python (agent) code.
+ * is used at python (agent) code.
*/
public String getDefaultAgentTaskTimeout() {
- String value = properties.getProperty(AGENT_TASK_TIMEOUT_KEY, AGENT_TASK_TIMEOUT_DEFAULT);
+ String value = properties.getProperty(AGENT_TASK_TIMEOUT_KEY, AGENT_TASK_TIMEOUT_DEFAULT);
if (StringUtils.isNumeric(value)) {
return value;
} else {
LOG.warn(String.format("Value of %s (%s) should be a number, " +
- "falling back to default value (%s)",
- AGENT_TASK_TIMEOUT_KEY, value, AGENT_TASK_TIMEOUT_DEFAULT));
+ "falling back to default value (%s)",
+ AGENT_TASK_TIMEOUT_KEY, value, AGENT_TASK_TIMEOUT_DEFAULT));
return AGENT_TASK_TIMEOUT_DEFAULT;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java
index f85f640..e7edafb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java
@@ -18,8 +18,6 @@
package org.apache.ambari.server.controller;
-import org.apache.ambari.server.actionmanager.ActionDefinition;
-
/**
* Used to respond to GET requests for actions
*/
@@ -47,15 +45,6 @@ public class ActionResponse {
setDefaultTimeout(defaultTimeout);
}
- public ActionResponse(ActionDefinition ad) {
- this(ad.getActionName(), ad.getActionType().toString(), ad.getInputs(),
- null == ad.getTargetService() ? "" : ad.getTargetService().toString(),
- null == ad.getTargetComponent() ? "" : ad.getTargetComponent().toString(),
- ad.getDescription(),
- null == ad.getTargetType() ? "" : ad.getTargetType().toString(),
- ad.getDefaultTimeout().toString());
- }
-
public String getActionName() {
return actionName;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/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 d985d9f..70f9e58 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
@@ -22,13 +22,13 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
import org.apache.ambari.server.StackAccessException;
-import org.apache.ambari.server.actionmanager.ActionDefinition;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.actionmanager.Stage;
import org.apache.ambari.server.actionmanager.TargetHostType;
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.customactions.ActionDefinition;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
@@ -41,9 +41,15 @@ import org.apache.ambari.server.utils.StageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCHEMA_VERSION;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
/**
* Helper class containing logic to process custom action execution requests
@@ -51,14 +57,13 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
public class AmbariActionExecutionHelper {
private final static Logger LOG =
LoggerFactory.getLogger(AmbariActionExecutionHelper.class);
+ private static final String TYPE_PYTHON = "PYTHON";
private ActionMetadata actionMetadata;
private Clusters clusters;
private AmbariManagementControllerImpl amcImpl;
private ActionManager actionManager;
private AmbariMetaInfo ambariMetaInfo;
- private static final String TYPE_PYTHON = "PYTHON";
-
public AmbariActionExecutionHelper(ActionMetadata actionMetadata, Clusters clusters,
AmbariManagementControllerImpl amcImpl) {
this.amcImpl = amcImpl;
@@ -82,7 +87,7 @@ public class AmbariActionExecutionHelper {
throw new AmbariException("Action name must be specified");
}
- ActionDefinition actionDef = actionManager.getActionDefinition(actionRequest.getActionName());
+ ActionDefinition actionDef = ambariMetaInfo.getActionDefinition(actionRequest.getActionName());
if (actionDef == null) {
throw new AmbariException("Action " + actionRequest.getActionName() + " does not exist");
}
@@ -164,7 +169,7 @@ public class AmbariActionExecutionHelper {
}
}
- if (actionDef.getTargetType() == TargetHostType.SPECIFIC
+ if (TargetHostType.SPECIFIC.name().equals(actionDef.getTargetType())
|| (targetService.isEmpty() && targetService.isEmpty())) {
if (actionRequest.getHosts().size() == 0) {
throw new AmbariException("Action " + actionRequest.getActionName() + " requires explicit target host(s)" +
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/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 7aa39a8..2b93e54 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
@@ -18,12 +18,19 @@
package org.apache.ambari.server.controller;
-import java.security.SecureRandom;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-
-import org.apache.ambari.server.actionmanager.*;
+import com.google.gson.Gson;
+import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import com.google.inject.name.Names;
+import com.google.inject.persist.jpa.JpaPersistModule;
+import org.apache.ambari.server.actionmanager.ActionDBAccessor;
+import org.apache.ambari.server.actionmanager.ActionDBAccessorImpl;
+import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
+import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
+import org.apache.ambari.server.actionmanager.HostRoleCommandFactoryImpl;
+import org.apache.ambari.server.actionmanager.RequestFactory;
+import org.apache.ambari.server.actionmanager.StageFactory;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.ComponentResourceProvider;
import org.apache.ambari.server.controller.internal.HostComponentResourceProvider;
@@ -64,14 +71,24 @@ import org.apache.ambari.server.state.svccomphost.ServiceComponentHostImpl;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
-import com.google.gson.Gson;
-import com.google.inject.AbstractModule;
-import com.google.inject.Scopes;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-import com.google.inject.name.Names;
-import com.google.inject.persist.jpa.JpaPersistModule;
+import java.security.SecureRandom;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
-import static org.eclipse.persistence.config.PersistenceUnitProperties.*;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_JDBC_DDL_FILE;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_ONLY;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.CREATE_OR_EXTEND;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_BOTH_GENERATION;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION_MODE;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.DROP_AND_CREATE;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.DROP_JDBC_DDL_FILE;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_DRIVER;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_PASSWORD;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_URL;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_USER;
+import static org.eclipse.persistence.config.PersistenceUnitProperties.THROW_EXCEPTIONS;
/**
* Used for injection purposes.
@@ -108,7 +125,6 @@ public class ControllerModule extends AbstractModule {
bind(Clusters.class).to(ClustersImpl.class);
bind(AmbariCustomCommandExecutionHelper.class);
bind(ActionDBAccessor.class).to(ActionDBAccessorImpl.class);
- bind(CustomActionDBAccessor.class).to(CustomActionDBAccessorImpl.class);
bindConstant().annotatedWith(Names.named("schedulerSleeptime")).to(10000L);
// This time is added to summary timeout time of all tasks in stage
@@ -141,13 +157,13 @@ public class ControllerModule extends AbstractModule {
// custom jdbc properties
Map<String, String> custom = configuration.getDatabaseCustomProperties();
-
+
if (0 != custom.size()) {
for (Entry<String, String> entry : custom.entrySet()) {
properties.setProperty("eclipselink.jdbc.property." + entry.getKey(),
- entry.getValue());
+ entry.getValue());
}
- }
+ }
switch (persistenceType) {
case IN_MEMORY:
@@ -202,16 +218,16 @@ public class ControllerModule extends AbstractModule {
Host.class, HostImpl.class).build(HostFactory.class));
install(new FactoryModuleBuilder().implement(
Service.class, ServiceImpl.class).build(ServiceFactory.class));
-
-
+
+
install(new FactoryModuleBuilder()
.implement(ResourceProvider.class, Names.named("host"), HostResourceProvider.class)
.implement(ResourceProvider.class, Names.named("hostComponent"), HostComponentResourceProvider.class)
.implement(ResourceProvider.class, Names.named("service"), ServiceResourceProvider.class)
.implement(ResourceProvider.class, Names.named("component"), ComponentResourceProvider.class)
- .build(ResourceProviderFactory.class));
+ .build(ResourceProviderFactory.class));
+
-
install(new FactoryModuleBuilder().implement(
ServiceComponent.class, ServiceComponentImpl.class).build(
ServiceComponentFactory.class));
@@ -221,9 +237,9 @@ public class ControllerModule extends AbstractModule {
install(new FactoryModuleBuilder().implement(
Config.class, ConfigImpl.class).build(ConfigFactory.class));
install(new FactoryModuleBuilder().implement(
- ConfigGroup.class, ConfigGroupImpl.class).build(ConfigGroupFactory.class));
+ ConfigGroup.class, ConfigGroupImpl.class).build(ConfigGroupFactory.class));
install(new FactoryModuleBuilder().implement(RequestExecution.class,
- RequestExecutionImpl.class).build(RequestExecutionFactory.class));
+ RequestExecutionImpl.class).build(RequestExecutionFactory.class));
install(new FactoryModuleBuilder().build(StageFactory.class));
install(new FactoryModuleBuilder().build(RequestFactory.class));
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java
index 54ab41c..faef86c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java
@@ -20,15 +20,11 @@
package org.apache.ambari.server.controller.internal;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.actionmanager.ActionDefinition;
import org.apache.ambari.server.actionmanager.ActionManager;
-import org.apache.ambari.server.actionmanager.ActionType;
-import org.apache.ambari.server.actionmanager.CustomActionDBAccessorImpl;
-import org.apache.ambari.server.actionmanager.TargetHostType;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.ActionRequest;
import org.apache.ambari.server.controller.ActionResponse;
import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.RequestStatusResponse;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -40,6 +36,7 @@ import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.customactions.ActionDefinition;
import java.util.Arrays;
import java.util.HashSet;
@@ -67,7 +64,6 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
.getPropertyId("Actions", "default_timeout");
private static Set<String> pkPropertyIds = new HashSet<String>(
Arrays.asList(new String[]{ACTION_NAME_PROPERTY_ID}));
- private Boolean enableExperimental = false;
public ActionResourceProvider(Set<String> propertyIds,
Map<Type, String> keyPropertyIds,
@@ -75,14 +71,6 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
super(propertyIds, keyPropertyIds, managementController);
}
- public Boolean getEnableExperimental() {
- return enableExperimental;
- }
-
- public void setEnableExperimental(Boolean enabled) {
- enableExperimental = enabled;
- }
-
@Override
public RequestStatus createResources(Request request)
throws SystemException,
@@ -90,29 +78,8 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
ResourceAlreadyExistsException,
NoSuchParentResourceException {
- if (!getEnableExperimental()) {
- throw new UnsupportedOperationException("Not currently supported.");
- }
-
- for (final Map<String, Object> properties : request.getProperties()) {
- createResources(new Command<Void>() {
- @Override
- public Void invoke() throws AmbariException {
- ActionRequest actionReq = getRequest(properties);
- LOG.info("Received a create request for Action with"
- + ", actionName = " + actionReq.getActionName()
- + ", actionType = " + actionReq.getActionType()
- + ", description = " + actionReq.getDescription()
- + ", service = " + actionReq.getTargetService());
+ throw new UnsupportedOperationException("Not currently supported.");
- createActionDefinition(actionReq);
- return null;
- }
- });
- }
- notifyCreate(Type.Action, request);
-
- return getRequestStatus(null);
}
@Override
@@ -120,34 +87,8 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
throws SystemException, UnsupportedPropertyException,
NoSuchResourceException, NoSuchParentResourceException {
- if (!getEnableExperimental()) {
- throw new UnsupportedOperationException("Not currently supported.");
- }
+ throw new UnsupportedOperationException("Not currently supported.");
- final Set<ActionRequest> requests = new HashSet<ActionRequest>();
- RequestStatusResponse response;
-
- for (Map<String, Object> requestPropertyMap : request.getProperties()) {
- Set<Map<String, Object>> propertyMaps = getPropertyMaps(requestPropertyMap, predicate);
- for (Map<String, Object> propertyMap : propertyMaps) {
- ActionRequest actionReq = getRequest(propertyMap);
- LOG.info("Received a update request for Action with"
- + ", actionName = " + actionReq.getActionName()
- + ", actionType = " + actionReq.getActionType()
- + ", description = " + actionReq.getDescription()
- + ", timeout = " + actionReq.getDefaultTimeout());
-
- requests.add(actionReq);
- }
- }
- response = modifyResources(new Command<RequestStatusResponse>() {
- @Override
- public RequestStatusResponse invoke() throws AmbariException {
- return updateActionDefinitions(requests, request.getRequestInfoProperties());
- }
- });
- notifyUpdate(Type.Action, request, predicate);
- return getRequestStatus(response);
}
@Override
@@ -205,23 +146,7 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
public RequestStatus deleteResources(Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
- if (!getEnableExperimental()) {
- throw new UnsupportedOperationException("Not currently supported.");
- }
-
- for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
- final ActionRequest request = getRequest(propertyMap);
- try {
- LOG.info("Received a delete request for Action with"
- + ", actionName = " + request.getActionName());
-
- deleteActionDefinition(request);
- } catch (AmbariException ex) {
- throw new NoSuchResourceException(ex.getMessage());
- }
- }
- notifyDelete(Type.Action, predicate);
- return getRequestStatus(null);
+ throw new UnsupportedOperationException("Not currently supported.");
}
private ActionRequest getRequest(Map<String, Object> properties) {
@@ -247,28 +172,8 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
return getManagementController().getActionManager();
}
- protected synchronized void createActionDefinition(ActionRequest request)
- throws AmbariException {
- if (request.getActionName() == null
- || request.getActionName().isEmpty()) {
- throw new IllegalArgumentException("Action name should be provided");
- }
-
- LOG.info("Received a createActionDefinition request = " + request.toString());
- if (request.getTargetType() == null || request.getActionType() == null) {
- throw new AmbariException("Both target_type and action_type must be specified.");
- }
- TargetHostType targetType = TargetHostType.valueOf(request.getTargetType());
- ActionType actionType = ActionType.valueOf(request.getActionType());
-
- Short defaultTimeout = CustomActionDBAccessorImpl.MIN_TIMEOUT;
- if (request.getDefaultTimeout() != null && !request.getDefaultTimeout().isEmpty()) {
- defaultTimeout = Short.parseShort(request.getDefaultTimeout());
- }
-
- getActionManager().createActionDefinition(request.getActionName(), actionType, request.getInputs(),
- request.getDescription(), request.getTargetService(), request.getTargetComponent(),
- targetType, defaultTimeout);
+ private AmbariMetaInfo getAmbariMetaInfo() {
+ return getManagementController().getAmbariMetaInfo();
}
protected synchronized Set<ActionResponse> getActionDefinitions(Set<ActionRequest> requests)
@@ -276,45 +181,18 @@ public class ActionResourceProvider extends AbstractControllerResourceProvider {
Set<ActionResponse> responses = new HashSet<ActionResponse>();
for (ActionRequest request : requests) {
if (request.getActionName() == null) {
- List<ActionDefinition> ads = getActionManager().getAllActionDefinition();
+ List<ActionDefinition> ads = getAmbariMetaInfo().getAllActionDefinition();
for (ActionDefinition ad : ads) {
- responses.add(new ActionResponse(ad));
+ responses.add(ad.convertToResponse());
}
} else {
- ActionDefinition ad = getActionManager().getActionDefinition(request.getActionName());
+ ActionDefinition ad = getAmbariMetaInfo().getActionDefinition(request.getActionName());
if (ad != null) {
- responses.add(new ActionResponse(ad));
+ responses.add(ad.convertToResponse());
}
}
}
return responses;
}
-
- protected synchronized RequestStatusResponse updateActionDefinitions(Set<ActionRequest> requests,
- Map<String, String> requestProperties)
- throws AmbariException {
- RequestStatusResponse response = null;
- for (ActionRequest request : requests) {
- if (null != request.getInputs() || null != request.getTargetService()
- || null != request.getTargetComponent()) {
- throw new AmbariException("Cannot update inputs, target_service, or target_component");
- }
- TargetHostType targetType = request.getTargetType() == null ? null
- : TargetHostType.valueOf(request.getTargetType());
- ActionType actionType = request.getActionType() == null ? null : ActionType.valueOf(request.getActionType());
- Short defaultTimeout = null;
- if (request.getDefaultTimeout() != null && !request.getDefaultTimeout().isEmpty()) {
- defaultTimeout = Short.parseShort(request.getDefaultTimeout());
- }
- getActionManager().updateActionDefinition(request.getActionName(), actionType,
- request.getDescription(), targetType, defaultTimeout);
- }
- return response;
- }
-
- protected synchronized void deleteActionDefinition(ActionRequest request)
- throws AmbariException {
- getActionManager().deleteActionDefinition(request.getActionName());
- }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
new file mode 100644
index 0000000..1f189a3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
@@ -0,0 +1,132 @@
+/**
+ * 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.customactions;
+
+import org.apache.ambari.server.actionmanager.ActionType;
+import org.apache.ambari.server.actionmanager.TargetHostType;
+import org.apache.ambari.server.controller.ActionResponse;
+
+/**
+ * The resource describing the definition of an action
+ */
+public class ActionDefinition {
+ private String actionName;
+ private ActionType actionType;
+ private String inputs;
+ private String targetService;
+ private String targetComponent;
+ private String description;
+ private TargetHostType targetType;
+ private Short defaultTimeout;
+
+ /**
+ * Create an instance of ActionDefinition
+ *
+ * @param actionName The name of the action
+ * @param actionType The type fo the action
+ * @param inputs Expected input of the action
+ * @param targetService Target service type (e.g. HDFS)
+ * @param targetComponent Target component type (e.g. DATANODE)
+ * @param description Short description of the action
+ * @param targetType Selection criteria for target hosts
+ * @param defaultTimeout The timeout value for this action when executed
+ */
+ public ActionDefinition(String actionName, ActionType actionType, String inputs,
+ String targetService, String targetComponent, String description,
+ TargetHostType targetType, Short defaultTimeout) {
+ setActionName(actionName);
+ setActionType(actionType);
+ setInputs(inputs);
+ setTargetService(targetService);
+ setTargetComponent(targetComponent);
+ setDescription(description);
+ setTargetType(targetType);
+ setDefaultTimeout(defaultTimeout);
+ }
+
+ public String getActionName() {
+ return actionName;
+ }
+
+ public void setActionName(String actionName) {
+ this.actionName = actionName;
+ }
+
+ public ActionType getActionType() {
+ return actionType;
+ }
+
+ public void setActionType(ActionType actionType) {
+ this.actionType = actionType;
+ }
+
+ public String getInputs() {
+ return inputs;
+ }
+
+ public void setInputs(String inputs) {
+ this.inputs = inputs;
+ }
+
+ public String getTargetService() {
+ return targetService;
+ }
+
+ public void setTargetService(String targetService) {
+ this.targetService = targetService;
+ }
+
+ public String getTargetComponent() {
+ return targetComponent;
+ }
+
+ public void setTargetComponent(String targetComponent) {
+ this.targetComponent = targetComponent;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public TargetHostType getTargetType() {
+ return targetType;
+ }
+
+ public void setTargetType(TargetHostType targetType) {
+ this.targetType = targetType;
+ }
+
+ public Short getDefaultTimeout() {
+ return defaultTimeout;
+ }
+
+ public void setDefaultTimeout(Short defaultTimeout) {
+ this.defaultTimeout = defaultTimeout;
+ }
+
+ public ActionResponse convertToResponse() {
+ return new ActionResponse(getActionName(), getActionType().name(), getInputs(),
+ getTargetService(), getTargetComponent(), getDescription(), getTargetType().name(),
+ getDefaultTimeout().toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
new file mode 100644
index 0000000..e058ce7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
@@ -0,0 +1,202 @@
+/**
+ * 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.customactions;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.actionmanager.ActionType;
+import org.apache.ambari.server.actionmanager.TargetHostType;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.UnmarshalException;
+import javax.xml.bind.Unmarshaller;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Manages Action definitions read from XML files
+ */
+public class ActionDefinitionManager {
+ public static final Short MIN_TIMEOUT = 60;
+ private final static Logger LOG = LoggerFactory
+ .getLogger(ActionDefinitionManager.class);
+ private static final Map<Class<?>, JAXBContext> _jaxbContexts =
+ new HashMap<Class<?>, JAXBContext>();
+ private static final Short MAX_TIMEOUT = 600;
+
+ static {
+ try {
+ JAXBContext ctx = JAXBContext.newInstance(ActionDefinitionXml.class);
+ _jaxbContexts.put(ActionDefinitionXml.class, ctx);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private final Map<String, ActionDefinition> actionDefinitionMap = new HashMap<String, ActionDefinition>();
+
+ public ActionDefinitionManager() {
+ }
+
+ public static <T> T unmarshal(Class<T> clz, File file) throws JAXBException {
+ Unmarshaller u = _jaxbContexts.get(clz).createUnmarshaller();
+
+ return clz.cast(u.unmarshal(file));
+ }
+
+ private <E extends Enum<E>> E safeValueOf(Class<E> enumm, String s, StringBuilder reason) {
+ if (s == null || s.length() == 0) {
+ return null;
+ }
+
+ try {
+ return Enum.valueOf(enumm, s);
+ } catch (IllegalArgumentException iaex) {
+ reason.append("Invalid value provided for " + enumm.getName());
+ return null;
+ }
+ }
+
+ public void readCustomActionDefinitions(File customActionDefinitionRoot) throws JAXBException, AmbariException {
+ if (customActionDefinitionRoot == null
+ || !customActionDefinitionRoot.exists()
+ || !customActionDefinitionRoot.canRead()) {
+ LOG.warn("Cannot read custom action definitions. " +
+ customActionDefinitionRoot == null ? "" : "Check path " + customActionDefinitionRoot.getAbsolutePath());
+ }
+
+ File[] customActionDefinitionFiles
+ = customActionDefinitionRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+
+ if (customActionDefinitionFiles != null) {
+ for (File definitionFile : customActionDefinitionFiles) {
+ ActionDefinitionXml adx = null;
+ try {
+ adx = unmarshal(ActionDefinitionXml.class, definitionFile);
+ } catch (UnmarshalException uex) {
+ LOG.warn("Encountered badly formed action definition file - " + definitionFile.getAbsolutePath());
+ continue;
+ }
+ for (ActionDefinitionSpec ad : adx.actionDefinitions()) {
+ LOG.debug("Read action definition = " + ad.toString());
+ StringBuilder errorReason =
+ new StringBuilder("Error while parsing action definition. ").append(ad.toString()).append(" --- ");
+
+ TargetHostType targetType = safeValueOf(TargetHostType.class, ad.getTargetType(), errorReason);
+ ActionType actionType = safeValueOf(ActionType.class, ad.getActionType(), errorReason);
+
+ Short defaultTimeout = MIN_TIMEOUT;
+ if (ad.getDefaultTimeout() != null && !ad.getDefaultTimeout().isEmpty()) {
+ defaultTimeout = Short.parseShort(ad.getDefaultTimeout());
+ }
+
+ if (isValidActionDefinition(ad, actionType, defaultTimeout, errorReason)) {
+ String actionName = ad.getActionName();
+ if (actionDefinitionMap.containsKey(actionName)) {
+ LOG.warn("Ignoring action definition as a different definition by that name already exists. "
+ + ad.toString());
+ continue;
+ }
+
+ actionDefinitionMap.put(ad.getActionName(), new ActionDefinition(ad.getActionName(), actionType,
+ ad.getInputs(), ad.getTargetService(), ad.getTargetComponent(), ad.getDescription(), targetType, defaultTimeout));
+ LOG.info("Added custom action definition for " + ad.getActionName());
+ } else {
+ LOG.warn(errorReason.toString());
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isValidActionDefinition(ActionDefinitionSpec ad, ActionType actionType,
+ Short defaultTimeout, StringBuilder reason) {
+ if (isValidActionName(ad.getActionName(), reason)) {
+
+ if (defaultTimeout < MIN_TIMEOUT || defaultTimeout > MAX_TIMEOUT) {
+ reason.append("Default timeout should be between " + MIN_TIMEOUT + " and " + MAX_TIMEOUT);
+ return false;
+ }
+
+ if (actionType == null || actionType == ActionType.SYSTEM_DISABLED) {
+ reason.append("Action type cannot be " + actionType);
+ return false;
+ }
+
+ if (ad.getDescription() == null || ad.getDescription().isEmpty()) {
+ reason.append("Action description cannot be empty");
+ return false;
+ }
+
+ if (ad.getTargetService() == null || ad.getTargetService().isEmpty()) {
+ if (ad.getTargetComponent() != null && !ad.getTargetComponent().isEmpty()) {
+ reason.append("Target component cannot be specified unless target service is specified");
+ return false;
+ }
+ }
+
+ if (ad.getInputs() != null && !ad.getInputs().isEmpty()) {
+ String[] parameters = ad.getInputs().split(",");
+ for (String parameter : parameters) {
+ if (parameter.trim().isEmpty()) {
+ reason.append("Empty parameter cannot be specified as an input parameter");
+ }
+ }
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+ }
+
+ public List<ActionDefinition> getAllActionDefinition() {
+ return new ArrayList<ActionDefinition>(actionDefinitionMap.values());
+ }
+
+ public ActionDefinition getActionDefinition(String name) {
+ return actionDefinitionMap.get(name);
+ }
+
+ public void addActionDefinition(ActionDefinition ad) throws AmbariException {
+ if (!actionDefinitionMap.containsKey(ad.getActionName())) {
+ actionDefinitionMap.put(ad.getActionName(), ad);
+ } else {
+ throw new AmbariException("Action definition by name " + ad.getActionName() + " already exists.");
+ }
+ }
+
+ private boolean isValidActionName(String actionName, StringBuilder reason) {
+ if (actionName == null || actionName.isEmpty()) {
+ reason.append("Action name cannot be empty");
+ return false;
+ }
+ String trimmedName = actionName.replaceAll("\\s+", "");
+ if (actionName.length() > trimmedName.length()) {
+ reason.append("Action name cannot contain white spaces");
+ return false;
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8e8a9a47/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
new file mode 100644
index 0000000..2dfa1f2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
@@ -0,0 +1,139 @@
+/**
+ * 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.customactions;
+
+public class ActionDefinitionSpec {
+ private String actionName;
+ private String actionType;
+ private String inputs;
+ private String targetService;
+ private String targetComponent;
+ private String description;
+ private String targetType;
+ private String defaultTimeout;
+
+ public String getTargetComponent() {
+ return targetComponent;
+ }
+
+ public void setTargetComponent(String targetComponent) {
+ this.targetComponent = targetComponent;
+ }
+
+ public String getTargetType() {
+ return targetType;
+ }
+
+ public void setTargetType(String targetType) {
+ this.targetType = targetType;
+ }
+
+ public String getDefaultTimeout() {
+ return defaultTimeout;
+ }
+
+ public void setDefaultTimeout(String defaultTimeout) {
+ this.defaultTimeout = defaultTimeout;
+ }
+
+ public String getActionName() {
+ return actionName;
+ }
+
+ public void setActionName(String actionName) {
+ this.actionName = actionName;
+ }
+
+ public String getActionType() {
+ return actionType;
+ }
+
+ public void setActionType(String actionType) {
+ this.actionType = actionType;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getInputs() {
+ return inputs;
+ }
+
+ public void setInputs(String inputs) {
+ this.inputs = inputs;
+ }
+
+ public String getTargetService() {
+ return targetService;
+ }
+
+ public void setTargetService(String targetService) {
+ this.targetService = targetService;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((actionName == null) ? 0 : actionName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ActionDefinitionSpec other = (ActionDefinitionSpec) obj;
+ if (description == null) {
+ if (other.description != null) {
+ return false;
+ }
+ } else if (!description.equals(other.description)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder().append("ActionDefinition:")
+ .append(" actionName: ").append(actionName)
+ .append(" actionType: ").append(actionType)
+ .append(" inputs: ").append(inputs)
+ .append(" description: ").append(description)
+ .append(" targetService: ").append(targetService)
+ .append(" targetComponent: ").append(targetComponent)
+ .append(" defaultTimeout: ").append(defaultTimeout)
+ .append(" targetType: ").append(targetType)
+ .toString();
+ }
+}