You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2015/10/21 05:42:39 UTC

[1/2] ambari git commit: AMBARI-13441. If Ambari Server is not part of the cluster, basic operations throw 500 (NPE) when Kerberos is enabled (even if it is Manual Kerberos) (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 d2dc26350 -> 24ce16b5a


http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
index 73b1649..f8f9ce9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
@@ -46,10 +46,6 @@ import java.util.TreeMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import com.google.inject.Inject;
-import com.google.inject.persist.PersistService;
-import junit.framework.Assert;
-
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
@@ -98,9 +94,13 @@ import org.slf4j.LoggerFactory;
 import com.google.common.reflect.TypeToken;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
+import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
 import com.google.inject.persist.UnitOfWork;
 
+import junit.framework.Assert;
+
 public class TestActionScheduler {
 
   private static final Logger log = LoggerFactory.getLogger(TestActionScheduler.class);
@@ -113,7 +113,6 @@ public class TestActionScheduler {
 
   private static Injector injector;
 
-  private final String serverHostname = StageUtils.getHostName();
   private final String hostname = "ahost.ambari.apache.org";
   private final int MAX_CYCLE_ITERATIONS = 100;
 
@@ -291,9 +290,9 @@ public class TestActionScheduler {
     when(request.isExclusive()).thenReturn(false);
     when(db.getRequestEntity(anyLong())).thenReturn(request);
 
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         HostRoleCommand command = s.getHostRoleCommand(host, role);
@@ -371,9 +370,9 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         HostRoleCommand command = s.getHostRoleCommand(host, role);
@@ -466,9 +465,9 @@ public class TestActionScheduler {
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
 
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         //HostRoleCommand command = stages.get(0).getHostRoleCommand(host, role);
@@ -482,9 +481,9 @@ public class TestActionScheduler {
       }
     }).when(db).timeoutHostRole(anyString(), anyLong(), anyLong(), anyString());
 
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         Long requestId = (Long) invocation.getArguments()[0];
         for (Stage stage : stages) {
           if (requestId.equals(stage.getRequestId())) {
@@ -564,27 +563,7 @@ public class TestActionScheduler {
     Properties properties = new Properties();
     Configuration conf = new Configuration(properties);
     Clusters fsm = mock(Clusters.class);
-    Cluster oneClusterMock = mock(Cluster.class);
-    Service serviceObj = mock(Service.class);
-    ServiceComponent scomp = mock(ServiceComponent.class);
-    ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    Host host = mock(Host.class);
-
-    when(host.getHostName()).thenReturn(serverHostname);
-    when(host.getState()).thenReturn(HostState.HEALTHY);
-
-    when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
-    when(fsm.getHost(anyString())).thenReturn(host);
-    when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
-    when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
-    when(scomp.getServiceComponentHost(anyString())).thenReturn(sch);
-    when(serviceObj.getCluster()).thenReturn(oneClusterMock);
-
-    HashMap<String, ServiceComponentHost> hosts =
-            new HashMap<String, ServiceComponentHost>();
-    hosts.put(serverHostname, sch);
-    when(scomp.getServiceComponentHosts()).thenReturn(hosts);
 
     List<Stage> stages = new ArrayList<Stage>();
     Map<String, String> payload = new HashMap<String, String>();
@@ -599,37 +578,44 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         CommandReport commandReport = (CommandReport) invocation.getArguments()[4];
-        HostRoleCommand command = s.getHostRoleCommand(host, role);
+
+        HostRoleCommand command = null;
+        if (null == host) {
+          command = s.getHostRoleCommand(null, role);
+        } else {
+          command = s.getHostRoleCommand(host, role);
+        }
+
         command.setStatus(HostRoleStatus.valueOf(commandReport.getStatus()));
         return null;
       }
     }).when(db).updateHostRoleState(anyString(), anyLong(), anyLong(), anyString(), any(CommandReport.class));
 
-    doAnswer(new Answer() {
+    doAnswer(new Answer<HostRoleCommand>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        return s.getHostRoleCommand(serverHostname, "AMBARI_SERVER_ACTION");
+      public HostRoleCommand answer(InvocationOnMock invocation) throws Throwable {
+        return s.getHostRoleCommand(null, "AMBARI_SERVER_ACTION");
       }
     }).when(db).getTask(anyLong());
-    doAnswer(new Answer() {
+
+    doAnswer(new Answer<List<HostRoleCommand>>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        String host = (String) invocation.getArguments()[0];
+      public List<HostRoleCommand> answer(InvocationOnMock invocation) throws Throwable {
         String role = (String) invocation.getArguments()[1];
         HostRoleStatus status = (HostRoleStatus) invocation.getArguments()[2];
 
-        HostRoleCommand task = s.getHostRoleCommand(host, role);
+        HostRoleCommand task = s.getHostRoleCommand(null, role);
 
         if (task.getStatus() == status) {
           return Arrays.asList(task);
         } else {
-          return null;
+          return Collections.emptyList();
         }
       }
     }).when(db).getTasksByHostRoleAndStatus(anyString(), anyString(), any(HostRoleStatus.class));
@@ -639,13 +625,13 @@ public class TestActionScheduler {
         new HostsMap((String) null), unitOfWork, null, conf);
 
     int cycleCount = 0;
-    while (!stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION")
+    while (!stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION")
         .equals(HostRoleStatus.COMPLETED) && cycleCount++ <= MAX_CYCLE_ITERATIONS) {
       scheduler.doWork();
       scheduler.getServerActionExecutor().doWork();
     }
 
-    assertEquals(stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION"),
+    assertEquals(stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION"),
         HostRoleStatus.COMPLETED);
   }
 
@@ -658,26 +644,7 @@ public class TestActionScheduler {
     Properties properties = new Properties();
     Configuration conf = new Configuration(properties);
     Clusters fsm = mock(Clusters.class);
-    Cluster oneClusterMock = mock(Cluster.class);
-    Service serviceObj = mock(Service.class);
-    ServiceComponent scomp = mock(ServiceComponent.class);
-    ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
-    when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
-    when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
-    when(scomp.getServiceComponentHost(anyString())).thenReturn(sch);
-    when(serviceObj.getCluster()).thenReturn(oneClusterMock);
-
-    Host host = mock(Host.class);
-    HashMap<String, ServiceComponentHost> hosts =
-            new HashMap<String, ServiceComponentHost>();
-    hosts.put(serverHostname, sch);
-    when(scomp.getServiceComponentHosts()).thenReturn(hosts);
-
-    when(fsm.getHost(anyString())).thenReturn(host);
-    when(host.getState()).thenReturn(HostState.HEALTHY);
-    when(host.getHostName()).thenReturn(serverHostname);
 
     List<Stage> stages = new ArrayList<Stage>();
     Map<String, String> payload = new HashMap<String, String>();
@@ -693,38 +660,46 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         CommandReport commandReport = (CommandReport) invocation.getArguments()[4];
-        HostRoleCommand command = s.getHostRoleCommand(host, role);
+
+        HostRoleCommand command = null;
+        if (null == host) {
+          command = s.getHostRoleCommand(null, role);
+        } else {
+          command = s.getHostRoleCommand(host, role);
+        }
+
         command.setStatus(HostRoleStatus.valueOf(commandReport.getStatus()));
         return null;
       }
     }).when(db).updateHostRoleState(anyString(), anyLong(), anyLong(), anyString(), any(CommandReport.class));
 
-    doAnswer(new Answer() {
+    doAnswer(new Answer<HostRoleCommand>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        return s.getHostRoleCommand(serverHostname, "AMBARI_SERVER_ACTION");
+      public HostRoleCommand answer(InvocationOnMock invocation) throws Throwable {
+        return s.getHostRoleCommand(null, "AMBARI_SERVER_ACTION");
       }
     }).when(db).getTask(anyLong());
-    doAnswer(new Answer() {
+
+    doAnswer(new Answer<List<HostRoleCommand>>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        String host = (String) invocation.getArguments()[0];
+      public List<HostRoleCommand> answer(InvocationOnMock invocation) throws Throwable {
         String role = (String) invocation.getArguments()[1];
         HostRoleStatus status = (HostRoleStatus) invocation.getArguments()[2];
 
-        HostRoleCommand task = s.getHostRoleCommand(host, role);
+        HostRoleCommand task = s.getHostRoleCommand(null, role);
 
         if (task.getStatus() == status) {
           return Arrays.asList(task);
         } else {
-          return null;
+          return Collections.emptyList();
         }
+
       }
     }).when(db).getTasksByHostRoleAndStatus(anyString(), anyString(), any(HostRoleStatus.class));
 
@@ -733,14 +708,14 @@ public class TestActionScheduler {
         new HostsMap((String) null), unitOfWork, null, conf);
 
     int cycleCount = 0;
-    while (!stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION").isCompletedState()
+    while (!stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION").isCompletedState()
         && cycleCount++ <= MAX_CYCLE_ITERATIONS) {
       scheduler.doWork();
       scheduler.getServerActionExecutor().doWork();
     }
 
     assertEquals(HostRoleStatus.TIMEDOUT,
-        stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION"));
+        stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION"));
   }
 
   @Test
@@ -749,21 +724,7 @@ public class TestActionScheduler {
     Properties properties = new Properties();
     Configuration conf = new Configuration(properties);
     Clusters fsm = mock(Clusters.class);
-    Cluster oneClusterMock = mock(Cluster.class);
-    Service serviceObj = mock(Service.class);
-    ServiceComponent scomp = mock(ServiceComponent.class);
-    ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
-    when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
-    when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
-    when(scomp.getServiceComponentHost(anyString())).thenReturn(sch);
-    when(serviceObj.getCluster()).thenReturn(oneClusterMock);
-
-    HashMap<String, ServiceComponentHost> hosts =
-            new HashMap<String, ServiceComponentHost>();
-    hosts.put(serverHostname, sch);
-    when(scomp.getServiceComponentHosts()).thenReturn(hosts);
 
     List<Stage> stages = new ArrayList<Stage>();
     Map<String, String> payload = new HashMap<String, String>();
@@ -779,37 +740,45 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         CommandReport commandReport = (CommandReport) invocation.getArguments()[4];
-        HostRoleCommand command = s.getHostRoleCommand(host, role);
+
+        HostRoleCommand command = null;
+        if (null == host) {
+          command = s.getHostRoleCommand(null, role);
+        } else {
+          command = s.getHostRoleCommand(host, role);
+        }
+
         command.setStatus(HostRoleStatus.valueOf(commandReport.getStatus()));
         return null;
       }
     }).when(db).updateHostRoleState(anyString(), anyLong(), anyLong(), anyString(), any(CommandReport.class));
 
-    doAnswer(new Answer() {
+    doAnswer(new Answer<HostRoleCommand>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        return s.getHostRoleCommand(serverHostname, "AMBARI_SERVER_ACTION");
+      public HostRoleCommand answer(InvocationOnMock invocation) throws Throwable {
+        return s.getHostRoleCommand(null, "AMBARI_SERVER_ACTION");
       }
     }).when(db).getTask(anyLong());
-    doAnswer(new Answer() {
+
+    doAnswer(new Answer<List<HostRoleCommand>>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        String host = (String) invocation.getArguments()[0];
+      public List<HostRoleCommand> answer(InvocationOnMock invocation) throws Throwable {
         String role = (String) invocation.getArguments()[1];
         HostRoleStatus status = (HostRoleStatus) invocation.getArguments()[2];
 
-        HostRoleCommand task = s.getHostRoleCommand(host, role);
+        HostRoleCommand task = s.getHostRoleCommand(null, role);
 
         if (task.getStatus() == status) {
           return Arrays.asList(task);
         } else {
-          return null;
+          return Collections.emptyList();
         }
       }
     }).when(db).getTasksByHostRoleAndStatus(anyString(), anyString(), any(HostRoleStatus.class));
@@ -818,12 +787,12 @@ public class TestActionScheduler {
         new HostsMap((String) null), unitOfWork, null, conf);
 
     int cycleCount = 0;
-    while (!stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION")
+    while (!stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION")
         .equals(HostRoleStatus.FAILED) && cycleCount++ <= MAX_CYCLE_ITERATIONS) {
       scheduler.doWork();
       scheduler.getServerActionExecutor().doWork();
     }
-    assertEquals(stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION"),
+    assertEquals(stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION"),
         HostRoleStatus.FAILED);
     assertEquals("test", stages.get(0).getRequestContext());
   }
@@ -831,14 +800,15 @@ public class TestActionScheduler {
   private Stage getStageWithServerAction(long requestId, long stageId,
                                                 Map<String, String> payload, String requestContext,
                                                 int timeout) {
-    String serverHostname = StageUtils.getHostName();
+
     Stage stage = stageFactory.createNew(requestId, "/tmp", "cluster1", 1L, requestContext, CLUSTER_HOST_INFO,
       "{}", "{}");
     stage.setStageId(stageId);
 
-    stage.addServerActionCommand(MockServerAction.class.getName(), Role.AMBARI_SERVER_ACTION,
+    stage.addServerActionCommand(MockServerAction.class.getName(), null,
+        Role.AMBARI_SERVER_ACTION,
         RoleCommand.EXECUTE, "cluster1",
-        new ServiceComponentHostServerActionEvent(serverHostname, System.currentTimeMillis()),
+        new ServiceComponentHostServerActionEvent(null, System.currentTimeMillis()),
         payload,
         null, null, timeout, false, false);
 
@@ -859,7 +829,6 @@ public class TestActionScheduler {
     ServiceComponent scomp = mock(ServiceComponent.class);
     ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    RequestFactory requestFactory = mock(RequestFactory.class);
     when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
     when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
     when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
@@ -917,10 +886,6 @@ public class TestActionScheduler {
     ActionScheduler scheduler = new ActionScheduler(100, 50, db, aq, fsm, 3,
             new HostsMap((String) null), unitOfWork, null, conf);
 
-    ActionManager am = new ActionManager(
-        2, 2, aq, fsm, db, new HostsMap((String) null),
-        unitOfWork, requestFactory, conf, null);
-
     scheduler.doWork();
 
     Assert.assertEquals(HostRoleStatus.QUEUED, stages.get(0).getHostRoleStatus(hostname1, "DATANODE"));
@@ -943,7 +908,6 @@ public class TestActionScheduler {
     ServiceComponent scomp = mock(ServiceComponent.class);
     ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    RequestFactory requestFactory = mock(RequestFactory.class);
     when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
     when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
     when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
@@ -1011,11 +975,6 @@ public class TestActionScheduler {
             new HostsMap((String) null),
             unitOfWork, null, conf);
 
-    ActionManager am = new ActionManager(
-        2, 2, aq, fsm, db, new HostsMap((String) null),
-        unitOfWork,
-        requestFactory, conf, null);
-
     scheduler.doWork();
 
     Assert.assertEquals(HostRoleStatus.QUEUED, stages.get(0).getHostRoleStatus(hostname1, "HIVE_CLIENT"));
@@ -1038,7 +997,6 @@ public class TestActionScheduler {
     ServiceComponent scomp = mock(ServiceComponent.class);
     ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    RequestFactory requestFactory = mock(RequestFactory.class);
     when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
     when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
     when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
@@ -1088,11 +1046,6 @@ public class TestActionScheduler {
         new HostsMap((String) null),
         unitOfWork, null, conf);
 
-    ActionManager am = new ActionManager(
-        2, 2, aq, fsm, db, new HostsMap((String) null),
-        unitOfWork,
-        requestFactory, conf, null);
-
     scheduler.doWork();
 
     Assert.assertEquals(HostRoleStatus.QUEUED, stages.get(0).getHostRoleStatus(hostname1, "NAMENODE"));
@@ -1143,16 +1096,15 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         List<CommandReport> reports = (List<CommandReport>) invocation.getArguments()[0];
         for (CommandReport report : reports) {
           String actionId = report.getActionId();
           long[] requestStageIds = StageUtils.getRequestStage(actionId);
           Long requestId = requestStageIds[0];
           Long stageId = requestStageIds[1];
-          String role = report.getRole();
           Long id = report.getTaskId();
           for (Stage stage : stages) {
             if (requestId.equals(stage.getRequestId()) && stageId.equals(stage.getStageId())) {
@@ -1184,9 +1136,9 @@ public class TestActionScheduler {
         return null;
       }
     });
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         Long requestId = (Long) invocation.getArguments()[0];
         for (Stage stage : stages) {
           if (requestId.equals(stage.getRequestId())) {
@@ -1251,7 +1203,6 @@ public class TestActionScheduler {
     ServiceComponent scomp = mock(ServiceComponent.class);
     ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    RequestFactory requestFactory = mock(RequestFactory.class);
     when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
     when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
     when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
@@ -1332,9 +1283,9 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         Long requestId = (Long) invocation.getArguments()[1];
         Long stageId = (Long) invocation.getArguments()[2];
@@ -1365,9 +1316,9 @@ public class TestActionScheduler {
         return null;
       }
     });
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         Long requestId = (Long) invocation.getArguments()[0];
         for (Stage stage : stages) {
           if (requestId.equals(stage.getRequestId())) {
@@ -1390,8 +1341,6 @@ public class TestActionScheduler {
     ActionScheduler scheduler = new ActionScheduler(100, 10000, db, aq, fsm, 3,
         new HostsMap((String) null),
         unitOfWork, null, conf);
-    ActionManager am = new ActionManager(
-        2, 10000, aq, fsm, db, new HostsMap((String) null), unitOfWork, requestFactory, conf, null);
 
     scheduler.doWork();
 
@@ -1511,16 +1460,15 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         List<CommandReport> reports = (List<CommandReport>) invocation.getArguments()[0];
         for (CommandReport report : reports) {
           String actionId = report.getActionId();
           long[] requestStageIds = StageUtils.getRequestStage(actionId);
           Long requestId = requestStageIds[0];
           Long stageId = requestStageIds[1];
-          String role = report.getRole();
           Long id = report.getTaskId();
           for (Stage stage : stages) {
             if (requestId.equals(stage.getRequestId()) && stageId.equals(stage.getStageId())) {
@@ -1552,9 +1500,9 @@ public class TestActionScheduler {
         return null;
       }
     });
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         Long requestId = (Long) invocation.getArguments()[0];
         for (Stage stage : stages) {
           if (requestId.equals(stage.getRequestId())) {
@@ -1882,26 +1830,11 @@ public class TestActionScheduler {
     Properties properties = new Properties();
     Configuration conf = new Configuration(properties);
     Clusters fsm = mock(Clusters.class);
-    Cluster oneClusterMock = mock(Cluster.class);
-    Service serviceObj = mock(Service.class);
-    ServiceComponent scomp = mock(ServiceComponent.class);
-    ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
-    when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
-    when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
-    when(scomp.getServiceComponentHost(anyString())).thenReturn(sch);
-    when(serviceObj.getCluster()).thenReturn(oneClusterMock);
-
-    HashMap<String, ServiceComponentHost> hosts =
-            new HashMap<String, ServiceComponentHost>();
-    hosts.put(serverHostname, sch);
-    when(scomp.getServiceComponentHosts()).thenReturn(hosts);
 
     List<Stage> stages = new ArrayList<Stage>();
     Map<String, String> payload = new HashMap<String, String>();
     final Stage s = getStageWithServerAction(1, 977, payload, "test", 300);
-    s.getExecutionCommands().get(serverHostname).get(0).getExecutionCommand().setServiceName(null);
     stages.add(s);
 
     ActionDBAccessor db = mock(ActionDBAccessor.class);
@@ -1912,37 +1845,45 @@ public class TestActionScheduler {
 
     when(db.getCommandsInProgressCount()).thenReturn(stages.size());
     when(db.getStagesInProgress()).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         String host = (String) invocation.getArguments()[0];
         String role = (String) invocation.getArguments()[3];
         CommandReport commandReport = (CommandReport) invocation.getArguments()[4];
-        HostRoleCommand command = s.getHostRoleCommand(host, role);
+
+        HostRoleCommand command = null;
+        if (null == host) {
+          command = s.getHostRoleCommand(null, role);
+        } else {
+          command = s.getHostRoleCommand(host, role);
+        }
+
         command.setStatus(HostRoleStatus.valueOf(commandReport.getStatus()));
         return null;
       }
     }).when(db).updateHostRoleState(anyString(), anyLong(), anyLong(), anyString(), any(CommandReport.class));
-    doAnswer(new Answer() {
+
+    doAnswer(new Answer<List<HostRoleCommand>>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        String host = (String) invocation.getArguments()[0];
+      public List<HostRoleCommand> answer(InvocationOnMock invocation) throws Throwable {
         String role = (String) invocation.getArguments()[1];
         HostRoleStatus status = (HostRoleStatus) invocation.getArguments()[2];
 
-        HostRoleCommand task = s.getHostRoleCommand(host, role);
+        HostRoleCommand task = s.getHostRoleCommand(null, role);
 
         if (task.getStatus() == status) {
           return Arrays.asList(task);
         } else {
-          return null;
+          return Collections.emptyList();
         }
       }
     }).when(db).getTasksByHostRoleAndStatus(anyString(), anyString(), any(HostRoleStatus.class));
-    doAnswer(new Answer() {
+
+    doAnswer(new Answer<HostRoleCommand>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        return s.getHostRoleCommand(serverHostname, "AMBARI_SERVER_ACTION");
+      public HostRoleCommand answer(InvocationOnMock invocation) throws Throwable {
+        return s.getHostRoleCommand(null, "AMBARI_SERVER_ACTION");
       }
     }).when(db).getTask(anyLong());
 
@@ -1951,13 +1892,13 @@ public class TestActionScheduler {
         new HostsMap((String) null), unitOfWork, null, conf);
 
     int cycleCount = 0;
-    while (!stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION")
+    while (!stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION")
         .equals(HostRoleStatus.COMPLETED) && cycleCount++ <= MAX_CYCLE_ITERATIONS) {
       scheduler.doWork();
       scheduler.getServerActionExecutor().doWork();
     }
 
-    assertEquals(stages.get(0).getHostRoleStatus(serverHostname, "AMBARI_SERVER_ACTION"),
+    assertEquals(stages.get(0).getHostRoleStatus(null, "AMBARI_SERVER_ACTION"),
             HostRoleStatus.COMPLETED);
   }
 
@@ -1970,7 +1911,6 @@ public class TestActionScheduler {
     ServiceComponent scomp = mock(ServiceComponent.class);
     ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    RequestFactory requestFactory = mock(RequestFactory.class);
     when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
     when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
     when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
@@ -2019,16 +1959,15 @@ public class TestActionScheduler {
     }
     when(db.getRequestTasks(anyLong())).thenReturn(requestTasks);
     when(db.getAllStages(anyLong())).thenReturn(stages);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         List<CommandReport> reports = (List<CommandReport>) invocation.getArguments()[0];
         for (CommandReport report : reports) {
           String actionId = report.getActionId();
           long[] requestStageIds = StageUtils.getRequestStage(actionId);
           Long requestId = requestStageIds[0];
           Long stageId = requestStageIds[1];
-          String role = report.getRole();
           Long id = report.getTaskId();
           for (Stage stage : stages) {
             if (requestId.equals(stage.getRequestId()) && stageId.equals(stage.getStageId())) {
@@ -2060,9 +1999,9 @@ public class TestActionScheduler {
         return null;
       }
     });
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         Long requestId = (Long) invocation.getArguments()[0];
         for (Stage stage : stages) {
           if (requestId.equals(stage.getRequestId())) {
@@ -2086,10 +2025,6 @@ public class TestActionScheduler {
     ActionScheduler scheduler = new ActionScheduler(100, 50, db, aq, fsm, 3,
         new HostsMap((String) null), unitOfWork, null, conf);
 
-    ActionManager am = new ActionManager(
-        2, 2, aq, fsm, db, new HostsMap((String) null),
-        unitOfWork, requestFactory, conf, null);
-
     scheduler.doWork();
 
     String reason = "Some reason";
@@ -2116,7 +2051,6 @@ public class TestActionScheduler {
     ServiceComponent scomp = mock(ServiceComponent.class);
     ServiceComponentHost sch = mock(ServiceComponentHost.class);
     UnitOfWork unitOfWork = mock(UnitOfWork.class);
-    RequestFactory requestFactory = mock(RequestFactory.class);
     when(fsm.getCluster(anyString())).thenReturn(oneClusterMock);
     when(oneClusterMock.getService(anyString())).thenReturn(serviceObj);
     when(serviceObj.getServiceComponent(anyString())).thenReturn(scomp);
@@ -2184,16 +2118,15 @@ public class TestActionScheduler {
     }
     when(db.getRequestTasks(anyLong())).thenReturn(requestTasks);
     when(db.getAllStages(anyLong())).thenReturn(stagesInProgress);
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         List<CommandReport> reports = (List<CommandReport>) invocation.getArguments()[0];
         for (CommandReport report : reports) {
           String actionId = report.getActionId();
           long[] requestStageIds = StageUtils.getRequestStage(actionId);
           Long requestId = requestStageIds[0];
           Long stageId = requestStageIds[1];
-          String role = report.getRole();
           Long id = report.getTaskId();
           for (Stage stage : stagesInProgress) {
             if (requestId.equals(stage.getRequestId()) && stageId.equals(stage.getStageId())) {
@@ -2227,9 +2160,9 @@ public class TestActionScheduler {
     });
 
     final Map<Long, Boolean> startedRequests = new HashMap<Long, Boolean>();
-    doAnswer(new Answer() {
+    doAnswer(new Answer<Void>() {
       @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
+      public Void answer(InvocationOnMock invocation) throws Throwable {
         startedRequests.put((Long)invocation.getArguments()[0], true);
         return null;
       }
@@ -2252,10 +2185,6 @@ public class TestActionScheduler {
     ActionScheduler scheduler = new ActionScheduler(100, 50, db, aq, fsm, 3,
         new HostsMap((String) null), unitOfWork, null, conf);
 
-    ActionManager am = new ActionManager(
-        2, 2, aq, fsm, db, new HostsMap((String) null),
-        unitOfWork, requestFactory, conf, null);
-
     // Execution of request 1
 
     scheduler.doWork();

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 069f67d..204b865 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -8078,11 +8078,9 @@ public class AmbariManagementControllerTest {
     stages.add(stageFactory.createNew(requestId3, "/a6", clusterName, 1L, context,
       CLUSTER_HOST_INFO, "", ""));
     stages.get(0).setStageId(6);
-    stages.get(0).addServerActionCommand("some.action.class.name", Role.AMBARI_SERVER_ACTION,
-        RoleCommand.EXECUTE, clusterName, serviceComponentHostServerActionEvent, null, null,
-        null, null,false, false);
-    assertEquals(StageUtils.getHostName(), stages.get(0).getOrderedHostRoleCommands().get(0).getHostName());
-
+    stages.get(0).addServerActionCommand("some.action.class.name", null, Role.AMBARI_SERVER_ACTION,
+        RoleCommand.EXECUTE, clusterName, serviceComponentHostServerActionEvent, null, null, null, null, false, false);
+    assertEquals("_internal_ambari", stages.get(0).getOrderedHostRoleCommands().get(0).getHostName());
     request = new Request(stages, clusters);
     actionDB.persistActions(request);
 
@@ -8134,7 +8132,7 @@ public class AmbariManagementControllerTest {
     assertNotNull(response);
     assertEquals(6L, response.getTaskId());
     // The host name for the task should be the same as what StageUtils#getHostName returns since
-    // the host was specifed as null when
+    // the host was specified as null when
     assertEquals(StageUtils.getHostName(), response.getHostName());
 
     //verify that task from second request (requestId2) does not present in first request (requestId1)

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
index a779949..17c15b2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
@@ -107,14 +107,6 @@ import com.google.inject.util.Modules;
  */
 public class UpgradeResourceProviderTest {
 
-  /**
-   * Server-side Actions still require a host in the cluster, so just use the
-   * local hostname when adding any host to the cluster. This prevents all sorts
-   * of problems when creating stages and tasks since the hosts in the cluster
-   * will now match the localhost.
-   */
-  private String s_serverHostName = StageUtils.getHostName();
-
   private UpgradeDAO upgradeDao = null;
   private RepositoryVersionDAO repoVersionDao = null;
   private Injector injector;
@@ -207,8 +199,8 @@ public class UpgradeResourceProviderTest {
     cluster.createClusterVersion(stack211, stack211.getStackVersion(), "admin", RepositoryVersionState.UPGRADING);
     cluster.transitionClusterVersion(stack211, stack211.getStackVersion(), RepositoryVersionState.CURRENT);
 
-    clusters.addHost(s_serverHostName);
-    Host host = clusters.getHost(s_serverHostName);
+    clusters.addHost("h1");
+    Host host = clusters.getHost("h1");
     Map<String, String> hostAttributes = new HashMap<String, String>();
     hostAttributes.put("os_family", "redhat");
     hostAttributes.put("os_release_version", "6.3");
@@ -216,7 +208,7 @@ public class UpgradeResourceProviderTest {
     host.setState(HostState.HEALTHY);
     host.persist();
 
-    clusters.mapHostToCluster(s_serverHostName, "c1");
+    clusters.mapHostToCluster("h1", "c1");
 
     // add a single ZK server
     Service service = cluster.addService("ZOOKEEPER");
@@ -224,11 +216,11 @@ public class UpgradeResourceProviderTest {
     service.persist();
 
     ServiceComponent component = service.addServiceComponent("ZOOKEEPER_SERVER");
-    ServiceComponentHost sch = component.addServiceComponentHost(s_serverHostName);
+    ServiceComponentHost sch = component.addServiceComponentHost("h1");
     sch.setVersion("2.1.1.0");
 
     component = service.addServiceComponent("ZOOKEEPER_CLIENT");
-    sch = component.addServiceComponentHost(s_serverHostName);
+    sch = component.addServiceComponentHost("h1");
     sch.setVersion("2.1.1.0");
 
     TopologyManager topologyManager = new TopologyManager();

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
index f9b023f..c3ada2b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/ServerActionExecutorTest.java
@@ -122,9 +122,7 @@ public class ServerActionExecutorTest {
         "{\"host_param\":\"param_value\"}", "{\"stage_param\":\"param_value\"}");
 
     stage.addServerActionCommand(ManualStageAction.class.getName(),
-        null, Role.AMBARI_SERVER_ACTION,
-        RoleCommand.EXECUTE,
-        "cluster1", SERVER_HOST_NAME,
+        null, Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE, "cluster1",
         new ServiceComponentHostServerActionEvent(StageUtils.getHostName(), System.currentTimeMillis()),
         Collections.<String, String> emptyMap(), null, null, 1200, false, false);
 
@@ -321,8 +319,8 @@ public class ServerActionExecutorTest {
                 1L, requestContext, CLUSTER_HOST_INFO, "{}", "{}");
 
             stage.setStageId(stageId);
-            stage.addServerActionCommand(MockServerAction.class.getName(), Role.AMBARI_SERVER_ACTION,
-                RoleCommand.EXECUTE, "cluster1",
+            stage.addServerActionCommand(MockServerAction.class.getName(), null,
+                Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE, "cluster1",
                 new ServiceComponentHostServerActionEvent(SERVER_HOST_NAME, System.currentTimeMillis()),
                 payload, "command detail", null, timeout, false, false);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java b/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
index c9d7856..3c192a2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stageplanner/TestStagePlanner.java
@@ -126,11 +126,11 @@ public class TestStagePlanner {
     Stage stage = stageFactory.createNew(1, "/tmp", "cluster1", 1L,  "execution command wrapper test",
             "clusterHostInfo", "commandParamsStage", "hostParamsStage");
     stage.setStageId(1);
-    stage.addServerActionCommand("RESTART", Role.HIVE_METASTORE,
+    stage.addServerActionCommand("RESTART", null, Role.HIVE_METASTORE,
             RoleCommand.CUSTOM_COMMAND, "cluster1",
             new ServiceComponentHostServerActionEvent("host2", System.currentTimeMillis()),
             null, "command detail", null, null, false, false);
-    stage.addServerActionCommand("RESTART", Role.MYSQL_SERVER,
+    stage.addServerActionCommand("RESTART", null, Role.MYSQL_SERVER,
             RoleCommand.CUSTOM_COMMAND, "cluster1",
             new ServiceComponentHostServerActionEvent("host2", System.currentTimeMillis()),
             null, "command detail", null, null, false, false);

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
index 76e96d1..a8ef7bc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
@@ -89,6 +89,7 @@ import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.persist.PersistService;
+import java.lang.reflect.Field;
 
 /**
  * {@link org.apache.ambari.server.upgrade.UpgradeCatalog213} unit tests.
@@ -135,7 +136,23 @@ public class UpgradeCatalog213Test {
     final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
     UpgradeCatalog213 upgradeCatalog = (UpgradeCatalog213) getUpgradeCatalog(dbAccessor);
 
+    Configuration configuration = createNiceMock(Configuration.class);
+    expect(configuration.getDatabaseUrl()).andReturn(Configuration.JDBC_IN_MEMORY_URL).anyTimes();
+
+    Capture<DBAccessor.DBColumnInfo> columnCapture = EasyMock.newCapture();
+    dbAccessor.alterColumn(eq("host_role_command"), capture(columnCapture));
+    expectLastCall();
+
+    replay(dbAccessor, configuration);
+    Class<?> c = AbstractUpgradeCatalog.class;
+    Field f = c.getDeclaredField("configuration");
+    f.setAccessible(true);
+    f.set(upgradeCatalog, configuration);
+
     upgradeCatalog.executeDDLUpdates();
+    verify(dbAccessor, configuration);
+
+    Assert.assertTrue(columnCapture.getValue().isNullable());
   }
 
   @Test
@@ -798,6 +815,7 @@ public class UpgradeCatalog213Test {
     Capture<String> capturedPKColumn = EasyMock.newCapture();
     Capture<List<DBAccessor.DBColumnInfo>> capturedColumns = EasyMock.newCapture();
     Capture<DBAccessor.DBColumnInfo> capturedColumn = EasyMock.newCapture();
+    Capture<DBAccessor.DBColumnInfo> capturedHostRoleCommandColumn = EasyMock.newCapture();
 
     EasyMock.expect(mockedInjector.getInstance(DaoUtils.class)).andReturn(mockedDaoUtils);
     mockedInjector.injectMembers(anyObject(UpgradeCatalog.class));
@@ -816,6 +834,7 @@ public class UpgradeCatalog213Test {
 
     // addKerberosDescriptorTable
     mockedDbAccessor.createTable(capture(capturedTableName), capture(capturedColumns), capture(capturedPKColumn));
+    mockedDbAccessor.alterColumn(eq("host_role_command"), capture(capturedHostRoleCommandColumn));
 
     mocksControl.replay();
 


[2/2] ambari git commit: AMBARI-13441. If Ambari Server is not part of the cluster, basic operations throw 500 (NPE) when Kerberos is enabled (even if it is Manual Kerberos) (rlevas)

Posted by rl...@apache.org.
AMBARI-13441. If Ambari Server is not part of the cluster, basic operations throw 500 (NPE) when Kerberos is enabled (even if it is Manual Kerberos) (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/24ce16b5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/24ce16b5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/24ce16b5

Branch: refs/heads/branch-2.1
Commit: 24ce16b5a3ced0944caa516fe07fc446435ce036
Parents: d2dc263
Author: Robert Levas <rl...@hortonworks.com>
Authored: Tue Oct 20 20:42:25 2015 -0700
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Tue Oct 20 20:42:25 2015 -0700

----------------------------------------------------------------------
 .../actionmanager/ActionDBAccessorImpl.java     |  57 ++--
 .../server/actionmanager/ActionScheduler.java   |  65 +++-
 .../server/actionmanager/HostRoleCommand.java   |   6 +-
 .../ambari/server/actionmanager/Stage.java      | 200 +++++++-----
 .../server/controller/KerberosHelperImpl.java   |   2 +-
 .../internal/UpgradeResourceProvider.java       |  24 +-
 .../server/orm/dao/HostRoleCommandDAO.java      |  23 +-
 .../orm/entities/HostRoleCommandEntity.java     |   4 +-
 .../serveraction/ServerActionExecutor.java      |   2 +-
 .../server/upgrade/UpgradeCatalog213.java       |   7 +
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   2 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   2 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   2 +-
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |   2 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |   2 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   2 +-
 .../ambari/server/actionmanager/StageTest.java  |   4 +-
 .../actionmanager/TestActionDBAccessorImpl.java |  36 +--
 .../actionmanager/TestActionScheduler.java      | 309 +++++++------------
 .../AmbariManagementControllerTest.java         |  10 +-
 .../internal/UpgradeResourceProviderTest.java   |  18 +-
 .../serveraction/ServerActionExecutorTest.java  |   8 +-
 .../server/stageplanner/TestStagePlanner.java   |   4 +-
 .../server/upgrade/UpgradeCatalog213Test.java   |  19 ++
 24 files changed, 424 insertions(+), 386 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
index 30da833..21d9f2b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
@@ -54,6 +54,7 @@ import org.apache.ambari.server.utils.LoopBody;
 import org.apache.ambari.server.utils.Parallel;
 import org.apache.ambari.server.utils.ParallelLoopResult;
 import org.apache.ambari.server.utils.StageUtils;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -297,35 +298,45 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
         HostRoleCommandEntity hostRoleCommandEntity = hostRoleCommand.constructNewPersistenceEntity();
         hostRoleCommandEntity.setStage(stageEntity);
 
-        HostEntity hostEntity = hostDAO.findById(hostRoleCommandEntity.getHostId());
-        if (hostEntity == null) {
-          String msg = String.format("Host %s doesn't exist in database", hostRoleCommandEntity.getHostName());
-          LOG.error(msg);
-          throw new AmbariException(msg);
-        }
-        hostRoleCommandEntity.setHostEntity(hostEntity);
+        HostEntity hostEntity = null;
+
         hostRoleCommandDAO.create(hostRoleCommandEntity);
 
-        assert hostRoleCommandEntity.getTaskId() != null;
         hostRoleCommand.setTaskId(hostRoleCommandEntity.getTaskId());
 
-        try {
-          // Get the in-memory host object and its prefix to construct the output and error log paths.
-          Host hostObject = clusters.getHost(hostRoleCommandEntity.getHostName());
-          String prefix = hostObject.getPrefix();
-          if (null != prefix && !prefix.isEmpty()) {
-            if (!prefix.endsWith("/")) {
-              prefix = prefix + "/";
+        String prefix = "";
+        String output = "output-" + hostRoleCommandEntity.getTaskId() + ".txt";
+        String error = "errors-" + hostRoleCommandEntity.getTaskId() + ".txt";
+
+        if (null != hostRoleCommandEntity.getHostId()) {
+          hostEntity = hostDAO.findById(hostRoleCommandEntity.getHostId());
+          if (hostEntity == null) {
+            String msg = String.format("Host %s doesn't exist in database", hostRoleCommandEntity.getHostName());
+            LOG.error(msg);
+            throw new AmbariException(msg);
+          }
+          hostRoleCommandEntity.setHostEntity(hostEntity);
+
+          try {
+            // Get the in-memory host object and its prefix to construct the output and error log paths.
+            Host hostObject = clusters.getHost(hostEntity.getHostName());
+
+            if (!StringUtils.isBlank(hostObject.getPrefix())) {
+              prefix = hostObject.getPrefix();
+              if (!prefix.endsWith("/")) {
+                prefix = prefix + "/";
+              }
             }
-            hostRoleCommand.setOutputLog(prefix + "output-" + hostRoleCommandEntity.getTaskId() + ".txt");
-            hostRoleCommand.setErrorLog(prefix + "errors-" + hostRoleCommandEntity.getTaskId() + ".txt");
-            hostRoleCommandEntity.setOutputLog(hostRoleCommand.getOutputLog());
-            hostRoleCommandEntity.setErrorLog(hostRoleCommand.getErrorLog());
+          } catch (AmbariException e) {
+            LOG.warn("Exception in getting prefix for host and setting output and error log files.  Using no prefix");
           }
-        } catch (AmbariException e) {
-          LOG.warn("Exception in getting prefix for host and setting output and error log files.");
         }
 
+        hostRoleCommand.setOutputLog(prefix + output);
+        hostRoleCommand.setErrorLog(prefix + error);
+        hostRoleCommandEntity.setOutputLog(hostRoleCommand.getOutputLog());
+        hostRoleCommandEntity.setErrorLog(hostRoleCommand.getErrorLog());
+
         ExecutionCommandEntity executionCommandEntity = hostRoleCommand.constructExecutionCommandEntity();
         executionCommandEntity.setHostRoleCommand(hostRoleCommandEntity);
 
@@ -334,7 +345,9 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
 
         executionCommandDAO.create(hostRoleCommandEntity.getExecutionCommand());
         hostRoleCommandDAO.merge(hostRoleCommandEntity);
-        hostDAO.merge(hostEntity);
+        if (null != hostEntity) {
+          hostDAO.merge(hostEntity);
+        }
       }
 
       for (RoleSuccessCriteriaEntity roleSuccessCriteriaEntity : stageEntity.getRoleSuccessCriterias()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
index 1e019b7..7b5adca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
@@ -89,7 +89,7 @@ class ActionScheduler implements Runnable {
   private final ActionDBAccessor db;
   private final short maxAttempts;
   private final ActionQueue actionQueue;
-  private final Clusters fsmObject;
+  private final Clusters clusters;
   private final AmbariEventPublisher ambariEventPublisher;
   private boolean taskTimeoutAdjustment = true;
   private final HostsMap hostsMap;
@@ -126,7 +126,7 @@ class ActionScheduler implements Runnable {
   private Cache<String, Map<String, String>> hostParamsStageCache;
 
   public ActionScheduler(long sleepTimeMilliSec, long actionTimeoutMilliSec,
-                         ActionDBAccessor db, ActionQueue actionQueue, Clusters fsmObject,
+                         ActionDBAccessor db, ActionQueue actionQueue, Clusters clusters,
                          int maxAttempts, HostsMap hostsMap,
                          UnitOfWork unitOfWork, AmbariEventPublisher ambariEventPublisher,
                          Configuration configuration) {
@@ -135,7 +135,7 @@ class ActionScheduler implements Runnable {
     actionTimeout = actionTimeoutMilliSec;
     this.db = db;
     this.actionQueue = actionQueue;
-    this.fsmObject = fsmObject;
+    this.clusters = clusters;
     this.ambariEventPublisher = ambariEventPublisher;
     this.maxAttempts = (short) maxAttempts;
     serverActionExecutor = new ServerActionExecutor(db, sleepTimeMilliSec);
@@ -343,7 +343,7 @@ class ActionScheduler implements Runnable {
         Map<ExecutionCommand, String> commandsToAbort = new HashMap<ExecutionCommand, String>();
         if (!eventMap.isEmpty()) {
           LOG.debug("==> processing {} serviceComponentHostEvents...", eventMap.size());
-          Cluster cluster = fsmObject.getCluster(stage.getClusterName());
+          Cluster cluster = clusters.getCluster(stage.getClusterName());
           if (cluster != null) {
             Map<ServiceComponentHostEvent, String> failedEvents = cluster.processServiceComponentHostEvents(eventMap);
 
@@ -523,14 +523,22 @@ class ActionScheduler implements Runnable {
 
     Cluster cluster = null;
     if (null != s.getClusterName()) {
-      cluster = fsmObject.getCluster(s.getClusterName());
+      cluster = clusters.getCluster(s.getClusterName());
     }
 
     for (String host : s.getHosts()) {
+
       List<ExecutionCommandWrapper> commandWrappers = s.getExecutionCommands(host);
-      Host hostObj = fsmObject.getHost(host);
+      Host hostObj = null;
+      try {
+        hostObj = clusters.getHost(host);
+      } catch (AmbariException e) {
+        LOG.debug("Host {} not found, stage is likely a server side action", host);
+      }
+
       int i_my = 0;
       LOG.trace("===>host=" + host);
+
       for(ExecutionCommandWrapper wrapper : commandWrappers) {
         ExecutionCommand c = wrapper.getExecutionCommand();
         String roleStr = c.getRole();
@@ -682,7 +690,7 @@ class ActionScheduler implements Runnable {
                                        boolean ignoreTransitionException) {
 
     try {
-      Cluster cluster = fsmObject.getCluster(clusterName);
+      Cluster cluster = clusters.getCluster(clusterName);
 
       ServiceComponentHostOpFailedEvent failedEvent =
         new ServiceComponentHostOpFailedEvent(componentName,
@@ -748,6 +756,17 @@ class ActionScheduler implements Runnable {
     return roleStats;
   }
 
+  /**
+   * Checks if timeout is required.
+   * @param status      the status of the current role
+   * @param stage       the stage
+   * @param host        the host object; can be {@code null} for server-side tasks
+   * @param role        the role
+   * @param currentTime the current
+   * @param taskTimeout the amount of time to determine timeout
+   * @return {@code true} if timeout is needed
+   * @throws AmbariException
+   */
   private boolean timeOutActionNeeded(HostRoleStatus status, Stage stage,
       Host host, String role, long currentTime, long taskTimeout) throws
     AmbariException {
@@ -755,29 +774,47 @@ class ActionScheduler implements Runnable {
         ( ! status.equals(HostRoleStatus.IN_PROGRESS) )) {
       return false;
     }
+
     // Fast fail task if host state is unknown
-    if (host.getState().equals(HostState.HEARTBEAT_LOST)) {
+    if (null != host && host.getState().equals(HostState.HEARTBEAT_LOST)) {
       LOG.debug("Timing out action since agent is not heartbeating.");
       return true;
     }
+
+    // tasks are held in a variety of in-memory maps that require a hostname key
+    // host being null is ok - that means it's a server-side task
+    String hostName = (null == host) ? null : host.getHostName();
+
     // If we have other command in progress for this stage do not timeout this one
-    if (hasCommandInProgress(stage, host.getHostName())
+    if (hasCommandInProgress(stage, hostName)
             && !status.equals(HostRoleStatus.IN_PROGRESS)) {
       return false;
     }
-    if (currentTime > stage.getLastAttemptTime(host.getHostName(), role)
+    if (currentTime > stage.getLastAttemptTime(hostName, role)
         + taskTimeout) {
       return true;
     }
     return false;
   }
 
-  private boolean hasCommandInProgress(Stage stage, String host) {
-    List<ExecutionCommandWrapper> commandWrappers = stage.getExecutionCommands(host);
+  /**
+   * Determines if at least one task for a given hostname in the specified stage is in progress.
+   * <p/>
+   * If the specified hostname is <code>null</code>, the Ambari Server host is assumed.
+   * See {@link Stage#getSafeHost(String)}.
+   *
+   * @param stage    a stage
+   * @param hostname a host name, if null the Ambari Server host is assumed
+   * @return true if at least one task for the given hostname in the specified stage is in progress; otherwize false
+   * @see Stage#getExecutionCommands(String)
+   * @see Stage#getHostRoleStatus(String, String)
+   */
+  private boolean hasCommandInProgress(Stage stage, String hostname) {
+    List<ExecutionCommandWrapper> commandWrappers = stage.getExecutionCommands(hostname);
     for (ExecutionCommandWrapper wrapper : commandWrappers) {
       ExecutionCommand c = wrapper.getExecutionCommand();
       String roleStr = c.getRole();
-      HostRoleStatus status = stage.getHostRoleStatus(host, roleStr);
+      HostRoleStatus status = stage.getHostRoleStatus(hostname, roleStr);
       if (status == HostRoleStatus.IN_PROGRESS) {
         return true;
       }
@@ -944,7 +981,7 @@ class ActionScheduler implements Runnable {
       // "Distribute repositories/install packages" action has been issued
       // against a concrete host without binding to a cluster)
       Long clusterId = clusterName != null ?
-              fsmObject.getCluster(clusterName).getClusterId() : null;
+              clusters.getCluster(clusterName).getClusterId() : null;
       ActionFinalReportReceivedEvent event = new ActionFinalReportReceivedEvent(
               clusterId, hostname, null,
               role);

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
index fec76ab..9585dc4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
@@ -141,7 +141,11 @@ public class HostRoleCommand {
     taskId = hostRoleCommandEntity.getTaskId();
     stageId = hostRoleCommandEntity.getStage().getStageId();
     requestId = hostRoleCommandEntity.getStage().getRequestId();
-    hostId = hostRoleCommandEntity.getHostId();
+
+    if (null != hostRoleCommandEntity.getHostId()) {
+      hostId = hostRoleCommandEntity.getHostId();
+    }
+
     hostName = hostRoleCommandEntity.getHostName();
     role = hostRoleCommandEntity.getRole();
     status = hostRoleCommandEntity.getStatus();

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
index 22b2ca4..8b2703c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
@@ -57,6 +57,14 @@ import com.google.inject.persist.Transactional;
 //required to persist an action.
 public class Stage {
 
+  /**
+   * Used because in-memory storage of commands requires a hostname for maps
+   * when the underlying store does not (host_id is {@code null}).  We also
+   * don't want stages getting confused with Ambari vs cluster hosts, so
+   * don't use {@link StageUtils#getHostName()}
+   */
+  private static final String INTERNAL_HOSTNAME = "_internal_ambari";
+
   private static Logger LOG = LoggerFactory.getLogger(Stage.class);
   private final long requestId;
   private String clusterName;
@@ -86,12 +94,6 @@ public class Stage {
   @Inject
   private HostRoleCommandFactory hostRoleCommandFactory;
 
-  @Inject
-  private HostRoleCommandDAO hostRoleCommandDAO;
-
-  @Inject
-  private ActionDBAccessor dbAccessor;
-
   @AssistedInject
   public Stage(@Assisted long requestId,
       @Assisted("logDir") String logDir,
@@ -119,8 +121,6 @@ public class Stage {
   public Stage(@Assisted StageEntity stageEntity, HostRoleCommandDAO hostRoleCommandDAO,
                ActionDBAccessor dbAccessor, Clusters clusters, HostRoleCommandFactory hostRoleCommandFactory) {
     this.hostRoleCommandFactory = hostRoleCommandFactory;
-    this.hostRoleCommandDAO = hostRoleCommandDAO;
-    this.dbAccessor = dbAccessor;
 
     requestId = stageEntity.getRequestId();
     stageId = stageEntity.getStageId();
@@ -146,7 +146,11 @@ public class Stage {
     Collection<HostRoleCommand> commands = dbAccessor.getTasks(taskIds);
 
     for (HostRoleCommand command : commands) {
-      String hostname = command.getHostName();
+      // !!! some commands won't have a hostname, because they are server-side and
+      // don't hold that information.  In that case, use the special key to
+      // use in the map
+      String hostname = getSafeHost(command.getHostName());
+
       if (!hostRoleCommands.containsKey(hostname)) {
         hostRoleCommands.put(hostname, new LinkedHashMap<String, HostRoleCommand>());
       }
@@ -358,39 +362,6 @@ public class Stage {
   }
 
   /**
-   * Creates server-side execution command.
-   * <p/>
-   * The action name for this command is expected to be the classname of a
-   * {@link org.apache.ambari.server.serveraction.ServerAction} implementation which will be
-   * instantiated and invoked as needed.
-   *
-   * @param actionName    a String declaring the action name (in the form of a classname) to execute
-   * @param role          the Role for this command
-   * @param command       the RoleCommand for this command
-   * @param clusterName   a String identifying the cluster on which to to execute this command
-   * @param event         a ServiceComponentHostServerActionEvent
-   * @param commandParams a Map of String to String data used to pass to the action - this may be
-   *                      empty or null if no data is relevant
-   * @param commandDetail a String declaring a descriptive name to pass to the action - null or an
-   *                      empty string indicates no value is to be set
-   * @param configTags    a Map of configuration tags to set for this command - if null, no
-   *                      configurations will be available for the command
-   * @param timeout       an Integer declaring the timeout for this action - if null, a default
-   * @param retryAllowed   indicates whether retry after failure is allowed
-   */
-  public synchronized void addServerActionCommand(String actionName, Role role, RoleCommand command,
-      String clusterName, ServiceComponentHostServerActionEvent event,
-      @Nullable Map<String, String> commandParams, @Nullable String commandDetail,
-      @Nullable Map<String, Map<String, String>> configTags, @Nullable Integer timeout,
-      boolean retryAllowed, boolean autoSkipFailure) {
-    addServerActionCommand(actionName, null, role, command, clusterName, StageUtils.getHostName(),
-        event, commandParams, commandDetail, configTags, timeout, retryAllowed, autoSkipFailure);
-  }
-
-  /**
-   * THIS METHOD IS TO WORKAROUND A BUG! The assumption of the framework is that
-   * the Ambari Server is installed on a host WITHIN the cluster, which is not
-   * always true. This method adds a host parameter.
    * <p/>
    * Creates server-side execution command.
    * <p/>
@@ -411,8 +382,6 @@ public class Stage {
    * @param clusterName
    *          a String identifying the cluster on which to to execute this
    *          command
-   * @param hostName
-   *          the name of the host
    * @param event
    *          a ServiceComponentHostServerActionEvent
    * @param commandParams
@@ -431,13 +400,13 @@ public class Stage {
    *          indicates whether retry after failure is allowed
    */
   public synchronized void addServerActionCommand(String actionName, @Nullable String userName,
-      Role role, RoleCommand command, String clusterName, String hostName,
+      Role role, RoleCommand command, String clusterName,
       ServiceComponentHostServerActionEvent event, @Nullable Map<String, String> commandParams,
       @Nullable String commandDetail, @Nullable Map<String, Map<String, String>> configTags,
       @Nullable Integer timeout, boolean retryAllowed, boolean autoSkipFailure) {
 
-    ExecutionCommandWrapper commandWrapper = addGenericExecutionCommand(clusterName, hostName, role,
-        command, event, retryAllowed, autoSkipFailure);
+    ExecutionCommandWrapper commandWrapper = addGenericExecutionCommand(clusterName,
+        INTERNAL_HOSTNAME, role, command, event, retryAllowed, autoSkipFailure);
 
     ExecutionCommand cmd = commandWrapper.getExecutionCommand();
 
@@ -469,7 +438,7 @@ public class Stage {
     cmd.setRoleParams(roleParams);
 
     if(commandDetail != null) {
-      HostRoleCommand hostRoleCommand = getHostRoleCommand(hostName, role.toString());
+      HostRoleCommand hostRoleCommand = getHostRoleCommand(INTERNAL_HOSTNAME, role.toString());
       if (hostRoleCommand != null) {
         hostRoleCommand.setCommandDetail(commandDetail);
         hostRoleCommand.setCustomCommandName(actionName);
@@ -546,25 +515,49 @@ public class Stage {
     return requestContext;
   }
 
-  public long getLastAttemptTime(String host, String role) {
-    return hostRoleCommands.get(host).get(role).getLastAttemptTime();
+  /**
+   * @param hostname  the hostname; {@code null} for a server-side stage
+   * @param role      the role
+   * @return the last attempt time
+   */
+  public long getLastAttemptTime(String hostname, String role) {
+    return hostRoleCommands.get(getSafeHost(hostname)).get(role).getLastAttemptTime();
   }
 
-  public short getAttemptCount(String host, String role) {
-    return hostRoleCommands.get(host).get(role).getAttemptCount();
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @return the number of attempts
+   */
+  public short getAttemptCount(String hostname, String role) {
+    return hostRoleCommands.get(getSafeHost(hostname)).get(role).getAttemptCount();
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   */
   public void incrementAttemptCount(String hostname, String role) {
-    hostRoleCommands.get(hostname).get(role).incrementAttemptCount();
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).incrementAttemptCount();
   }
 
-  public void setLastAttemptTime(String host, String role, long t) {
-    hostRoleCommands.get(host).get(role).setLastAttemptTime(t);
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @param t           the last time the role was attempted
+   */
+  public void setLastAttemptTime(String hostname, String role, long t) {
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).setLastAttemptTime(t);
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @return            the wrapper
+   */
   public ExecutionCommandWrapper getExecutionCommandWrapper(String hostname,
       String role) {
-    HostRoleCommand hrc = hostRoleCommands.get(hostname).get(role);
+    HostRoleCommand hrc = hostRoleCommands.get(getSafeHost(hostname)).get(role);
     if (hrc != null) {
       return hrc.getExecutionCommandWrapper();
     } else {
@@ -572,47 +565,95 @@ public class Stage {
     }
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @return  the list of commands for the host
+   */
   public List<ExecutionCommandWrapper> getExecutionCommands(String hostname) {
     checkWrappersLoaded();
-    return commandsToSend.get(hostname);
+    return commandsToSend.get(getSafeHost(hostname));
   }
 
+/**
+ * @param hostname    the hostname; {@code null} for a server-side stage
+ * @param role        the role
+ * @return the start time for the task
+ */
   public long getStartTime(String hostname, String role) {
-    return hostRoleCommands.get(hostname).get(role).getStartTime();
+    return hostRoleCommands.get(getSafeHost(hostname)).get(role).getStartTime();
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @param startTime   the start time
+   */
   public void setStartTime(String hostname, String role, long startTime) {
-    hostRoleCommands.get(hostname).get(role).setStartTime(startTime);
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).setStartTime(startTime);
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @return the status
+   */
   public HostRoleStatus getHostRoleStatus(String hostname, String role) {
-    return hostRoleCommands.get(hostname).get(role).getStatus();
+    return hostRoleCommands.get(getSafeHost(hostname)).get(role).getStatus();
   }
 
-  public void setHostRoleStatus(String host, String role,
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @param status      the status
+   */
+  public void setHostRoleStatus(String hostname, String role,
       HostRoleStatus status) {
-    hostRoleCommands.get(host).get(role).setStatus(status);
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).setStatus(status);
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param roleStr     the role name
+   * @return the wrapper event
+   */
   public ServiceComponentHostEventWrapper getFsmEvent(String hostname, String roleStr) {
-    return hostRoleCommands.get(hostname).get(roleStr).getEvent();
+    return hostRoleCommands.get(getSafeHost(hostname)).get(roleStr).getEvent();
   }
 
-
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @param exitCode    the exit code
+   */
   public void setExitCode(String hostname, String role, int exitCode) {
-    hostRoleCommands.get(hostname).get(role).setExitCode(exitCode);
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).setExitCode(exitCode);
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @return the exit code
+   */
   public int getExitCode(String hostname, String role) {
-    return hostRoleCommands.get(hostname).get(role).getExitCode();
+    return hostRoleCommands.get(getSafeHost(hostname)).get(role).getExitCode();
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @param stdErr      the standard error string
+   */
   public void setStderr(String hostname, String role, String stdErr) {
-    hostRoleCommands.get(hostname).get(role).setStderr(stdErr);
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).setStderr(stdErr);
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @param stdOut      the standard output string
+   */
   public void setStdout(String hostname, String role, String stdOut) {
-    hostRoleCommands.get(hostname).get(role).setStdout(stdOut);
+    hostRoleCommands.get(getSafeHost(hostname)).get(role).setStdout(stdOut);
   }
 
   public synchronized boolean isStageInProgress() {
@@ -667,10 +708,16 @@ public class Stage {
    * This method should be used only in stage planner. To add
    * a new execution command use
    * {@link #addHostRoleExecutionCommand(String, org.apache.ambari.server.Role, org.apache.ambari.server.RoleCommand, org.apache.ambari.server.state.ServiceComponentHostEvent, String, String, boolean)}
+   * @param origStage the stage
+   * @param hostname  the hostname; {@code null} for a server-side stage
+   * @param r         the role
    */
   public synchronized void addExecutionCommandWrapper(Stage origStage,
       String hostname, Role r) {
     //used on stage creation only, no need to check if wrappers loaded
+
+    hostname = getSafeHost(hostname);
+
     String role = r.toString();
     if (commandsToSend.get(hostname) == null) {
       commandsToSend.put(hostname, new ArrayList<ExecutionCommandWrapper>());
@@ -685,8 +732,13 @@ public class Stage {
         origStage.getHostRoleCommand(hostname, role));
   }
 
+  /**
+   * @param hostname    the hostname; {@code null} for a server-side stage
+   * @param role        the role
+   * @return the role command
+   */
   public HostRoleCommand getHostRoleCommand(String hostname, String role) {
-    return hostRoleCommands.get(hostname).get(role);
+    return hostRoleCommands.get(getSafeHost(hostname)).get(role);
   }
 
   /**
@@ -773,4 +825,14 @@ public class Stage {
     builder.append("STAGE DESCRIPTION END\n");
     return builder.toString();
   }
+
+  /**
+   * Helper to make sure the hostname is non-null for internal command map.
+   * @param hostname  the hostname for the map key
+   * @return the hostname when not {@code null}, otherwise {@link #INTERNAL_HOSTNAME}
+   */
+  private static String getSafeHost(String hostname) {
+    return (null == hostname) ? INTERNAL_HOSTNAME : hostname;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
index 20b4658..f35305e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
@@ -1655,7 +1655,7 @@ public class KerberosHelperImpl implements KerberosHelper {
                                         Integer timeout) throws AmbariException {
 
     Stage stage = createNewStage(id, cluster, requestId, requestContext, clusterHostInfo, commandParams, hostParams);
-    stage.addServerActionCommand(actionClass.getName(), Role.AMBARI_SERVER_ACTION,
+    stage.addServerActionCommand(actionClass.getName(), null, Role.AMBARI_SERVER_ACTION,
         RoleCommand.EXECUTE, cluster.getClusterName(), event, commandParameters, commandDetail,
         ambariManagementController.findConfigurationTagsWithOverrides(cluster, null), timeout,
         false, false);

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index d1b5102..ecf22c2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -23,7 +23,6 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -72,7 +71,6 @@ import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.RequestDAO;
 import org.apache.ambari.server.orm.dao.UpgradeDAO;
-import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.RequestEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
@@ -1309,21 +1307,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     String itemDetail = entity.getText();
     String stageText = StringUtils.abbreviate(entity.getText(), 255);
 
-    String hostName = null;
-    Collection<Long> hostIds = cluster.getAllHostsDesiredConfigs().keySet();
-    if (!hostIds.isEmpty()) {
-      Long hostId = hostIds.iterator().next();
-      HostEntity hostEntity = s_hostDAO.findById(hostId);
-      if (hostEntity != null) {
-        hostName = hostEntity.getHostName();
-      }
-    }
-
-    if (StringUtils.isBlank(hostName)) {
-      throw new AmbariException(
-          "Could not retrieve an arbitrary host name to use for the server-side command.");
-    }
-
     switch (task.getType()) {
       case MANUAL: {
         ManualTask mt = (ManualTask) task;
@@ -1395,9 +1378,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     stage.setStageId(stageId);
     entity.setStageId(Long.valueOf(stageId));
 
-    stage.addServerActionCommand(task.getImplementationClass(), null, Role.AMBARI_SERVER_ACTION,
-        RoleCommand.EXECUTE, cluster.getClusterName(), hostName,
-        new ServiceComponentHostServerActionEvent(hostName, System.currentTimeMillis()), commandParams,
+    stage.addServerActionCommand(task.getImplementationClass(),
+        getManagementController().getAuthName(), Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE,
+        cluster.getClusterName(),
+        new ServiceComponentHostServerActionEvent(null, System.currentTimeMillis()), commandParams,
         itemDetail, null, Integer.valueOf(1200), allowRetry,
         context.isComponentFailureAutoSkipped());
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
index f04c868..da4afbf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
@@ -32,7 +32,6 @@ import java.util.Map;
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 
-import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.HostEntity;
@@ -241,13 +240,21 @@ public class HostRoleCommandDAO {
 
   @RequiresSession
   public List<HostRoleCommandEntity> findByHostRole(String hostName, long requestId, long stageId, String role) {
-    TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createQuery("SELECT command " +
-        "FROM HostRoleCommandEntity command " +
-        "WHERE command.hostEntity.hostName=?1 AND command.requestId=?2 " +
-        "AND command.stageId=?3 AND command.role=?4 " +
-        "ORDER BY command.taskId", HostRoleCommandEntity.class);
-
-    return daoUtils.selectList(query, hostName, requestId, stageId, role);
+    if (null == hostName) {
+      TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createQuery("SELECT command " +
+          "FROM HostRoleCommandEntity command " +
+          "WHERE command.hostEntity IS NULL AND command.requestId=?1 " +
+          "AND command.stageId=?2 AND command.role=?3 " +
+          "ORDER BY command.taskId", HostRoleCommandEntity.class);
+      return daoUtils.selectList(query, requestId, stageId, role);
+    } else {
+      TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createQuery("SELECT command " +
+          "FROM HostRoleCommandEntity command " +
+          "WHERE command.hostEntity.hostName=?1 AND command.requestId=?2 " +
+          "AND command.stageId=?3 AND command.role=?4 " +
+          "ORDER BY command.taskId", HostRoleCommandEntity.class);
+      return daoUtils.selectList(query, hostName, requestId, stageId, role);
+    }
   }
 
   @RequiresSession

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
index c005efc..763111b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
@@ -77,7 +77,7 @@ public class HostRoleCommandEntity {
   @Basic
   private Long stageId;
 
-  @Column(name = "host_id", insertable = false, updatable = false, nullable = false)
+  @Column(name = "host_id", insertable = false, updatable = false, nullable = true)
   @Basic
   private Long hostId;
 
@@ -170,7 +170,7 @@ public class HostRoleCommandEntity {
   private StageEntity stage;
 
   @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
-  @JoinColumn(name = "host_id", referencedColumnName = "host_id", nullable = false)
+  @JoinColumn(name = "host_id", referencedColumnName = "host_id", nullable = true)
   private HostEntity hostEntity;
 
   @OneToOne(mappedBy = "hostRoleCommandEntity", cascade = CascadeType.REMOVE)

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
index 670e925..4c241d1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
@@ -329,7 +329,7 @@ public class ServerActionExecutor {
       commandReport = createErrorReport("Unknown error condition");
     }
 
-    db.updateHostRoleState(executionCommand.getHostname(), hostRoleCommand.getRequestId(),
+    db.updateHostRoleState(null, hostRoleCommand.getRequestId(),
         hostRoleCommand.getStageId(), executionCommand.getRole(), commandReport);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
index 3695faa..be43e71 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
@@ -106,6 +106,9 @@ public class UpgradeCatalog213 extends AbstractUpgradeCatalog {
   public static final String UPGRADE_TYPE_COL = "upgrade_type";
   public static final String REPO_VERSION_TABLE = "repo_version";
 
+  private static final String HOST_ROLE_COMMAND_TABLE = "host_role_command";
+  private static final String HOST_ID_COL = "host_id";
+
   private static final String KERBEROS_DESCRIPTOR_TABLE = "kerberos_descriptor";
   private static final String KERBEROS_DESCRIPTOR_NAME_COLUMN = "kerberos_descriptor_name";
   private static final String KERBEROS_DESCRIPTOR_COLUMN = "kerberos_descriptor";
@@ -163,6 +166,10 @@ public class UpgradeCatalog213 extends AbstractUpgradeCatalog {
   @Override
   protected void executeDDLUpdates() throws AmbariException, SQLException {
     executeUpgradeDDLUpdates();
+
+    // Alter the host_role_command table to allow host_id to be nullable
+    dbAccessor.alterColumn(HOST_ROLE_COMMAND_TABLE, new DBColumnInfo(HOST_ID_COL, Long.class, null, null, true));
+
     addKerberosDescriptorTable();
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/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 4ffe8da..9330310 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -226,7 +226,7 @@ CREATE TABLE host_role_command (
   retry_allowed SMALLINT DEFAULT 0 NOT NULL,
   event LONGTEXT NOT NULL,
   exitcode INTEGER NOT NULL,
-  host_id BIGINT NOT NULL,
+  host_id BIGINT,
   last_attempt_time BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   role VARCHAR(255),

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/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 8fb6e68..8b36f9e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -216,7 +216,7 @@ CREATE TABLE host_role_command (
   retry_allowed NUMBER(1) DEFAULT 0 NOT NULL,
   event CLOB NULL,
   exitcode NUMBER(10) NOT NULL,
-  host_id NUMBER(19) NOT NULL,
+  host_id NUMBER(19),
   last_attempt_time NUMBER(19) NOT NULL,
   request_id NUMBER(19) NOT NULL,
   role VARCHAR2(255) NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/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 fb98757..764396e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -228,7 +228,7 @@ CREATE TABLE host_role_command (
   retry_allowed SMALLINT DEFAULT 0 NOT NULL,
   event VARCHAR(32000) NOT NULL,
   exitcode INTEGER NOT NULL,
-  host_id BIGINT NOT NULL,
+  host_id BIGINT,
   last_attempt_time BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   role VARCHAR(255),

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index 098444b..dbca53e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -259,7 +259,7 @@ CREATE TABLE ambari.host_role_command (
   retry_allowed SMALLINT DEFAULT 0 NOT NULL,
   event VARCHAR(32000) NOT NULL,
   exitcode INTEGER NOT NULL,
-  host_id BIGINT NOT NULL,
+  host_id BIGINT,
   last_attempt_time BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   role VARCHAR(255),

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index 8eacfa8..2f93825 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -215,7 +215,7 @@ CREATE TABLE host_role_command (
   retry_allowed SMALLINT DEFAULT 0 NOT NULL,
   event TEXT NOT NULL,
   exitcode INTEGER NOT NULL,
-  host_id NUMERIC(19) NOT NULL,
+  host_id NUMERIC(19),
   last_attempt_time NUMERIC(19) NOT NULL,
   request_id NUMERIC(19) NOT NULL,
   role VARCHAR(255),

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index a947ce0..ef90205 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -245,7 +245,7 @@ CREATE TABLE host_role_command (
   retry_allowed SMALLINT DEFAULT 0 NOT NULL,
   event VARCHAR(MAX) NOT NULL,
   exitcode INTEGER NOT NULL,
-  host_id BIGINT NOT NULL,
+  host_id BIGINT,
   last_attempt_time BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   role VARCHAR(255),

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/StageTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/StageTest.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/StageTest.java
index c1bd8bc..663d68d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/StageTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/StageTest.java
@@ -67,11 +67,11 @@ public class StageTest {
     stage.addServerActionCommand(ConfigureAction.class.getName(),
         "user1", Role.AMBARI_SERVER_ACTION,
         RoleCommand.EXECUTE,
-        "cluster1", SERVER_HOST_NAME,
+        "cluster1",
         new ServiceComponentHostServerActionEvent(StageUtils.getHostName(), System.currentTimeMillis()),
         Collections.<String, String> emptyMap(), null, null, 1200, false, false);
 
-    List<ExecutionCommandWrapper> executionCommands = stage.getExecutionCommands(SERVER_HOST_NAME);
+    List<ExecutionCommandWrapper> executionCommands = stage.getExecutionCommands(null);
     assertEquals(1, executionCommands.size());
 
     String actionUserName = executionCommands.get(0).getExecutionCommand().getRoleParams().get(ServerAction.ACTION_USER_NAME);

http://git-wip-us.apache.org/repos/asf/ambari/blob/24ce16b5/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 798261b..f88cf8e 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
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -37,7 +36,6 @@ import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.BaseRequest;
 import org.apache.ambari.server.configuration.Configuration;
-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.DBAccessor;
@@ -355,7 +353,6 @@ public class TestActionDBAccessorImpl {
     assertEquals(HostRoleStatus.QUEUED, stage.getHostRoleStatus(hostName, actionName));
     assertEquals(HostRoleStatus.PENDING, entities.get(0).getStatus());
 
-    long now = System.currentTimeMillis();
     db.hostRoleScheduled(stage, hostName, actionName);
 
     entities = hostRoleCommandDAO.findByHostRole(
@@ -383,25 +380,25 @@ public class TestActionDBAccessorImpl {
 
   @Test
   public void testServerActionScheduled() throws InterruptedException, AmbariException {
-    populateActionDBWithServerAction(db, serverHostName, requestId, stageId);
+    populateActionDBWithServerAction(db, null, requestId, stageId);
 
     final String roleName = Role.AMBARI_SERVER_ACTION.toString();
     Stage stage = db.getStage(StageUtils.getActionId(requestId, stageId));
-    assertEquals(HostRoleStatus.PENDING, stage.getHostRoleStatus(serverHostName, roleName));
+    assertEquals(HostRoleStatus.PENDING, stage.getHostRoleStatus(null, roleName));
     List<HostRoleCommandEntity> entities =
-        hostRoleCommandDAO.findByHostRole(serverHostName, requestId, stageId, roleName);
+        hostRoleCommandDAO.findByHostRole(null, requestId, stageId, roleName);
 
     assertEquals(HostRoleStatus.PENDING, entities.get(0).getStatus());
-    stage.setHostRoleStatus(serverHostName, roleName, HostRoleStatus.QUEUED);
+    stage.setHostRoleStatus(null, roleName, HostRoleStatus.QUEUED);
 
-    entities = hostRoleCommandDAO.findByHostRole(serverHostName, requestId, stageId, roleName);
-    assertEquals(HostRoleStatus.QUEUED, stage.getHostRoleStatus(serverHostName, roleName));
+    entities = hostRoleCommandDAO.findByHostRole(null, requestId, stageId, roleName);
+    assertEquals(HostRoleStatus.QUEUED, stage.getHostRoleStatus(null, roleName));
     assertEquals(HostRoleStatus.PENDING, entities.get(0).getStatus());
 
-    db.hostRoleScheduled(stage, serverHostName, roleName);
+    db.hostRoleScheduled(stage, null, roleName);
 
     entities = hostRoleCommandDAO.findByHostRole(
-        serverHostName, requestId, stageId, roleName);
+        null, requestId, stageId, roleName);
     assertEquals(HostRoleStatus.QUEUED, entities.get(0).getStatus());
 
 
@@ -409,8 +406,8 @@ public class TestActionDBAccessorImpl {
       @Override
       public void run() {
         Stage stage1 = db.getStage("23-31");
-        stage1.setHostRoleStatus(serverHostName, roleName, HostRoleStatus.COMPLETED);
-        db.hostRoleScheduled(stage1, serverHostName, roleName);
+        stage1.setHostRoleStatus(null, roleName, HostRoleStatus.COMPLETED);
+        db.hostRoleScheduled(stage1, null, roleName);
         injector.getInstance(EntityManager.class).clear();
       }
     };
@@ -419,7 +416,7 @@ public class TestActionDBAccessorImpl {
     thread.join();
 
     injector.getInstance(EntityManager.class).clear();
-    entities = hostRoleCommandDAO.findByHostRole(serverHostName, requestId, stageId, roleName);
+    entities = hostRoleCommandDAO.findByHostRole(null, requestId, stageId, roleName);
     assertEquals("Concurrent update failed", HostRoleStatus.COMPLETED, entities.get(0).getStatus());
   }
 
@@ -766,8 +763,6 @@ public class TestActionDBAccessorImpl {
     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, null, false);
     Request request = new Request(stages, clusters);
     db.persistActions(request);
   }
@@ -777,17 +772,10 @@ public class TestActionDBAccessorImpl {
     Stage s = stageFactory.createNew(requestId, "/a/b", "cluster1", 1L, "action db accessor test",
         "", "commandParamsStage", "hostParamsStage");
     s.setStageId(stageId);
-    s.addServerActionCommand(serverActionName, Role.AMBARI_SERVER_ACTION,
+    s.addServerActionCommand(serverActionName, null, Role.AMBARI_SERVER_ACTION,
         RoleCommand.ACTIONEXECUTE, clusterName, null, null, "command details", null, 300, false, false);
     List<Stage> stages = new ArrayList<Stage>();
     stages.add(s);
-    final RequestResourceFilter resourceFilter = new RequestResourceFilter("AMBARI", "SERVER", Arrays.asList(hostname));
-    List<RequestResourceFilter> resourceFilters = new
-        ArrayList<RequestResourceFilter>() {{
-          add(resourceFilter);
-        }};
-    ExecuteActionRequest executeActionRequest = new ExecuteActionRequest
-        ("cluster1", null, serverActionName, resourceFilters, null, null, false);
     Request request = new Request(stages, clusters);
     db.persistActions(request);
   }