You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2014/02/25 19:20:33 UTC

[2/3] AMBARI-4791. API call to restart all components on one or more hosts should result in one request. (swagle)

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/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 7e7f381..60688af 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,22 +18,11 @@
 
 package org.apache.ambari.server.controller;
 
-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.EnumSet;
-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 org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -52,9 +41,11 @@ import org.apache.ambari.server.actionmanager.Request;
 import org.apache.ambari.server.actionmanager.RequestFactory;
 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;
+import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
@@ -64,14 +55,15 @@ 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.CommandScriptDefinition;
 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.MaintenanceState;
+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;
@@ -82,14 +74,15 @@ 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.ServiceOsSpecific;
 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.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
-import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostDisableEvent;
+import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostRestoreEvent;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent;
@@ -101,17 +94,48 @@ import org.apache.http.client.utils.URIBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-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.EnumSet;
+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 static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JAVA_HOME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JCE_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MYSQL_JDBC_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.ORACLE_JDBC_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
+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;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
 
 @Singleton
-public class AmbariManagementControllerImpl implements
-    AmbariManagementController {
+public class AmbariManagementControllerImpl implements AmbariManagementController {
 
   private final static Logger LOG =
       LoggerFactory.getLogger(AmbariManagementControllerImpl.class);
@@ -185,7 +209,8 @@ public class AmbariManagementControllerImpl implements
 
   @Inject
   private AmbariCustomCommandExecutionHelper customCommandExecutionHelper;
-  final private AmbariActionExecutionHelper actionExecutionHelper;
+  @Inject
+  private AmbariActionExecutionHelper actionExecutionHelper;
 
   @Inject
   public AmbariManagementControllerImpl(ActionManager actionManager,
@@ -227,9 +252,6 @@ public class AmbariManagementControllerImpl implements
       this.mysqljdbcUrl = null;
       this.serverDB = null;
     }
-
-    this.actionExecutionHelper = new AmbariActionExecutionHelper(
-        this.actionMetadata, this.clusters, this);
   }
   
   public String getAmbariServerURI(String path) {
@@ -1100,6 +1122,180 @@ public class AmbariManagementControllerImpl implements
     return executionScheduleManager;
   }
 
+  /**
+   * Creates and populates an EXECUTION_COMMAND for host
+   */
+  private 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);
+    StackInfo stackInfo = ambariMetaInfo.getStackInfo(stackId.getStackName(),
+      stackId.getStackVersion());
+
+    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);
+    }
+
+    String jobtrackerHost = getJobTrackerHost(cluster);
+    if (!scHost.getHostName().equals(jobtrackerHost)) {
+      if (configTags.get(Configuration.GLOBAL_CONFIG_TAG) != null) {
+        configHelper.applyCustomConfig(
+          configurations, Configuration.GLOBAL_CONFIG_TAG,
+          Configuration.RCA_ENABLED_PROPERTY, "false", false);
+      }
+    }
+
+    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 = configs.getDefaultAgentTaskTimeout();
+    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());
+        if (script.getTimeout() > 0) {
+          commandTimeout = String.valueOf(script.getTimeout());
+        }
+      } else {
+        String message = String.format("Component %s of service %s has no " +
+          "command script defined", componentName, serviceName);
+        throw new AmbariException(message);
+      }
+    }
+    commandParams.put(COMMAND_TIMEOUT, commandTimeout);
+    commandParams.put(SERVICE_PACKAGE_FOLDER,
+      serviceInfo.getServicePackageFolder());
+    commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
+
+    execCmd.setCommandParams(commandParams);
+
+    String repoInfo = customCommandExecutionHelper.getRepoInfo(cluster, host);
+    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>();
+    hostParams.put(REPO_INFO, repoInfo);
+    hostParams.put(JDK_LOCATION, getJdkResourceUrl());
+    hostParams.put(JAVA_HOME, getJavaHome());
+    hostParams.put(JDK_NAME, getJDKName());
+    hostParams.put(JCE_NAME, getJCEName());
+    hostParams.put(STACK_NAME, stackId.getStackName());
+    hostParams.put(STACK_VERSION, stackId.getStackVersion());
+    hostParams.put(DB_NAME, getServerDB());
+    hostParams.put(MYSQL_JDBC_URL, getMysqljdbcUrl());
+    hostParams.put(ORACLE_JDBC_URL, getOjdbcUrl());
+    hostParams.putAll(getRcaParameters());
+
+    // 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(serviceRepo);
+        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);
+
+    execCmd.setPassiveInfo(MaintenanceStateHelper.getMaintenanceHostCompoments(clusters, cluster));
+  }
+
+  private ActionExecutionContext getActionExecutionContext
+      (ExecuteActionRequest actionRequest) throws AmbariException {
+
+    if (actionRequest.isCommand()) {
+      return new ActionExecutionContext(actionRequest.getClusterName(),
+        actionRequest.getCommandName(), actionRequest.getResourceFilters(),
+        actionRequest.getParameters());
+    } else {
+
+    ActionDefinition actionDef = ambariMetaInfo.getActionDefinition(actionRequest.getActionName());
+
+    if (actionDef == null) {
+      throw new AmbariException("Action " + actionRequest.getActionName() + " does not exist");
+    }
+
+    return new ActionExecutionContext(actionRequest.getClusterName(),
+      actionRequest.getActionName(), actionRequest.getResourceFilters(),
+      actionRequest.getParameters(), actionDef.getTargetType(),
+      actionDef.getDefaultTimeout(), actionDef.getTargetService(),
+      actionDef.getTargetComponent());
+
+    }
+  }
+
   private List<Stage> doStageCreation(Cluster cluster,
       Map<State, List<Service>> changedServices,
       Map<State, List<ServiceComponent>> changedComps,
@@ -1294,9 +1490,8 @@ public class AmbariManagementControllerImpl implements
               }
             }
 
-            customCommandExecutionHelper.createHostAction(cluster, stage, scHost,
-                    configurations, configTags,
-                    roleCommand, requestParameters, event);
+            createHostAction(cluster, stage, scHost, configurations, configTags,
+              roleCommand, requestParameters, event);
           }
         }
       }
@@ -1319,8 +1514,8 @@ public class AmbariManagementControllerImpl implements
         }
 
         customCommandExecutionHelper.addServiceCheckAction(stage, clientHost,
-            smokeTestRole, nowTimestamp, serviceName,
-            null, null, createDefaultHostParams(cluster));
+          smokeTestRole, nowTimestamp, serviceName,
+          null, null, createDefaultHostParams(cluster));
       }
 
       RoleCommandOrder rco = getRoleCommandOrder(cluster);
@@ -2118,11 +2313,15 @@ public class AmbariManagementControllerImpl implements
 
     Cluster cluster = clusters.getCluster(clusterName);
 
-    ActionExecutionContext actionExecContext = null;
+    LOG.info("Received action execution request"
+      + ", clusterName=" + actionRequest.getClusterName()
+      + ", request=" + actionRequest.toString());
+
+    ActionExecutionContext actionExecContext = getActionExecutionContext(actionRequest);
     if (actionRequest.isCommand()) {
-      customCommandExecutionHelper.validateCustomCommand(actionRequest);
+      customCommandExecutionHelper.validateAction(actionRequest);
     } else {
-      actionExecContext = actionExecutionHelper.validateCustomAction(actionRequest, cluster);
+      actionExecutionHelper.validateAction(actionRequest);
     }
 
     Map<String, Set<String>> clusterHostInfo = StageUtils.getClusterHostInfo(
@@ -2134,9 +2333,9 @@ public class AmbariManagementControllerImpl implements
     Map<String, String> params = createDefaultHostParams(cluster);
 
     if (actionRequest.isCommand()) {
-      customCommandExecutionHelper.addAction(actionRequest, stage, params);
+      customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, params);
     } else {
-      actionExecutionHelper.addAction(actionExecContext, stage, configs, hostsMap, params);
+      actionExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, params);
     }
 
     RoleCommandOrder rco = this.getRoleCommandOrder(cluster);
@@ -2313,7 +2512,6 @@ public class AmbariManagementControllerImpl implements
       }
     }
   }
-  
 
   @Override
   public Set<StackVersionResponse> getStackVersions(

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index b9f62e4..2361af7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -131,6 +131,7 @@ public class AmbariServer {
     return clusterController;
   }
 
+  @SuppressWarnings("deprecation")
   public void run() throws Exception {
     // Initialize meta info before heartbeat monitor
     ambariMetaInfo.init();

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/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 ae57af2..adb78c3 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
@@ -37,7 +37,6 @@ import org.apache.ambari.server.controller.internal.HostComponentResourceProvide
 import org.apache.ambari.server.controller.internal.HostResourceProvider;
 import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
-import org.apache.ambari.server.orm.DBAccessorImpl;
 import org.apache.ambari.server.orm.PersistenceType;
 import org.apache.ambari.server.scheduler.ExecutionScheduler;
 import org.apache.ambari.server.scheduler.ExecutionSchedulerImpl;
@@ -71,12 +70,13 @@ import org.apache.ambari.server.state.scheduler.RequestExecutionImpl;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostImpl;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.crypto.password.StandardPasswordEncoder;
+
 import java.security.SecureRandom;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
+
 import com.google.gson.GsonBuilder;
-import org.apache.ambari.server.orm.DBAccessor;
 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;
@@ -247,7 +247,6 @@ public class ControllerModule extends AbstractModule {
     install(new FactoryModuleBuilder().build(RequestFactory.class));
 
     bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
-    bind(DBAccessor.class).to(DBAccessorImpl.class);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/controller/ExecuteActionRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExecuteActionRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExecuteActionRequest.java
index f8dd908..3b5afcd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ExecuteActionRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ExecuteActionRequest.java
@@ -17,7 +17,7 @@
  */
 package org.apache.ambari.server.controller;
 
-import org.apache.ambari.server.utils.StageUtils;
+import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -28,38 +28,36 @@ import java.util.Map;
  * Helper class to capture details used to create action or custom commands
  */
 public class ExecuteActionRequest {
-  private String clusterName;
-  private String commandName;
+  private final String clusterName;
+  private final String commandName;
+  private final List<RequestResourceFilter> resourceFilters;
   private String actionName;
-  private String serviceName;
-  private String componentName;
-  private List<String> hosts;
   private Map<String, String> parameters;
 
   public ExecuteActionRequest(String clusterName, String commandName,
-                              String actionName, String serviceName, String componentName,
-                              List<String> hosts, Map<String, String> parameters) {
-    this(clusterName, commandName, serviceName, parameters);
+                              String actionName,
+                              List<RequestResourceFilter> resourceFilters,
+                              Map<String, String> parameters) {
+    this(clusterName, commandName, parameters);
     this.actionName = actionName;
-    this.componentName = componentName;
-    if (hosts != null) {
-      this.hosts.addAll(hosts);
+    if (resourceFilters != null) {
+      this.resourceFilters.addAll(resourceFilters);
     }
   }
 
   /**
-   * Create an ExecuteActionRequest to execute a command
+   * Create an ExecuteActionRequest to execute a command.
+   * No filters.
    */
-  public ExecuteActionRequest(String clusterName, String commandName, String serviceName,
-                              Map<String, String> parameters) {
+  public ExecuteActionRequest(String clusterName, String commandName, Map<String, String> parameters) {
     this.clusterName = clusterName;
     this.commandName = commandName;
-    this.serviceName = serviceName;
+    this.actionName = null;
     this.parameters = new HashMap<String, String>();
     if (parameters != null) {
       this.parameters.putAll(parameters);
     }
-    this.hosts = new ArrayList<String>();
+    this.resourceFilters = new ArrayList<RequestResourceFilter>();
   }
 
   public String getClusterName() {
@@ -74,22 +72,14 @@ public class ExecuteActionRequest {
     return actionName;
   }
 
-  public String getServiceName() {
-    return serviceName;
-  }
-
-  public String getComponentName() {
-    return componentName;
+  public List<RequestResourceFilter> getResourceFilters() {
+    return resourceFilters;
   }
 
   public Map<String, String> getParameters() {
     return parameters;
   }
 
-  public List<String> getHosts() {
-    return hosts;
-  }
-
   public Boolean isCommand() {
     return actionName == null || actionName.isEmpty();
   }
@@ -101,9 +91,7 @@ public class ExecuteActionRequest {
         append(", action :" + actionName).
         append(", command :" + commandName).
         append(", inputs :" + parameters.toString()).
-        append(", targetService :" + serviceName).
-        append(", targetComponent :" + componentName).
-        append(", targetHosts :" + hosts.toString()).
+        append(", resourceFilters: " + resourceFilters).
         append(", clusterName :" + clusterName).toString();
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/controller/MaintenanceStateHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/MaintenanceStateHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/MaintenanceStateHelper.java
index 5251b3d..b78f68f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/MaintenanceStateHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/MaintenanceStateHelper.java
@@ -17,14 +17,17 @@
  */
 package org.apache.ambari.server.controller;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.HostNotFoundException;
 import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Host;
@@ -32,7 +35,6 @@ import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
-
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 
@@ -143,11 +145,14 @@ public class MaintenanceStateHelper {
     
     // return the first one, just like amc.createStages()
     RequestStatusResponse response = null;
-    
+
+    RequestResourceFilter resourceFilter =
+      new RequestResourceFilter(NAGIOS_SERVICE, NAGIOS_COMPONENT, null);
+
     for (String clusterName : clusterNames) {
       ExecuteActionRequest actionRequest = new ExecuteActionRequest(
-          clusterName, RoleCommand.ACTIONEXECUTE.name(),
-          NAGIOS_ACTION_NAME, NAGIOS_SERVICE, NAGIOS_COMPONENT, null, params);
+        clusterName, null, NAGIOS_ACTION_NAME,
+        Collections.singletonList(resourceFilter), params);
       
       if (null == response)
         response = amc.createAction(actionRequest, requestProperties);

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceFilter.java
new file mode 100644
index 0000000..8a492a2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceFilter.java
@@ -0,0 +1,69 @@
+/**
+ * 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.internal;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RequestResourceFilter {
+  private String serviceName;
+  private String componentName;
+  private final List<String> hostNames = new ArrayList<String>();
+
+  public RequestResourceFilter() {
+
+  }
+
+  public RequestResourceFilter(String serviceName, String componentName, List<String> hostNames) {
+    this.serviceName = serviceName;
+    this.componentName = componentName;
+    if (hostNames != null) {
+      this.hostNames.addAll(hostNames);
+    }
+  }
+
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
+  @JsonProperty("service_name")
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
+  @JsonProperty("component_name")
+  public String getComponentName() {
+    return componentName;
+  }
+
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
+  @JsonProperty("hosts")
+  public List<String> getHostNames() {
+    return hostNames;
+  }
+
+  @Override
+  public String toString() {
+    return "RequestResourceFilter{" +
+      "serviceName='" + serviceName + '\'' +
+      ", componentName='" + componentName + '\'' +
+      ", hostNames=" + hostNames +
+      '}';
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
index 92d1476..5b3ff8a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
@@ -17,12 +17,14 @@
  */
 package org.apache.ambari.server.controller.internal;
 
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
-import org.apache.ambari.server.controller.ExecuteActionRequest;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ExecuteActionRequest;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -33,9 +35,9 @@ import org.apache.ambari.server.controller.spi.Resource;
 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.state.Clusters;
 
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -62,9 +64,7 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
   public static final String REQUEST_SOURCE_SCHEDULE_HREF = "Requests/request_schedule/href";
   protected static final String REQUEST_TYPE_ID = "Requests/type";
   protected static final String REQUEST_INPUTS_ID = "Requests/inputs";
-  protected static final String REQUEST_TARGET_SERVICE_ID = "Requests/target_service";
-  protected static final String REQUEST_TARGET_COMPONENT_ID = "Requests/target_component";
-  protected static final String REQUEST_TARGET_HOSTS_ID = "Requests/target_hosts";
+  protected static final String REQUEST_RESOURCE_FILTER_ID = "Requests/resources";
   protected static final String REQUEST_CREATE_TIME_ID = "Requests/create_time";
   protected static final String REQUEST_START_TIME_ID = "Requests/start_time";
   protected static final String REQUEST_END_TIME_ID = "Requests/end_time";
@@ -77,13 +77,11 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
   protected static final String REQUEST_PROGRESS_PERCENT_ID = "Requests/progress_percent";
   protected static final String COMMAND_ID = "command";
   protected static final String ACTION_ID = "action";
-  protected static final String HOSTS_ID = "hosts";
-  protected static final String SERVICE_NAME_ID = "service_name";
-  protected static final String COMPONENT_NAME_ID = "component_name";
   protected static final String INPUTS_ID = "parameters";
   private static Set<String> pkPropertyIds =
       new HashSet<String>(Arrays.asList(new String[]{
           REQUEST_ID_PROPERTY_ID}));
+  private Gson gson = new Gson();
 
   // ----- Constructors ----------------------------------------------------
 
@@ -165,6 +163,7 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
   // ----- utility methods --------------------------------------------------
 
   // Get request to execute an action/command
+  @SuppressWarnings("unchecked")
   private ExecuteActionRequest getActionRequest(Request request) {
     Map<String, String> requestInfoProperties = request.getRequestInfoProperties();
     Map<String, Object> propertyMap = request.getProperties().iterator().next();
@@ -184,20 +183,13 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
       actionName = requestInfoProperties.get(ACTION_ID);
     }
 
-    String hostList = requestInfoProperties.get(HOSTS_ID);
-    List<String> hosts = new ArrayList<String>();
-    if (hostList != null && !hostList.isEmpty()) {
-      for (String hostname : hostList.split(",")) {
-        String trimmedName = hostname.trim();
-        if (!trimmedName.isEmpty()) {
-          hosts.add(hostname.trim());
-        }
-      }
+    List<RequestResourceFilter> resourceFilters = null;
+    Object resourceFilterObj = propertyMap.get(REQUEST_RESOURCE_FILTER_ID);
+    if (resourceFilterObj != null) {
+      Type filterListType = new TypeToken<List<RequestResourceFilter>>(){}.getType();
+      resourceFilters = gson.fromJson((String) resourceFilterObj, filterListType);
     }
 
-    String serviceName = requestInfoProperties.get(SERVICE_NAME_ID);
-    String componentName = requestInfoProperties.get(COMPONENT_NAME_ID);
-
     Map<String, String> params = new HashMap<String, String>();
     String keyPrefix = "/" + INPUTS_ID + "/";
     for (String key : requestInfoProperties.keySet()) {
@@ -207,13 +199,11 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
     }
 
     return new ExecuteActionRequest(
-        (String) propertyMap.get(REQUEST_CLUSTER_NAME_PROPERTY_ID),
-        commandName,
-        actionName,
-        serviceName,
-        componentName,
-        hosts,
-        params);
+      (String) propertyMap.get(REQUEST_CLUSTER_NAME_PROPERTY_ID),
+      commandName,
+      actionName,
+      resourceFilters,
+      params);
   }
 
   // Get all of the request resources for the given properties
@@ -286,9 +276,7 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
     setResourceProperty(resource, REQUEST_CONTEXT_ID, request.getRequestContext(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_TYPE_ID, request.getRequestType(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_INPUTS_ID, request.getInputs(), requestedPropertyIds);
-    setResourceProperty(resource, REQUEST_TARGET_SERVICE_ID, request.getTargetService(), requestedPropertyIds);
-    setResourceProperty(resource, REQUEST_TARGET_COMPONENT_ID, request.getTargetComponent(), requestedPropertyIds);
-    setResourceProperty(resource, REQUEST_TARGET_HOSTS_ID, request.getTargetHosts(), requestedPropertyIds);
+    setResourceProperty(resource, REQUEST_RESOURCE_FILTER_ID, request.getResourceFilters(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_CREATE_TIME_ID, request.getCreateTime(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_START_TIME_ID, request.getStartTime(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_END_TIME_ID, request.getEndTime(), requestedPropertyIds);
@@ -421,4 +409,5 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
 
     return resource;
   }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestEntity.java
index 072b4ed..17fbe2f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestEntity.java
@@ -29,7 +29,6 @@ import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
@@ -63,18 +62,6 @@ public class RequestEntity {
   @Basic
   private String inputs;
 
-  @Column(name = "target_service")
-  @Basic
-  private String targetService;
-
-  @Column(name = "target_component")
-  @Basic
-  private String targetComponent;
-
-  @Column(name = "target_hosts")
-  @Lob
-  private String targetHosts;
-
   @Column(name = "request_type")
   @Enumerated(value = EnumType.STRING)
   private RequestType requestType;
@@ -98,6 +85,9 @@ public class RequestEntity {
   @OneToMany(mappedBy = "request")
   private Collection<StageEntity> stages;
 
+  @OneToMany(mappedBy = "requestEntity")
+  private Collection<RequestResourceFilterEntity> resourceFilterEntities;
+
   @ManyToOne(cascade = {CascadeType.MERGE})
   @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id")
   private ClusterEntity cluster;
@@ -170,30 +160,6 @@ public class RequestEntity {
     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 getTargetHosts() {
-    return targetHosts;
-  }
-
-  public void setTargetHosts(String targetHosts) {
-    this.targetHosts = targetHosts;
-  }
-
   public RequestType getRequestType() {
     return requestType;
   }
@@ -206,8 +172,17 @@ public class RequestEntity {
     return clusterId;
   }
 
+  public Collection<RequestResourceFilterEntity> getResourceFilterEntities() {
+    return resourceFilterEntities;
+  }
+
+  public void setResourceFilterEntities(Collection<RequestResourceFilterEntity> resourceFilterEntities) {
+    this.resourceFilterEntities = resourceFilterEntities;
+  }
+
   public void setClusterId(Long clusterId) {
     this.clusterId = clusterId;
+
   }
 
   public String getCommandName() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestResourceFilterEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestResourceFilterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestResourceFilterEntity.java
new file mode 100644
index 0000000..e03b3b6
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RequestResourceFilterEntity.java
@@ -0,0 +1,94 @@
+/*
+ * 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.orm.entities;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "requestresourcefilter")
+public class RequestResourceFilterEntity {
+
+  @Column(name = "request_id", nullable = false, insertable = true, updatable = true)
+  @Id
+  private Long requestId;
+
+  @Column(name = "service")
+  @Basic
+  @Id
+  private String serviceName;
+
+  @Column(name = "component")
+  @Basic
+  @Id
+  private String componentName;
+
+  @Column(name = "hosts")
+  @Lob
+  private String hosts;
+
+  @ManyToOne
+  @JoinColumn(name = "request_id", referencedColumnName = "request_id", nullable = false, insertable = false, updatable = false)
+  private RequestEntity requestEntity;
+
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  public void setServiceName(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public void setComponentName(String componentName) {
+    this.componentName = componentName;
+  }
+
+  public String getHosts() {
+    return hosts;
+  }
+
+  public void setHosts(String hosts) {
+    this.hosts = hosts;
+  }
+
+  public Long getRequestId() {
+    return requestId;
+  }
+
+  public void setRequestId(Long requestId) {
+    this.requestId = requestId;
+  }
+
+  public RequestEntity getRequestEntity() {
+    return requestEntity;
+  }
+
+  public void setRequestEntity(RequestEntity request) {
+    this.requestEntity = request;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
index f104259..33e49ac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
@@ -200,6 +200,15 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog {
 
     dbAccessor.createTable("hostgroup_component", columns, "blueprint_name", "hostgroup_name", "name");
 
+    // RequestResourceFilter
+    columns.clear();
+    columns.add(new DBColumnInfo("request_id", Long.class, null, null, false));
+    columns.add(new DBColumnInfo("service_name", String.class, 255, null, true));
+    columns.add(new DBColumnInfo("component_name", String.class, 255, null, true));
+    columns.add(new DBColumnInfo("hosts", byte[].class, null, null, true));
+
+    dbAccessor.createTable("requestresourcefilter", columns, "request_id", "service_name", "component_name");
+
     createQuartzTables();
 
     // ========================================================================
@@ -249,6 +258,7 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog {
     dbAccessor.addFKConstraint("confgrouphostmapping", "FK_cghostm_configgroup_id", "config_group_id", "configgroup", "group_id", true);
     dbAccessor.addFKConstraint("confgrouphostmapping", "FK_cghostm_host_name", "host_name", "hosts", "host_name", true);
     dbAccessor.addFKConstraint("clusterconfigmapping", "FK_clustercfgmap_cluster_id", "cluster_id", "clusters", "cluster_id", true);
+    dbAccessor.addFKConstraint("requestresourcefilter", "FK_requestresourcefilter_req_id", "request_id", "request", "request_id", true);
 
     // ========================================================================
     // Finally update schema version

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index 2e97b08..2224a85 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -42,7 +42,8 @@ CREATE TABLE execution_command (task_id BIGINT NOT NULL, command LONGBLOB, PRIMA
 CREATE TABLE host_role_command (task_id BIGINT NOT NULL, attempt_count SMALLINT NOT NULL, event LONGTEXT NOT NULL, exitcode INTEGER NOT NULL, host_name VARCHAR(255) NOT NULL, last_attempt_time BIGINT NOT NULL, request_id BIGINT NOT NULL, role VARCHAR(255), role_command VARCHAR(255), stage_id BIGINT NOT NULL, start_time BIGINT NOT NULL, end_time BIGINT, status VARCHAR(255), std_error LONGBLOB, std_out LONGBLOB, structured_out LONGBLOB, command_detail VARCHAR(255), custom_command_name VARCHAR(255), PRIMARY KEY (task_id));
 CREATE TABLE role_success_criteria (role VARCHAR(255) NOT NULL, request_id BIGINT NOT NULL, stage_id BIGINT NOT NULL, success_factor DOUBLE NOT NULL, PRIMARY KEY (role, request_id, stage_id));
 CREATE TABLE stage (stage_id BIGINT NOT NULL, request_id BIGINT NOT NULL, cluster_id BIGINT, log_info VARCHAR(255) NOT NULL, request_context VARCHAR(255), cluster_host_info LONGBLOB, PRIMARY KEY (stage_id, request_id));
-CREATE TABLE request (request_id BIGINT NOT NULL, cluster_id BIGINT, request_schedule_id BIGINT, command_name VARCHAR(255), create_time BIGINT NOT NULL, end_time BIGINT NOT NULL, inputs LONGTEXT, request_context VARCHAR(255), request_type VARCHAR(255), start_time BIGINT NOT NULL, status VARCHAR(255), target_component VARCHAR(255), target_hosts LONGTEXT, target_service VARCHAR(255), PRIMARY KEY (request_id));
+CREATE TABLE request (request_id BIGINT NOT NULL, cluster_id BIGINT, request_schedule_id BIGINT, command_name VARCHAR(255), create_time BIGINT NOT NULL, end_time BIGINT NOT NULL, inputs LONGTEXT, request_context VARCHAR(255), request_type VARCHAR(255), start_time BIGINT NOT NULL, status VARCHAR(255), PRIMARY KEY (request_id));
+CREATE TABLE requestresourcefilter (request_id BIGINT NOT NULL, service_name VARCHAR(255), component_name VARCHAR(255), hosts LONGTEXT, PRIMARY KEY (request_id, service_name, component_name));
 CREATE TABLE key_value_store (`key` VARCHAR(255), `value` LONGTEXT, PRIMARY KEY (`key`));
 CREATE TABLE clusterconfigmapping (type_name VARCHAR(255) NOT NULL, create_timestamp BIGINT NOT NULL, cluster_id BIGINT NOT NULL, selected INTEGER NOT NULL DEFAULT 0, version_tag VARCHAR(255) NOT NULL, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY (type_name, create_timestamp, cluster_id));
 CREATE TABLE hostconfigmapping (create_timestamp BIGINT NOT NULL, host_name VARCHAR(255) NOT NULL, cluster_id BIGINT NOT NULL, type_name VARCHAR(255) NOT NULL, selected INTEGER NOT NULL DEFAULT 0, service_name VARCHAR(255), version_tag VARCHAR(255) NOT NULL, user_name VARCHAR(255) NOT NULL DEFAULT '_db', PRIMARY KEY (create_timestamp, host_name, cluster_id, type_name));
@@ -93,6 +94,7 @@ ALTER TABLE configgrouphostmapping ADD CONSTRAINT FK_configgrouphostmapping_host
 ALTER TABLE requestschedulebatchrequest ADD CONSTRAINT FK_requestschedulebatchrequest_schedule_id FOREIGN KEY (schedule_id) REFERENCES ambari.requestschedule (schedule_id);
 ALTER TABLE hostgroup ADD FOREIGN KEY (blueprint_name) REFERENCES blueprint(blueprint_name);
 ALTER TABLE hostgroup_component ADD FOREIGN KEY (blueprint_name, hostgroup_name) REFERENCES hostgroup(blueprint_name, name);
+ALTER TABLE requestresourcefilter ADD CONSTRAINT FK_requestresourcefilter_req_id FOREIGN KEY (request_id) REFERENCES request (request_id);
 
 
 INSERT INTO ambari_sequences(sequence_name, value) values ('cluster_id_seq', 1);

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index e0e6927..637a149 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -32,7 +32,8 @@ CREATE TABLE execution_command (task_id NUMBER(19) NOT NULL, command BLOB NULL,
 CREATE TABLE host_role_command (task_id NUMBER(19) NOT NULL, attempt_count NUMBER(5) NOT NULL, event CLOB NULL, exitcode NUMBER(10) NOT NULL, host_name VARCHAR2(255) NOT NULL, last_attempt_time NUMBER(19) NOT NULL, request_id NUMBER(19) NOT NULL, role VARCHAR2(255) NULL, role_command VARCHAR2(255) NULL, stage_id NUMBER(19) NOT NULL, start_time NUMBER(19) NOT NULL, end_time NUMBER(19), status VARCHAR2(255) NULL, std_error BLOB NULL, std_out BLOB NULL, structured_out BLOB NULL,  command_detail VARCHAR2(255) NULL, custom_command_name VARCHAR2(255) NULL, PRIMARY KEY (task_id));
 CREATE TABLE role_success_criteria (role VARCHAR2(255) NOT NULL, request_id NUMBER(19) NOT NULL, stage_id NUMBER(19) NOT NULL, success_factor NUMBER(19,4) NOT NULL, PRIMARY KEY (role, request_id, stage_id));
 CREATE TABLE stage (stage_id NUMBER(19) NOT NULL, request_id NUMBER(19) NOT NULL, cluster_id NUMBER(19) NULL, log_info VARCHAR2(255) NULL, request_context VARCHAR2(255) NULL, cluster_host_info BLOB NOT NULL, PRIMARY KEY (stage_id, request_id));
-CREATE TABLE request (request_id NUMBER(19) NOT NULL, cluster_id NUMBER(19), request_schedule_id NUMBER(19), command_name VARCHAR(255), create_time NUMBER(19) NOT NULL, end_time NUMBER(19) NOT NULL, inputs CLOB, request_context VARCHAR(255), request_type VARCHAR(255), start_time NUMBER(19) NOT NULL, status VARCHAR(255), target_component VARCHAR(255), target_hosts CLOB, target_service VARCHAR(255), PRIMARY KEY (request_id));
+CREATE TABLE request (request_id NUMBER(19) NOT NULL, cluster_id NUMBER(19), request_schedule_id NUMBER(19), command_name VARCHAR(255), create_time NUMBER(19) NOT NULL, end_time NUMBER(19) NOT NULL, inputs CLOB, request_context VARCHAR(255), request_type VARCHAR(255), start_time NUMBER(19) NOT NULL, status VARCHAR(255), PRIMARY KEY (request_id));
+CREATE TABLE requestresourcefilter (request_id NUMBER(19) NOT NULL, service_name VARCHAR2(255), component_name VARCHAR2(255), hosts CLOB, PRIMARY KEY (request_id, service_name, component_name));
 CREATE TABLE key_value_store ("key" VARCHAR2(255) NOT NULL, "value" CLOB NULL, PRIMARY KEY ("key"));
 CREATE TABLE clusterconfigmapping (type_name VARCHAR2(255) NOT NULL, create_timestamp NUMBER(19) NOT NULL, cluster_id NUMBER(19) NOT NULL, selected NUMBER(10) NOT NULL, version_tag VARCHAR2(255) NOT NULL, user_name VARCHAR(255) DEFAULT '_db', PRIMARY KEY (type_name, create_timestamp, cluster_id));
 CREATE TABLE hostconfigmapping (create_timestamp NUMBER(19) NOT NULL, host_name VARCHAR2(255) NOT NULL, cluster_id NUMBER(19) NOT NULL, type_name VARCHAR2(255) NOT NULL, selected NUMBER(10) NOT NULL, service_name VARCHAR2(255) NULL, version_tag VARCHAR2(255) NOT NULL, user_name VARCHAR(255) DEFAULT '_db', PRIMARY KEY (create_timestamp, host_name, cluster_id, type_name));
@@ -81,6 +82,7 @@ ALTER TABLE configgrouphostmapping ADD CONSTRAINT FK_cghm_hname FOREIGN KEY (hos
 ALTER TABLE requestschedulebatchrequest ADD CONSTRAINT FK_rsbatchrequest_schedule_id FOREIGN KEY (schedule_id) REFERENCES requestschedule (schedule_id);
 ALTER TABLE hostgroup ADD FOREIGN KEY (blueprint_name) REFERENCES ambari.blueprint(blueprint_name);
 ALTER TABLE hostgroup_component ADD FOREIGN KEY (blueprint_name, hostgroup_name) REFERENCES ambari.hostgroup(blueprint_name, name);
+ALTER TABLE requestresourcefilter ADD CONSTRAINT FK_requestresourcefilter_req_id FOREIGN KEY (request_id) REFERENCES request (request_id);
 
 INSERT INTO ambari_sequences(sequence_name, value) values ('host_role_command_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, value) values ('user_id_seq', 1);

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 60462e2..3db04b4 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -79,7 +79,10 @@ GRANT ALL PRIVILEGES ON TABLE ambari.role_success_criteria TO :username;
 CREATE TABLE ambari.stage (stage_id BIGINT NOT NULL, request_id BIGINT NOT NULL, cluster_id BIGINT NOT NULL, log_info VARCHAR(255) NOT NULL, request_context VARCHAR(255), cluster_host_info BYTEA NOT NULL, PRIMARY KEY (stage_id, request_id));
 GRANT ALL PRIVILEGES ON TABLE ambari.stage TO :username;
 
-CREATE TABLE ambari.request (request_id BIGINT NOT NULL, cluster_id BIGINT, command_name VARCHAR(255), create_time BIGINT NOT NULL, end_time BIGINT NOT NULL, inputs VARCHAR(32000), request_context VARCHAR(255), request_type VARCHAR(255), request_schedule_id BIGINT, start_time BIGINT NOT NULL, status VARCHAR(255), target_component VARCHAR(255), target_hosts TEXT, target_service VARCHAR(255), PRIMARY KEY (request_id));
+CREATE TABLE ambari.request (request_id BIGINT NOT NULL, cluster_id BIGINT, command_name VARCHAR(255), create_time BIGINT NOT NULL, end_time BIGINT NOT NULL, inputs VARCHAR(32000), request_context VARCHAR(255), request_type VARCHAR(255), request_schedule_id BIGINT, start_time BIGINT NOT NULL, status VARCHAR(255), PRIMARY KEY (request_id));
+GRANT ALL PRIVILEGES ON TABLE ambari.request TO :username;
+
+CREATE TABLE ambari.requestresourcefilter (request_id BIGINT NOT NULL, service_name VARCHAR(255), component_name VARCHAR(255), hosts TEXT, PRIMARY KEY (request_id, service_name, component_name));
 GRANT ALL PRIVILEGES ON TABLE ambari.request TO :username;
 
 CREATE TABLE ambari.ClusterHostMapping (cluster_id BIGINT NOT NULL, host_name VARCHAR(255) NOT NULL, PRIMARY KEY (cluster_id, host_name));
@@ -98,7 +101,6 @@ CREATE TABLE ambari.metainfo ("metainfo_key" VARCHAR(255), "metainfo_value" VARC
 GRANT ALL PRIVILEGES ON TABLE ambari.metainfo TO :username;
 
 CREATE TABLE ambari.ambari_sequences (sequence_name VARCHAR(255) PRIMARY KEY, "value" BIGINT NOT NULL);
-
 GRANT ALL PRIVILEGES ON TABLE ambari.ambari_sequences TO :username;
 
 CREATE TABLE ambari.configgroup (group_id BIGINT, cluster_id BIGINT NOT NULL, group_name VARCHAR(255) NOT NULL, tag VARCHAR(1024) NOT NULL, description VARCHAR(1024), create_timestamp BIGINT NOT NULL, PRIMARY KEY(group_id));
@@ -157,6 +159,7 @@ ALTER TABLE ambari.configgrouphostmapping ADD CONSTRAINT FK_configgrouphostmappi
 ALTER TABLE ambari.requestschedulebatchrequest ADD CONSTRAINT FK_requestschedulebatchrequest_schedule_id FOREIGN KEY (schedule_id) REFERENCES ambari.requestschedule (schedule_id);
 ALTER TABLE ambari.hostgroup ADD FOREIGN KEY (blueprint_name) REFERENCES ambari.blueprint(blueprint_name);
 ALTER TABLE ambari.hostgroup_component ADD FOREIGN KEY (blueprint_name, hostgroup_name) REFERENCES ambari.hostgroup(blueprint_name, name);
+ALTER TABLE ambari.requestresourcefilter ADD CONSTRAINT FK_requestresourcefilter_req_id FOREIGN KEY (request_id) REFERENCES ambari.request (request_id);
 
 
 ---------inserting some data-----------

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index c85d79d..b6c1bd9 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -38,12 +38,12 @@
     <class>org.apache.ambari.server.orm.entities.ConfigGroupEntity</class>
     <class>org.apache.ambari.server.orm.entities.ConfigGroupConfigMappingEntity</class>
     <class>org.apache.ambari.server.orm.entities.ConfigGroupHostMappingEntity</class>
-    <class>org.apache.ambari.server.orm.entities.ActionEntity</class>
     <class>org.apache.ambari.server.orm.entities.RequestScheduleEntity</class>
     <class>org.apache.ambari.server.orm.entities.RequestScheduleBatchRequestEntity</class>
     <class>org.apache.ambari.server.orm.entities.BlueprintEntity</class>
     <class>org.apache.ambari.server.orm.entities.HostGroupEntity</class>
     <class>org.apache.ambari.server.orm.entities.HostGroupComponentEntity</class>
+    <class>org.apache.ambari.server.orm.entities.RequestResourceFilterEntity</class>
 
     <properties>
       <!--<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/ambari" />-->

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index 270353b..d3987b5 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -103,9 +103,7 @@
         "Requests/request_schedule",
         "Requests/type",
         "Requests/inputs",
-        "Requests/target_service",
-        "Requests/target_component",
-        "Requests/target_hosts",
+        "Requests/resources",
         "Requests/create_time",
         "Requests/start_time",
         "Requests/end_time",

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6987eee/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
index d052673..344891d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
@@ -30,6 +30,7 @@ import org.apache.ambari.server.agent.ActionQueue;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.controller.ExecuteActionRequest;
 import org.apache.ambari.server.controller.HostsMap;
+import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.ExecutionCommandDAO;
@@ -366,8 +367,11 @@ public class TestActionDBAccessorImpl {
             hostname, System.currentTimeMillis()), "cluster1", "HBASE");
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
-    ExecuteActionRequest executeActionRequest = new ExecuteActionRequest("cluster1", null, actionName, "HBASE",
-        "HBASE_MASTER", null, null);
+    final RequestResourceFilter resourceFilter = new RequestResourceFilter("HBASE", "HBASE_MASTER", null);
+    List<RequestResourceFilter> resourceFilters = new
+      ArrayList<RequestResourceFilter>() {{ add(resourceFilter); }};
+    ExecuteActionRequest executeActionRequest = new ExecuteActionRequest
+      ("cluster1", null, actionName, resourceFilters, null);
     Request request = new Request(stages, clusters);
     db.persistActions(request);
   }