You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/04/19 02:04:32 UTC

[3/3] ambari git commit: AMBARI-10169. Full Delete of Host : Switch host_version and host_role_command tables to use host_id instead of host_name column (alejandro)

AMBARI-10169. Full Delete of Host : Switch host_version and host_role_command tables to use host_id instead of host_name column (alejandro)


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

Branch: refs/heads/trunk
Commit: ee79dd21cca51646e3344c161ea61bc2e68f21fb
Parents: 8102135
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Wed Apr 15 17:00:18 2015 -0700
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Sat Apr 18 16:18:05 2015 -0700

----------------------------------------------------------------------
 .../actionmanager/ActionDBAccessorImpl.java     |   2 +-
 .../server/actionmanager/HostRoleCommand.java   |  60 +++--
 .../actionmanager/HostRoleCommandFactory.java   |  30 +++
 .../HostRoleCommandFactoryImpl.java             |  48 +++-
 .../ambari/server/actionmanager/Stage.java      |  24 +-
 .../server/actionmanager/StageFactoryImpl.java  |  81 ++++++
 .../controller/AmbariManagementController.java  |   8 +
 .../AmbariManagementControllerImpl.java         |  14 +-
 .../server/controller/ControllerModule.java     |  12 +-
 .../server/controller/KerberosHelper.java       |  20 +-
 .../ClusterStackVersionResourceProvider.java    |  26 +-
 .../internal/UpgradeResourceProvider.java       |   4 +-
 .../upgrade/HostVersionOutOfSyncListener.java   |   5 +-
 .../ambari/server/orm/DBAccessorImpl.java       |  17 +-
 .../server/orm/dao/HostRoleCommandDAO.java      |  10 +-
 .../ambari/server/orm/entities/HostEntity.java  |   2 +-
 .../orm/entities/HostRoleCommandEntity.java     |  26 +-
 .../server/orm/entities/HostVersionEntity.java  |  81 ++----
 .../ambari/server/stageplanner/RoleGraph.java   |  19 +-
 .../server/stageplanner/RoleGraphFactory.java   |  35 +++
 .../stageplanner/RoleGraphFactoryImpl.java      |  54 ++++
 .../server/state/cluster/ClusterImpl.java       |  15 +-
 .../server/upgrade/UpgradeCatalog210.java       |  63 ++++-
 .../apache/ambari/server/utils/StageUtils.java  |  14 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  13 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  13 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  13 +-
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |  13 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  11 +-
 .../ExecutionCommandWrapperTest.java            |  98 +++----
 .../ambari/server/actionmanager/StageTest.java  |  19 +-
 .../actionmanager/TestActionDBAccessorImpl.java |  14 +-
 .../server/actionmanager/TestActionManager.java |   5 +-
 .../actionmanager/TestActionScheduler.java      |  64 +++--
 .../ambari/server/actionmanager/TestStage.java  |  26 +-
 .../ambari/server/agent/AgentResourceTest.java  |   4 +-
 .../server/agent/TestHeartbeatHandler.java      | 263 +++++++------------
 .../AmbariCustomCommandExecutionHelperTest.java |   7 +-
 .../AmbariManagementControllerTest.java         |  15 +-
 .../server/controller/KerberosHelperTest.java   |  20 +-
 .../internal/CalculatedStatusTest.java          |  32 ++-
 ...ClusterStackVersionResourceProviderTest.java |  60 ++++-
 .../apache/ambari/server/orm/OrmTestHelper.java |  10 +-
 .../server/orm/dao/HostVersionDAOTest.java      |  48 ++--
 .../ambari/server/orm/dao/RequestDAOTest.java   |   2 +-
 .../serveraction/ServerActionExecutorTest.java  |  74 ++++--
 .../upgrades/UpgradeActionTest.java             |  90 +++----
 .../server/stageplanner/TestStagePlanner.java   |  15 +-
 .../server/state/cluster/ClusterTest.java       |   3 +-
 .../ambari/server/upgrade/UpgradeTest.java      |   9 -
 50 files changed, 1040 insertions(+), 571 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 7447a2d..8444862 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
@@ -268,7 +268,7 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
           LOG.error(msg);
           throw new AmbariException(msg);
         }
-        hostRoleCommandEntity.setHost(hostEntity);
+        hostRoleCommandEntity.setHostEntity(hostEntity);
         hostRoleCommandDAO.create(hostRoleCommandEntity);
 
         assert hostRoleCommandEntity.getTaskId() != null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 f37e937..662a545 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
@@ -17,10 +17,13 @@
  */
 package org.apache.ambari.server.actionmanager;
 
+import com.google.inject.Inject;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.orm.dao.ExecutionCommandDAO;
+import org.apache.ambari.server.orm.dao.HostDAO;
 import org.apache.ambari.server.orm.entities.ExecutionCommandEntity;
+import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.apache.ambari.server.state.ServiceComponentHostEvent;
 
@@ -40,7 +43,7 @@ public class HostRoleCommand {
   private long taskId = -1;
   private long stageId = -1;
   private long requestId = -1;
-  private String hostName;
+  private HostEntity hostEntity;
   private HostRoleStatus status = HostRoleStatus.PENDING;
   private String stdout = "";
   private String stderr = "";
@@ -57,28 +60,58 @@ public class HostRoleCommand {
   private String commandDetail;
   private String customCommandName;
   private ExecutionCommandWrapper executionCommandWrapper;
+
+  @Inject
   private ExecutionCommandDAO executionCommandDAO;
 
-  public HostRoleCommand(String host, Role role,
-                         ServiceComponentHostEvent event, RoleCommand command) {
-    this(host, role, event, command, false);
-  }
+  @Inject
+  private HostDAO hostDAO;
+
+  /**
+   * Simple constructor, should be created using the Factory class.
+   * @param hostName Host name
+   * @param role Action to run
+   * @param event Event on the host and component
+   * @param command Type of command
+   * @param hostDAO {@link org.apache.ambari.server.orm.dao.HostDAO} instance being injected
+   */
+  @AssistedInject
+  public HostRoleCommand(String hostName, Role role,
+                         ServiceComponentHostEvent event, RoleCommand command, HostDAO hostDAO, ExecutionCommandDAO executionCommandDAO) {
+    this(hostName, role, event, command, false, hostDAO, executionCommandDAO);
+  }
+
+  /**
+   * Simple constructor, should be created using the Factory class.
+   * @param hostName Host name
+   * @param role Action to run
+   * @param event Event on the host and component
+   * @param command Type of command
+   * @param retryAllowed Whether the command can be repeated
+   * @param hostDAO {@link org.apache.ambari.server.orm.dao.HostDAO} instance being injected
+   */
+  @AssistedInject
+  public HostRoleCommand(String hostName, Role role,
+                         ServiceComponentHostEvent event, RoleCommand command, boolean retryAllowed, HostDAO hostDAO, ExecutionCommandDAO executionCommandDAO) {
+    this.hostDAO = hostDAO;
+    this.executionCommandDAO = executionCommandDAO;
 
-  public HostRoleCommand(String host, Role role,
-                         ServiceComponentHostEvent event, RoleCommand command, boolean retryAllowed) {
-    this.hostName = host;
     this.role = role;
     this.event = new ServiceComponentHostEventWrapper(event);
     this.roleCommand = command;
     this.retryAllowed = retryAllowed;
+    this.hostEntity = this.hostDAO.findByName(hostName);
   }
 
   @AssistedInject
-  public HostRoleCommand(@Assisted HostRoleCommandEntity hostRoleCommandEntity, Injector injector) {
+  public HostRoleCommand(@Assisted HostRoleCommandEntity hostRoleCommandEntity, HostDAO hostDAO, ExecutionCommandDAO executionCommandDAO) {
+    this.hostDAO = hostDAO;
+    this.executionCommandDAO = executionCommandDAO;
+
     taskId = hostRoleCommandEntity.getTaskId();
     stageId = hostRoleCommandEntity.getStage().getStageId();
     requestId = hostRoleCommandEntity.getStage().getRequestId();
-    this.hostName = hostRoleCommandEntity.getHostName();
+    this.hostEntity = hostRoleCommandEntity.getHostEntity();
     role = hostRoleCommandEntity.getRole();
     status = hostRoleCommandEntity.getStatus();
     stdout = hostRoleCommandEntity.getStdOut() != null ? new String(hostRoleCommandEntity.getStdOut()) : "";
@@ -96,14 +129,11 @@ public class HostRoleCommand {
     event = new ServiceComponentHostEventWrapper(hostRoleCommandEntity.getEvent());
     commandDetail = hostRoleCommandEntity.getCommandDetail();
     customCommandName = hostRoleCommandEntity.getCustomCommandName();
-    //make use of lazy loading
-
-    executionCommandDAO = injector.getInstance(ExecutionCommandDAO.class);
   }
 
   HostRoleCommandEntity constructNewPersistenceEntity() {
     HostRoleCommandEntity hostRoleCommandEntity = new HostRoleCommandEntity();
-    hostRoleCommandEntity.setHostName(hostName);
+    hostRoleCommandEntity.setHostEntity(hostEntity);
     hostRoleCommandEntity.setRole(role);
     hostRoleCommandEntity.setStatus(status);
     hostRoleCommandEntity.setStdError(stderr.getBytes());
@@ -145,7 +175,7 @@ public class HostRoleCommand {
   }
 
   public String getHostName() {
-    return hostName;
+    return hostEntity != null ? hostEntity.getHostName() : null;
   }
 
   public Role getRole() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactory.java
index 1126666..0c92526 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactory.java
@@ -18,8 +18,38 @@
 
 package org.apache.ambari.server.actionmanager;
 
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
 
 public interface HostRoleCommandFactory {
+
+  /**
+   * Constructor via factory.
+   * @param hostName Host name
+   * @param role Action to run
+   * @param event Event on the host and component
+   * @param command Type of command
+   * @return An instance constructed where retryAllowed defaults to false
+   */
+  HostRoleCommand create(String hostName, Role role, ServiceComponentHostEvent event, RoleCommand command);
+
+  /**
+   * Constructor via factory.
+   * @param hostName Host name
+   * @param role Action to run
+   * @param event Event on the host and component
+   * @param command Type of command
+   * @param retryAllowed Whether the command can be repeated
+   * @return An instance of a HostRoleCommand.
+   */
+  HostRoleCommand create(String hostName, Role role, ServiceComponentHostEvent event, RoleCommand command, boolean retryAllowed);
+
+  /**
+   * Constructor via factory
+   * @param hostRoleCommandEntity Object to copy fields from.
+   * @return An instance constructed from the input object.
+   */
   HostRoleCommand createExisting(HostRoleCommandEntity hostRoleCommandEntity);
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactoryImpl.java
index b63adfa..653da89 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommandFactoryImpl.java
@@ -21,10 +21,16 @@ package org.apache.ambari.server.actionmanager;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.orm.dao.ExecutionCommandDAO;
+import org.apache.ambari.server.orm.dao.HostDAO;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
 
 @Singleton
 public class HostRoleCommandFactoryImpl implements HostRoleCommandFactory {
+  
   private Injector injector;
 
   @Inject
@@ -32,8 +38,48 @@ public class HostRoleCommandFactoryImpl implements HostRoleCommandFactory {
     this.injector = injector;
   }
 
+  /**
+   * Constructor via factory.
+   * @param hostName Host name
+   * @param role Action to run
+   * @param event Event on the host and component
+   * @param command Type of command
+   * @return An instance constructed where retryAllowed defaults to false
+   */
+  @Override
+  public HostRoleCommand create(String hostName, Role role,
+                                ServiceComponentHostEvent event, RoleCommand command) {
+    return new HostRoleCommand(hostName, role, event, command,
+        this.injector.getInstance(HostDAO.class),
+        this.injector.getInstance(ExecutionCommandDAO.class));
+  }
+
+  /**
+   * Constructor via factory.
+   * @param hostName Host name
+   * @param role Action to run
+   * @param event Event on the host and component
+   * @param command Type of command
+   * @param retryAllowed Whether the command can be repeated
+   * @return An instance of a HostRoleCommand.
+   */
+  @Override
+  public HostRoleCommand create(String hostName, Role role,
+                                        ServiceComponentHostEvent event, RoleCommand command, boolean retryAllowed) {
+    return new HostRoleCommand(hostName, role, event, command, retryAllowed,
+        this.injector.getInstance(HostDAO.class),
+        this.injector.getInstance(ExecutionCommandDAO.class));
+  }
+
+  /**
+   * Constructor via factory
+   * @param hostRoleCommandEntity Object to copy fields from.
+   * @return An instance constructed from the input object.
+   */
   @Override
   public HostRoleCommand createExisting(HostRoleCommandEntity hostRoleCommandEntity) {
-    return new HostRoleCommand(hostRoleCommandEntity, injector);
+    return new HostRoleCommand(hostRoleCommandEntity,
+        this.injector.getInstance(HostDAO.class),
+        this.injector.getInstance(ExecutionCommandDAO.class));
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 51d5e8a..03b3648 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
@@ -28,6 +28,7 @@ import java.util.TreeMap;
 
 import javax.annotation.Nullable;
 
+import com.google.inject.Inject;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.agent.AgentCommand.AgentCommandType;
@@ -80,6 +81,15 @@ public class Stage {
   private Map<String, List<ExecutionCommandWrapper>> commandsToSend =
       new TreeMap<String, List<ExecutionCommandWrapper>>();
 
+  @Inject
+  private HostRoleCommandFactory hostRoleCommandFactory;
+
+  @Inject
+  private HostRoleCommandDAO hostRoleCommandDAO;
+
+  @Inject
+  private ActionDBAccessor dbAccessor;
+
   @AssistedInject
   public Stage(@Assisted long requestId,
       @Assisted("logDir") String logDir,
@@ -88,7 +98,8 @@ public class Stage {
       @Assisted("requestContext") @Nullable String requestContext,
       @Assisted("clusterHostInfo") String clusterHostInfo,
       @Assisted("commandParamsStage") String commandParamsStage,
-      @Assisted("hostParamsStage") String hostParamsStage) {
+      @Assisted("hostParamsStage") String hostParamsStage,
+      HostRoleCommandFactory hostRoleCommandFactory) {
     this.wrappersLoaded = true;
     this.requestId = requestId;
     this.logDir = logDir;
@@ -99,11 +110,15 @@ public class Stage {
     this.commandParamsStage = commandParamsStage;
     this.hostParamsStage = hostParamsStage;
     this.skippable = false;
+    this.hostRoleCommandFactory = hostRoleCommandFactory;
   }
 
   @AssistedInject
   public Stage(@Assisted StageEntity stageEntity, HostRoleCommandDAO hostRoleCommandDAO,
-      ActionDBAccessor dbAccessor, Clusters clusters) {
+               ActionDBAccessor dbAccessor, Clusters clusters, HostRoleCommandFactory hostRoleCommandFactory) {
+    this.hostRoleCommandFactory = hostRoleCommandFactory;
+    this.hostRoleCommandDAO = hostRoleCommandDAO;
+    this.dbAccessor = dbAccessor;
 
     requestId = stageEntity.getRequestId();
     stageId = stageEntity.getStageId();
@@ -125,19 +140,16 @@ public class Stage {
     commandParamsStage = stageEntity.getCommandParamsStage();
     hostParamsStage = stageEntity.getHostParamsStage();
 
-
     List<Long> taskIds = hostRoleCommandDAO.findTaskIdsByStage(requestId, stageId);
     Collection<HostRoleCommand> commands = dbAccessor.getTasks(taskIds);
 
     for (HostRoleCommand command : commands) {
       String hostname = command.getHostName();
       if (!hostRoleCommands.containsKey(hostname)) {
-//        commandsToSend.put(hostname, new ArrayList<ExecutionCommandWrapper>());
         hostRoleCommands.put(hostname, new LinkedHashMap<String, HostRoleCommand>());
       }
 
       hostRoleCommands.get(hostname).put(command.getRole().toString(), command);
-//      commandsToSend.get(hostname).add(command.getExecutionCommandWrapper());
     }
 
     for (RoleSuccessCriteriaEntity successCriteriaEntity : stageEntity.getRoleSuccessCriterias()) {
@@ -257,7 +269,7 @@ public class Stage {
       RoleCommand command, ServiceComponentHostEvent event, boolean retryAllowed){
 
     //used on stage creation only, no need to check if wrappers loaded
-    HostRoleCommand hrc = new HostRoleCommand(hostName, role, event, command, retryAllowed);
+    HostRoleCommand hrc = hostRoleCommandFactory.create(hostName, role, event, command, retryAllowed);
     ExecutionCommand cmd = new ExecutionCommand();
     ExecutionCommandWrapper wrapper = new ExecutionCommandWrapper(cmd);
     hrc.setExecutionCommandWrapper(wrapper);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/StageFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/StageFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/StageFactoryImpl.java
new file mode 100644
index 0000000..9ee7c16
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/StageFactoryImpl.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.actionmanager;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.assistedinject.Assisted;
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.StageEntity;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
+import org.apache.ambari.server.state.cluster.ClusterImpl;
+
+@Singleton
+public class StageFactoryImpl implements StageFactory {
+  private Injector injector;
+
+  @Inject
+  public StageFactoryImpl(Injector injector) {
+    this.injector = injector;
+  }
+
+  /**
+   * Constructor via the factory.
+   * @param requestId Unique identifier for the request
+   * @param logDir Directory to log to
+   * @param clusterName Cluster name
+   * @param clusterId Cluster ID
+   * @param requestContext Information about the context of the request
+   * @param clusterHostInfo Information about the host
+   * @param commandParamsStage Information about the command parameters
+   * @param hostParamsStage Information about the host parameters for the stage
+   * @return An instance of a Stage with the provided params.
+   */
+  @Override
+  public Stage createNew(long requestId,
+                         @Assisted("logDir") String logDir,
+                         @Assisted("clusterName") String clusterName,
+                         @Assisted("clusterId") long clusterId,
+                         @Assisted("requestContext") String requestContext,
+                         @Assisted("clusterHostInfo") String clusterHostInfo,
+                         @Assisted("commandParamsStage") String commandParamsStage,
+                         @Assisted("hostParamsStage") String hostParamsStage) {
+    return new Stage(requestId, logDir, clusterName, clusterId, requestContext, clusterHostInfo, commandParamsStage, hostParamsStage,
+        injector.getInstance(HostRoleCommandFactory.class));
+  }
+
+  /**
+   * Constructor via the factory.
+   * @param stageEntity Existing stage entity to copy fields form.
+   * @return An instance of a Stage that is created using the provided stage as input.
+   */
+  @Override
+  public Stage createExisting(@Assisted StageEntity stageEntity) {
+    return new Stage(stageEntity, injector.getInstance(HostRoleCommandDAO.class),
+        injector.getInstance(ActionDBAccessor.class), injector.getInstance(Clusters.class),
+        injector.getInstance(HostRoleCommandFactory.class));
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 38c222d..828df47 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -28,6 +28,7 @@ import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
 import org.apache.ambari.server.security.ldap.LdapBatchDto;
 import org.apache.ambari.server.security.ldap.LdapSyncDto;
+import org.apache.ambari.server.stageplanner.RoleGraphFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ConfigHelper;
@@ -523,6 +524,13 @@ public interface AmbariManagementController {
   public ConfigGroupFactory getConfigGroupFactory();
 
   /**
+   * Get the role graph factory for this management controller.
+   *
+   * @return the role graph factory
+   */
+  public RoleGraphFactory getRoleGraphFactory();
+
+  /**
     * Get the action manager for this management controller.
     *
     * @return the action manager

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index b2120ab..614134e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -111,6 +111,7 @@ import org.apache.ambari.server.security.ldap.LdapSyncDto;
 import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationException;
 import org.apache.ambari.server.stageplanner.RoleGraph;
+import org.apache.ambari.server.stageplanner.RoleGraphFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.CommandScriptDefinition;
@@ -211,6 +212,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   @Inject
   private AbstractRootServiceResponseFactory rootServiceResponseFactory;
   @Inject
+  private RoleGraphFactory roleGraphFactory;
+  @Inject
   private ConfigGroupFactory configGroupFactory;
   @Inject
   private ConfigHelper configHelper;
@@ -2230,7 +2233,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       }
 
       RoleCommandOrder rco = getRoleCommandOrder(cluster);
-      RoleGraph rg = new RoleGraph(rco);
+      RoleGraph rg = roleGraphFactory.createNew(rco);
 
       rg.build(stage);
       requestStages.addStages(rg.getStages());
@@ -3093,9 +3096,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     RoleGraph rg;
     if (null != cluster) {
       RoleCommandOrder rco = getRoleCommandOrder(cluster);
-      rg = new RoleGraph(rco);
+      rg = roleGraphFactory.createNew(rco);
     } else {
-      rg = new RoleGraph();
+      rg = roleGraphFactory.createNew();
     }
 
     rg.build(stage);
@@ -3767,6 +3770,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   @Override
+  public RoleGraphFactory getRoleGraphFactory() {
+    return roleGraphFactory;
+  }
+
+  @Override
   public AbstractRootServiceResponseFactory getRootServiceResponseFactory() {
     return rootServiceResponseFactory;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 0c5e04a..36ae66b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -55,6 +55,7 @@ import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.actionmanager.HostRoleCommandFactoryImpl;
 import org.apache.ambari.server.actionmanager.RequestFactory;
 import org.apache.ambari.server.actionmanager.StageFactory;
+import org.apache.ambari.server.actionmanager.StageFactoryImpl;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType;
 import org.apache.ambari.server.configuration.Configuration.DatabaseType;
@@ -75,6 +76,8 @@ import org.apache.ambari.server.security.SecurityHelper;
 import org.apache.ambari.server.security.SecurityHelperImpl;
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandlerFactory;
 import org.apache.ambari.server.stack.StackManagerFactory;
+import org.apache.ambari.server.stageplanner.RoleGraphFactory;
+import org.apache.ambari.server.stageplanner.RoleGraphFactoryImpl;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -359,6 +362,10 @@ public class ControllerModule extends AbstractModule {
     return jpaPersistModule;
   }
 
+  /**
+   * Bind classes to their Factories, which can be built on-the-fly.
+   * Often, will also have to edit AgentResourceTest.java
+   */
   private void installFactories() {
     install(new FactoryModuleBuilder().implement(
         Cluster.class, ClusterImpl.class).build(ClusterFactory.class));
@@ -389,10 +396,11 @@ public class ControllerModule extends AbstractModule {
     install(new FactoryModuleBuilder().implement(RequestExecution.class,
         RequestExecutionImpl.class).build(RequestExecutionFactory.class));
 
-    install(new FactoryModuleBuilder().build(StageFactory.class));
+    bind(StageFactory.class).to(StageFactoryImpl.class);
+    bind(RoleGraphFactory.class).to(RoleGraphFactoryImpl.class);
     install(new FactoryModuleBuilder().build(RequestFactory.class));
     install(new FactoryModuleBuilder().build(StackManagerFactory.class));
-
+    
     bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
     bind(SecurityHelper.class).toInstance(SecurityHelperImpl.getInstance());
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
index 1bb0d0f..f198523 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
@@ -19,6 +19,7 @@
 package org.apache.ambari.server.controller;
 
 import com.google.inject.Inject;
+import com.google.inject.Injector;
 import com.google.inject.persist.Transactional;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
@@ -68,6 +69,7 @@ import org.apache.ambari.server.serveraction.kerberos.KerberosRealmException;
 import org.apache.ambari.server.serveraction.kerberos.KerberosServerAction;
 import org.apache.ambari.server.serveraction.kerberos.UpdateKerberosConfigsServerAction;
 import org.apache.ambari.server.stageplanner.RoleGraph;
+import org.apache.ambari.server.stageplanner.RoleGraphFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -155,6 +157,9 @@ public class KerberosHelper {
   private StageFactory stageFactory;
 
   @Inject
+  private RoleGraphFactory roleGraphFactory;
+
+  @Inject
   private Clusters clusters;
 
   @Inject
@@ -181,7 +186,6 @@ public class KerberosHelper {
    */
   private static ClusterController clusterController = null;
 
-
   /**
    * Toggles Kerberos security to enable it or remove it depending on the state of the cluster.
    * <p/>
@@ -2097,7 +2101,7 @@ public class KerberosHelper {
           "Create Principals",
           1200);
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }
@@ -2120,7 +2124,7 @@ public class KerberosHelper {
           "Destroy Principals",
           1200);
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }
@@ -2143,7 +2147,7 @@ public class KerberosHelper {
           "Create Keytabs",
           1200);
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }
@@ -2182,7 +2186,7 @@ public class KerberosHelper {
         customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestParams, false);
       }
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }
@@ -2247,7 +2251,7 @@ public class KerberosHelper {
         customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestParams, false);
       }
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }
@@ -2270,7 +2274,7 @@ public class KerberosHelper {
           "Update Service Configurations",
           1200);
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }
@@ -2298,7 +2302,7 @@ public class KerberosHelper {
           commandParameters,
           "Finalize Operations", 300);
 
-      RoleGraph roleGraph = new RoleGraph(roleCommandOrder);
+      RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder);
       roleGraph.build(stage);
       requestStageContainer.addStages(roleGraph.getStages());
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index b952c7c..4e6877e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -33,6 +33,7 @@ import org.apache.ambari.server.Role;
 import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.actionmanager.RequestFactory;
 import org.apache.ambari.server.actionmanager.Stage;
@@ -55,10 +56,13 @@ import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
@@ -143,6 +147,9 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
   @Inject
   private static RepositoryVersionDAO repositoryVersionDAO;
 
+  @Inject
+  private static HostRoleCommandFactory hostRoleCommandFactory;
+
   private static Gson gson = StageUtils.getGson();
 
   @Inject
@@ -152,6 +159,9 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
   private static StageFactory stageFactory;
 
   @Inject
+  private static ClusterDAO clusterDAO;
+
+  @Inject
   private static RequestFactory requestFactory;
 
   @Inject
@@ -497,6 +507,19 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
           String.format("Invalid desired state %s. Should be either CURRENT or INSTALLED",
                   newStateStr));
       }
+
+      // Get a host name to populate the hostrolecommand table's hostEntity.
+      ClusterEntity cluster = clusterDAO.findByName(clName);
+      String defaultHostName = null;
+      List<HostEntity> hosts = new ArrayList(cluster.getHostEntities());
+      if (hosts != null && !hosts.isEmpty()) {
+        Collections.sort(hosts);
+        defaultHostName = hosts.get(0).getHostName();
+      }
+      if (defaultHostName == null) {
+        throw new AmbariException("Could not find at least one host to set the command for");
+      }
+
       args.put(FinalizeUpgradeAction.VERSION_KEY, desiredRepoVersion);
       args.put(FinalizeUpgradeAction.CLUSTER_NAME_KEY, clName);
 
@@ -504,7 +527,8 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       command.setCommandParams(args);
       command.setClusterName(clName);
       finalizeUpgradeAction.setExecutionCommand(command);
-      HostRoleCommand hostRoleCommand = new HostRoleCommand("none",
+      
+      HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(defaultHostName,
               Role.AMBARI_SERVER_ACTION, null, null);
       finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 926d9bb..483e169 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
@@ -789,7 +789,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
 
   private void makeServerSideStage(UpgradeContext context, RequestStageContainer request,
                                    UpgradeItemEntity entity, ServerSideActionTask task,
-                                   boolean skippable, boolean allowRtery) throws AmbariException {
+                                   boolean skippable, boolean allowRetry) throws AmbariException {
 
     Cluster cluster = context.getCluster();
 
@@ -894,7 +894,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         itemDetail,
         null,
         Integer.valueOf(1200),
-        allowRtery);
+        allowRetry);
 
     request.addStages(Collections.singletonList(stage));
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java
index dcc06a7..7a8c4b9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java
@@ -31,6 +31,7 @@ import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.HostDAO;
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -154,9 +155,9 @@ public class HostVersionOutOfSyncListener {
       for (ClusterVersionEntity clusterVersion : allClusterVersions) {
         if (clusterVersion.getState() != RepositoryVersionState.CURRENT) { // Current version is taken care of automatically
           String hostName = event.getHostName();
-          HostVersionEntity missingHostVersion = new HostVersionEntity(hostName,
+          HostEntity hostEntity = hostDAO.get().findByName(hostName);
+          HostVersionEntity missingHostVersion = new HostVersionEntity(hostEntity,
                   clusterVersion.getRepositoryVersion(), RepositoryVersionState.OUT_OF_SYNC);
-          missingHostVersion.setHostEntity(hostDAO.get().findByName(hostName));
           hostVersionDAO.get().create(missingHostVersion);
           changedRepositoryVersions.add(clusterVersion.getRepositoryVersion().getVersion());
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
index 279c78f..29cf755 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
@@ -204,11 +204,20 @@ public class DBAccessorImpl implements DBAccessor {
   public boolean tableHasData(String tableName) throws SQLException {
     String query = "SELECT count(*) from " + tableName;
     Statement statement = getConnection().createStatement();
-    ResultSet rs = statement.executeQuery(query);
     boolean retVal = false;
-    if (rs != null) {
-      if (rs.next()) {
-        return rs.getInt(1) > 0;
+    ResultSet rs = null;
+    try {
+       rs = statement.executeQuery(query);
+      if (rs != null) {
+        if (rs.next()) {
+          return rs.getInt(1) > 0;
+        }
+      }
+    } catch (Exception e) {
+      LOG.error("Unable to check if table " + tableName + " has any data. Exception: " + e.getMessage());
+    } finally {
+      if (rs != null) {
+        rs.close();
       }
     }
     return retVal;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 f927197..7d3f4e4 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
@@ -167,7 +167,7 @@ public class HostRoleCommandDAO {
   public List<Long> findTaskIdsByHostRoleAndStatus(String hostname, String role, HostRoleStatus status) {
     TypedQuery<Long> query = entityManagerProvider.get().createQuery(
         "SELECT DISTINCT task.taskId FROM HostRoleCommandEntity task " +
-            "WHERE task.hostName=?1 AND task.role=?2 AND task.status=?3 " +
+            "WHERE task.hostEntity.hostName=?1 AND task.role=?2 AND task.status=?3 " +
             "ORDER BY task.taskId", Long.class
     );
 
@@ -188,9 +188,9 @@ public class HostRoleCommandDAO {
   public List<HostRoleCommandEntity> findSortedCommandsByStageAndHost(StageEntity stageEntity, HostEntity hostEntity) {
     TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createQuery("SELECT hostRoleCommand " +
         "FROM HostRoleCommandEntity hostRoleCommand " +
-        "WHERE hostRoleCommand.stage=?1 AND hostRoleCommand.host=?2 " +
+        "WHERE hostRoleCommand.stage=?1 AND hostRoleCommand.hostEntity.hostName=?2 " +
         "ORDER BY hostRoleCommand.taskId", HostRoleCommandEntity.class);
-    return daoUtils.selectList(query, stageEntity, hostEntity);
+    return daoUtils.selectList(query, stageEntity, hostEntity.getHostName());
   }
 
   @RequiresSession
@@ -198,7 +198,7 @@ public class HostRoleCommandDAO {
     TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createQuery("SELECT hostRoleCommand " +
         "FROM HostRoleCommandEntity hostRoleCommand " +
         "WHERE hostRoleCommand.stage=?1 " +
-        "ORDER BY hostRoleCommand.hostName, hostRoleCommand.taskId", HostRoleCommandEntity.class);
+        "ORDER BY hostRoleCommand.hostEntity.hostName, hostRoleCommand.taskId", HostRoleCommandEntity.class);
     List<HostRoleCommandEntity> commandEntities = daoUtils.selectList(query, stageEntity);
 
     Map<String, List<HostRoleCommandEntity>> hostCommands = new HashMap<String, List<HostRoleCommandEntity>>();
@@ -229,7 +229,7 @@ public class HostRoleCommandDAO {
   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.hostName=?1 AND command.requestId=?2 " +
+        "WHERE command.hostEntity.hostName=?1 AND command.requestId=?2 " +
         "AND command.stageId=?3 AND command.role=?4 " +
         "ORDER BY command.taskId", HostRoleCommandEntity.class);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
index c329f24..1ed1020 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
@@ -142,7 +142,7 @@ public class HostEntity implements Comparable<HostEntity> {
   @OneToOne(mappedBy = "hostEntity", cascade = {CascadeType.REMOVE, CascadeType.PERSIST})
   private HostStateEntity hostStateEntity;
 
-  @OneToMany(mappedBy = "host", cascade = CascadeType.REMOVE)
+  @OneToMany(mappedBy = "hostEntity", cascade = CascadeType.REMOVE)
   private Collection<HostRoleCommandEntity> hostRoleCommandEntities;
 
   public Long getHostId() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 c9877fb..a2bbd1c 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
@@ -75,9 +75,9 @@ public class HostRoleCommandEntity {
   @Basic
   private Long stageId;
 
-  @Column(name = "host_name", insertable = false, updatable = false, nullable = false)
+  @Column(name = "host_id", insertable = false, updatable = false, nullable = false)
   @Basic
-  private String hostName;
+  private Long hostId;
 
   @Column(name = "role")
   private String role;
@@ -161,8 +161,8 @@ public class HostRoleCommandEntity {
   private StageEntity stage;
 
   @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
-  @JoinColumn(name = "host_name", referencedColumnName = "host_name", nullable = false)
-  private HostEntity host;
+  @JoinColumn(name = "host_id", referencedColumnName = "host_id", nullable = false)
+  private HostEntity hostEntity;
 
   public Long getTaskId() {
     return taskId;
@@ -189,11 +189,7 @@ public class HostRoleCommandEntity {
   }
 
   public String getHostName() {
-    return hostName;
-  }
-
-  public void setHostName(String hostName) {
-    this.hostName = hostName;
+    return hostEntity != null ? hostEntity.getHostName() : null;
   }
 
   public Role getRole() {
@@ -360,7 +356,7 @@ public class HostRoleCommandEntity {
     if (exitcode != null ? !exitcode.equals(that.exitcode) : that.exitcode != null) {
       return false;
     }
-    if (hostName != null ? !hostName.equals(that.hostName) : that.hostName != null) {
+    if (hostEntity != null ? !hostEntity.equals(that.hostEntity) : that.hostEntity != null) {
       return false;
     }
     if (lastAttemptTime != null ? !lastAttemptTime.equals(that.lastAttemptTime) : that.lastAttemptTime != null) {
@@ -411,7 +407,7 @@ public class HostRoleCommandEntity {
     int result = taskId != null ? taskId.hashCode() : 0;
     result = 31 * result + (requestId != null ? requestId.hashCode() : 0);
     result = 31 * result + (stageId != null ? stageId.hashCode() : 0);
-    result = 31 * result + (hostName != null ? hostName.hashCode() : 0);
+    result = 31 * result + (hostEntity != null ? hostEntity.hashCode() : 0);
     result = 31 * result + (role != null ? role.hashCode() : 0);
     result = 31 * result + (event != null ? event.hashCode() : 0);
     result = 31 * result + (exitcode != null ? exitcode.hashCode() : 0);
@@ -444,11 +440,11 @@ public class HostRoleCommandEntity {
     this.stage = stage;
   }
 
-  public HostEntity getHost() {
-    return host;
+  public HostEntity getHostEntity() {
+    return hostEntity;
   }
 
-  public void setHost(HostEntity host) {
-    this.host = host;
+  public void setHostEntity(HostEntity hostEntity) {
+    this.hostEntity = hostEntity;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
index 5fb024d..9d7d68f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java
@@ -49,20 +49,20 @@ import org.apache.ambari.server.state.RepositoryVersionState;
 
     @NamedQuery(name = "hostVersionByClusterAndHostname", query =
         "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN host.clusterEntities clusters " +
-            "WHERE clusters.clusterName=:clusterName AND hostVersion.hostName=:hostName"),
+            "WHERE clusters.clusterName=:clusterName AND hostVersion.hostEntity.hostName=:hostName"),
 
     @NamedQuery(name = "hostVersionByHostname", query =
         "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host " +
-            "WHERE hostVersion.hostName=:hostName"),
+            "WHERE hostVersion.hostEntity.hostName=:hostName"),
 
     @NamedQuery(name = "hostVersionByClusterHostnameAndState", query =
         "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN host.clusterEntities clusters " +
-            "WHERE clusters.clusterName=:clusterName AND hostVersion.hostName=:hostName AND hostVersion.state=:state"),
+            "WHERE clusters.clusterName=:clusterName AND hostVersion.hostEntity.hostName=:hostName AND hostVersion.state=:state"),
 
     @NamedQuery(name = "hostVersionByClusterStackVersionAndHostname", query =
         "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN host.clusterEntities clusters " +
             "WHERE clusters.clusterName=:clusterName AND hostVersion.repositoryVersion.stack.stackName=:stackName AND hostVersion.repositoryVersion.stack.stackVersion=:stackVersion AND hostVersion.repositoryVersion.version=:version AND " +
-            "hostVersion.hostName=:hostName"),
+            "hostVersion.hostEntity.hostName=:hostName"),
 })
 public class HostVersionEntity {
 
@@ -71,15 +71,15 @@ public class HostVersionEntity {
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "host_version_id_generator")
   private Long id;
 
-  @Column(name = "host_name", nullable = false, insertable = false, updatable = false)
-  private String hostName;
-
   @ManyToOne
   @JoinColumn(name = "repo_version_id", referencedColumnName = "repo_version_id", nullable = false)
   private RepositoryVersionEntity repositoryVersion;
 
+  @Column(name = "host_id", nullable=false, insertable = false, updatable = false)
+  private Long hostId;
+
   @ManyToOne
-  @JoinColumn(name = "host_name", referencedColumnName = "host_name", nullable = false)
+  @JoinColumn(name = "host_id", referencedColumnName = "host_id", nullable = false)
   private HostEntity hostEntity;
 
   @Column(name = "state", nullable = false, insertable = true, updatable = true)
@@ -96,8 +96,8 @@ public class HostVersionEntity {
    * When using this constructor, you should also call setHostEntity(). Otherwise
    * you will have persistence errors when persisting the instance.
    */
-  public HostVersionEntity(String hostName, RepositoryVersionEntity repositoryVersion, RepositoryVersionState state) {
-    this.hostName = hostName;
+  public HostVersionEntity(HostEntity hostEntity, RepositoryVersionEntity repositoryVersion, RepositoryVersionState state) {
+    this.hostEntity = hostEntity;
     this.repositoryVersion = repositoryVersion;
     this.state = state;
   }
@@ -106,9 +106,9 @@ public class HostVersionEntity {
    * This constructor is mainly used by the unit tests in order to construct an object without the id.
    */
   public HostVersionEntity(HostVersionEntity other) {
-    hostName = other.hostName;
-    repositoryVersion = other.repositoryVersion;
-    state = other.state;
+    this.hostEntity = other.hostEntity;
+    this.repositoryVersion = other.repositoryVersion;
+    this.state = other.state;
   }
 
   public Long getId() {
@@ -120,11 +120,7 @@ public class HostVersionEntity {
   }
 
   public String getHostName() {
-    return hostName;
-  }
-
-  public void setHostName(String hostName) {
-    this.hostName = hostName;
+    return hostEntity != null ? hostEntity.getHostName() : null;
   }
 
   public HostEntity getHostEntity() {
@@ -156,7 +152,7 @@ public class HostVersionEntity {
     final int prime = 31;
     int result = 1;
     result = prime * result + ((hostEntity == null) ? 0 : hostEntity.hashCode());
-    result = prime * result + ((hostName == null) ? 0 : hostName.hashCode());
+    result = prime * result + ((hostEntity == null) ? 0 : hostEntity.hashCode());
     result = prime * result + ((id == null) ? 0 : id.hashCode());
     result = prime * result + ((repositoryVersion == null) ? 0 : repositoryVersion.hashCode());
     result = prime * result + ((state == null) ? 0 : state.hashCode());
@@ -165,48 +161,15 @@ public class HostVersionEntity {
 
   @Override
   public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
+    if (this == obj) return true;
+    if (obj == null) return false;
+    if (getClass() != obj.getClass()) return false;
 
     HostVersionEntity other = (HostVersionEntity) obj;
-    if (hostEntity == null) {
-      if (other.hostEntity != null) {
-        return false;
-      }
-    } else if (!hostEntity.equals(other.hostEntity)) {
-      return false;
-    }
-    if (hostName == null) {
-      if (other.hostName != null) {
-        return false;
-      }
-    } else if (!hostName.equals(other.hostName)) {
-      return false;
-    }
-    if (id == null) {
-      if (other.id != null) {
-        return false;
-      }
-    } else if (!id.equals(other.id)) {
-      return false;
-    }
-    if (repositoryVersion == null) {
-      if (other.repositoryVersion != null) {
-        return false;
-      }
-    } else if (!repositoryVersion.equals(other.repositoryVersion)) {
-      return false;
-    }
-    if (state != other.state) {
-      return false;
-    }
+    if (id != null ? id != other.id : other.id != null) return false;
+    if (hostEntity != null ? !hostEntity.equals(other.hostEntity) : other.hostEntity != null) return false;
+    if (repositoryVersion != null ? !repositoryVersion.equals(other.repositoryVersion) : other.repositoryVersion != null) return false;
+    if (state != other.state) return false;
     return true;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraph.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraph.java b/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraph.java
index 4fe3787..0b1854a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraph.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraph.java
@@ -22,8 +22,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
+import com.google.inject.Inject;
+import com.google.inject.Injector;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.Stage;
+import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -32,15 +35,23 @@ public class RoleGraph {
 
   private static Log LOG = LogFactory.getLog(RoleGraph.class);
 
+  
   Map<String, RoleGraphNode> graph = null;
   private RoleCommandOrder roleDependencies;
   private Stage initialStage = null;
   private boolean sameHostOptimization = true;
 
-  public RoleGraph() {
+  @Inject
+  private StageFactory stageFactory;
+
+  @Inject
+  public RoleGraph(StageFactory stageFactory) {
+    this.stageFactory = stageFactory;
   }
-  
-  public RoleGraph(RoleCommandOrder rd) {
+
+  @Inject
+  public RoleGraph(RoleCommandOrder rd, StageFactory stageFactory) {
+    this(stageFactory);
     this.roleDependencies = rd;
   }
 
@@ -136,7 +147,7 @@ public class RoleGraph {
   private Stage getStageFromGraphNodes(Stage origStage,
       List<RoleGraphNode> stageGraphNodes) {
 
-    Stage newStage = new Stage(origStage.getRequestId(),
+    Stage newStage = stageFactory.createNew(origStage.getRequestId(),
         origStage.getLogDir(), origStage.getClusterName(),
         origStage.getClusterId(),
         origStage.getRequestContext(), origStage.getClusterHostInfo(),

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactory.java
new file mode 100644
index 0000000..625b168
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactory.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.stageplanner;
+
+import org.apache.ambari.server.metadata.RoleCommandOrder;
+
+public interface RoleGraphFactory {
+  /**
+   *
+   * @return
+   */
+  public RoleGraph createNew();
+
+  /**
+   *
+   * @param rd
+   * @return
+   */
+  public RoleGraph createNew(RoleCommandOrder rd);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactoryImpl.java
new file mode 100644
index 0000000..5ca4d88
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stageplanner/RoleGraphFactoryImpl.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.stageplanner;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import org.apache.ambari.server.actionmanager.StageFactory;
+import org.apache.ambari.server.metadata.RoleCommandOrder;
+
+
+@Singleton
+public class RoleGraphFactoryImpl implements RoleGraphFactory {
+  private Injector injector;
+
+  @Inject
+  public RoleGraphFactoryImpl(Injector injector) {
+    this.injector = injector;
+  }
+
+  /**
+   *
+   * @return
+   */
+  @Override
+  public RoleGraph createNew() {
+    return new RoleGraph(this.injector.getInstance(StageFactory.class));
+  }
+
+  /**
+   *
+   * @param rd
+   * @return
+   */
+  @Override
+  public RoleGraph createNew(RoleCommandOrder rd) {
+    return new RoleGraph(rd, this.injector.getInstance(StageFactory.class));
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 9643fe1..0d9c36a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -1044,8 +1044,7 @@ public class ClusterImpl implements Cluster {
           if (!intersection.contains(hostname)) {
             // According to the business logic, we don't create objects in a CURRENT state.
             HostEntity hostEntity = hostDAO.findByName(hostname);
-            HostVersionEntity hostVersionEntity = new HostVersionEntity(hostname, currentClusterVersion.getRepositoryVersion(), desiredState);
-            hostVersionEntity.setHostEntity(hostEntity);
+            HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntity, currentClusterVersion.getRepositoryVersion(), desiredState);
             hostVersionDAO.create(hostVersionEntity);
           } else {
             HostVersionEntity hostVersionEntity = existingHostToHostVersionEntity.get(hostname);
@@ -1122,10 +1121,9 @@ public class ClusterImpl implements Cluster {
         if (hostsMissingRepoVersion.contains(hostname)) {
           // Create new host stack version
           HostEntity hostEntity = hostDAO.findByName(hostname);
-          HostVersionEntity hostVersionEntity = new HostVersionEntity(hostname,
+          HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntity,
               sourceClusterVersion.getRepositoryVersion(),
               RepositoryVersionState.INSTALLING);
-          hostVersionEntity.setHostEntity(hostEntity);
           hostVersionDAO.create(hostVersionEntity);
         } else {
           // Update existing host stack version
@@ -1347,8 +1345,7 @@ public class ClusterImpl implements Cluster {
     try {
       // Create one if it doesn't already exist. It will be possible to make further transitions below.
       if (hostVersionEntity == null) {
-        hostVersionEntity = new HostVersionEntity(host.getHostName(), repositoryVersion, RepositoryVersionState.UPGRADING);
-        hostVersionEntity.setHostEntity(host);
+        hostVersionEntity = new HostVersionEntity(host, repositoryVersion, RepositoryVersionState.UPGRADING);
         hostVersionDAO.create(hostVersionEntity);
       }
 
@@ -1565,11 +1562,7 @@ public class ClusterImpl implements Cluster {
             }
             if (null == target) {
               // If no matching version was found, create one with the desired state
-              HostVersionEntity hve = new HostVersionEntity();
-              hve.setHostEntity(he);
-              hve.setHostName(he.getHostName());
-              hve.setRepositoryVersion(existingClusterVersion.getRepositoryVersion());
-              hve.setState(state);
+              HostVersionEntity hve = new HostVersionEntity(he, existingClusterVersion.getRepositoryVersion(), state);
               hostVersionDAO.create(hve);
             }
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
index 8897657..40d2241 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
@@ -33,6 +33,7 @@ import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
 import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.dao.DaoUtils;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -83,6 +84,9 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
   private static final DBColumnInfo CURRENT_STACK_ID_COLUMN = new DBColumnInfo(CURRENT_STACK_ID_COLUMN_NAME, Long.class, null, null, true);
   private static final DBColumnInfo STACK_ID_COLUMN = new DBColumnInfo(STACK_ID_COLUMN_NAME, Long.class, null, null, true);
 
+  @Inject
+  DaoUtils daoUtils;
+  
   /**
    * {@inheritDoc}
    */
@@ -123,6 +127,8 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
   public UpgradeCatalog210(Injector injector) {
     super(injector);
     this.injector = injector;
+
+    daoUtils = injector.getInstance(DaoUtils.class);
   }
 
   // ----- AbstractUpgradeCatalog --------------------------------------------
@@ -154,6 +160,14 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
   private void executeHostsDDLUpdates() throws AmbariException, SQLException {
     Configuration.DatabaseType databaseType = configuration.getDatabaseType();
 
+    String randomHostName = null;
+    if (dbAccessor.tableHasData(HOST_ROLE_COMMAND_TABLE)) {
+      randomHostName = getRandomHostName();
+      if (StringUtils.isBlank(randomHostName)) {
+        throw new AmbariException("UpgradeCatalog210 could not retrieve a random host_name from the hosts table while running executeHostsDDLUpdates.");
+      }
+    }
+
     dbAccessor.addColumn(HOSTS_TABLE, new DBColumnInfo(HOST_ID_COL, Long.class, null, null, true));
 
     // Sequence value for the hosts table primary key. First record will be 1, so ambari_sequence value must be 0.
@@ -232,7 +246,7 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
         dbAccessor.executeQuery("ALTER TABLE " + HOSTS_TABLE + " DROP CONSTRAINT " + constraintName);
       }
     } else {
-      dbAccessor.dropConstraint(HOSTS_TABLE, "hosts_pkey");
+      dbAccessor.executeQuery("ALTER TABLE " + HOSTS_TABLE + " DROP CONSTRAINT hosts_pkey");
     }
     dbAccessor.executeQuery("ALTER TABLE " + HOSTS_TABLE + " ADD CONSTRAINT PK_hosts_id PRIMARY KEY (host_id)");
     dbAccessor.executeQuery("ALTER TABLE " + HOSTS_TABLE + " ADD CONSTRAINT UQ_hosts_host_name UNIQUE (host_name)");
@@ -240,10 +254,6 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
 
     // TODO, for now, these still point to the host_name and will be fixed one table at a time to point to the host id.
     // Re-add the FKs
-    dbAccessor.addFKConstraint(HOST_VERSION_TABLE, "FK_host_version_host_name",
-        "host_name", HOSTS_TABLE, "host_name", false);
-    dbAccessor.addFKConstraint(HOST_ROLE_COMMAND_TABLE, "FK_host_role_command_host_name",
-        "host_name", HOSTS_TABLE, "host_name", false);
     dbAccessor.addFKConstraint(HOST_CONFIG_MAPPING_TABLE, "FK_hostconfmapping_host_name",
         "host_name", HOSTS_TABLE, "host_name", false);
     dbAccessor.addFKConstraint(CONFIG_GROUP_HOST_MAPPING_TABLE, "FK_cghm_hname",
@@ -258,12 +268,21 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
         CLUSTER_HOST_MAPPING_TABLE,
         HOST_COMPONENT_STATE_TABLE,
         HOST_COMPONENT_DESIRED_STATE_TABLE,
-        HOST_STATE_TABLE
+        HOST_ROLE_COMMAND_TABLE,
+        HOST_STATE_TABLE,
+        HOST_VERSION_TABLE
     };
+
     for (String tableName : tablesToAddHostID) {
       dbAccessor.addColumn(tableName, new DBColumnInfo(HOST_ID_COL, Long.class, null, null, true));
       dbAccessor.executeQuery("UPDATE " + tableName + " t SET host_id = (SELECT host_id FROM hosts h WHERE h.host_name = t.host_name) WHERE t.host_id IS NULL AND t.host_name IS NOT NULL");
 
+      // For legacy reasons, the hostrolecommand table will contain "none" for some records where the host_name was not important.
+      // These records were populated during Finalize in Rolling Upgrade, so they must be updated to use a valid host_name.
+      if (tableName == HOST_ROLE_COMMAND_TABLE && StringUtils.isNotBlank(randomHostName)) {
+        dbAccessor.executeQuery("UPDATE " + tableName + " t SET host_id = (SELECT host_id FROM hosts h WHERE h.host_name = '" + randomHostName + "') WHERE t.host_id IS NULL AND t.host_name = 'none'");
+      }
+
       if (databaseType == Configuration.DatabaseType.DERBY) {
         // This is a workaround for UpgradeTest.java unit test
         dbAccessor.executeQuery("ALTER TABLE " + tableName + " ALTER column " + HOST_ID_COL + " NOT NULL");
@@ -302,11 +321,10 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
         }
       }
     } else {
-
-      dbAccessor.dropConstraint(CLUSTER_HOST_MAPPING_TABLE, "clusterhostmapping_pkey");
-      dbAccessor.dropConstraint(HOST_COMPONENT_STATE_TABLE, "hostcomponentstate_pkey");
-      dbAccessor.dropConstraint(HOST_COMPONENT_DESIRED_STATE_TABLE, "hostcomponentdesiredstate_pkey");
-      dbAccessor.dropConstraint(HOST_STATE_TABLE, "hoststate_pkey");
+      dbAccessor.executeQuery("ALTER TABLE " + CLUSTER_HOST_MAPPING_TABLE + " DROP CONSTRAINT clusterhostmapping_pkey");
+      dbAccessor.executeQuery("ALTER TABLE " + HOST_COMPONENT_STATE_TABLE + " DROP CONSTRAINT hostcomponentstate_pkey");
+      dbAccessor.executeQuery("ALTER TABLE " + HOST_COMPONENT_DESIRED_STATE_TABLE + " DROP CONSTRAINT hostcomponentdesiredstate_pkey");
+      dbAccessor.executeQuery("ALTER TABLE " + HOST_STATE_TABLE + " DROP CONSTRAINT hoststate_pkey");
       // TODO, include other tables.
     }
     dbAccessor.executeQuery("ALTER TABLE " + CLUSTER_HOST_MAPPING_TABLE +
@@ -323,7 +341,9 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
     dbAccessor.dropColumn(CLUSTER_HOST_MAPPING_TABLE, "host_name");
     dbAccessor.dropColumn(HOST_COMPONENT_STATE_TABLE, "host_name");
     dbAccessor.dropColumn(HOST_COMPONENT_DESIRED_STATE_TABLE, "host_name");
+    dbAccessor.dropColumn(HOST_ROLE_COMMAND_TABLE, "host_name");
     dbAccessor.dropColumn(HOST_STATE_TABLE, "host_name");
+    dbAccessor.dropColumn(HOST_VERSION_TABLE, "host_name");
     // TODO, include other tables.
 
     // view columns for cluster association
@@ -565,9 +585,8 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
         while (resultSet.next()) {
           hostId++;
           final String hostName = resultSet.getString(1);
-          Long currHostID = resultSet.getLong(2); // in case of a retry, may not be null
 
-          if (currHostID == null && StringUtils.isNotBlank(hostName)) {
+          if (StringUtils.isNotBlank(hostName)) {
             dbAccessor.executeQuery("UPDATE " + HOSTS_TABLE + " SET host_id = " + hostId +
                 " WHERE host_name = '" + hostName + "'");
           }
@@ -579,6 +598,24 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
     return hostId;
   }
 
+  private String getRandomHostName() throws SQLException {
+    String randomHostName = null;
+    ResultSet resultSet = null;
+    try {
+      resultSet = dbAccessor.executeSelect("SELECT host_name FROM hosts ORDER BY host_name ASC");
+      if (resultSet != null && resultSet.next()) {
+        randomHostName = resultSet.getString(1);
+      }
+    } catch (Exception e) {
+      LOG.error("Failed to retrieve random host name. Exception: " + e.getMessage());
+    } finally {
+      if (resultSet != null) {
+        resultSet.close();
+      }
+    }
+    return randomHostName;
+  }
+
   /**
    * Get the constraint name created by Derby if one was not specified for the table.
    * @param type Constraint-type, either, "p" (Primary), "c" (Check), "f" (Foreign), "u" (Unique)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
index 020dd4b..9bf2ac4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
@@ -19,10 +19,12 @@ package org.apache.ambari.server.utils;
 
 import com.google.common.base.Joiner;
 import com.google.gson.Gson;
+import com.google.inject.Inject;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.actionmanager.Stage;
+import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.controller.ActionExecutionContext;
 import org.apache.ambari.server.state.Cluster;
@@ -76,6 +78,14 @@ public class StageUtils {
       new HashMap<String, String>();
   private volatile static Gson gson;
 
+  @Inject
+  private static StageFactory stageFactory;
+
+  @Inject
+  public StageUtils(StageFactory stageFactory) {
+    StageUtils.stageFactory = stageFactory;
+  }
+
   private static String server_hostname;
   static {
     try {
@@ -166,9 +176,9 @@ public class StageUtils {
   }
 
   //For testing only
+  @Inject
   public static Stage getATestStage(long requestId, long stageId, String hostname, String clusterHostInfo, String commandParamsStage, String hostParamsStage) {
-
-    Stage s = new Stage(requestId, "/tmp", "cluster1", 1L, "context", clusterHostInfo, commandParamsStage, hostParamsStage);
+    Stage s = stageFactory.createNew(requestId, "/tmp", "cluster1", 1L, "context", clusterHostInfo, commandParamsStage, hostParamsStage);
     s.setStageId(stageId);
     long now = System.currentTimeMillis();
     s.addHostRoleExecutionCommand(hostname, Role.NAMENODE, RoleCommand.INSTALL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 62a8541..b6f2aaa 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -170,8 +170,7 @@ CREATE TABLE hoststate (
 CREATE TABLE host_version (
   id BIGINT NOT NULL,
   repo_version_id BIGINT NOT NULL,
-  host_name VARCHAR(255) NOT NULL,
-  -- host_id BIGINT NOT NULL,
+  host_id BIGINT NOT NULL,
   state VARCHAR(32) NOT NULL,
   PRIMARY KEY (id));
 
@@ -230,8 +229,7 @@ CREATE TABLE host_role_command (
   retry_allowed SMALLINT DEFAULT 0 NOT NULL,
   event LONGTEXT NOT NULL,
   exitcode INTEGER NOT NULL,
-  host_name VARCHAR(255) NOT NULL,
-  -- host_id BIGINT NOT NULL,
+  host_id BIGINT NOT NULL,
   last_attempt_time BIGINT NOT NULL,
   request_id BIGINT NOT NULL,
   role VARCHAR(255),
@@ -608,6 +606,7 @@ ALTER TABLE repo_version ADD CONSTRAINT UQ_repo_version_display_name UNIQUE (dis
 ALTER TABLE repo_version ADD CONSTRAINT UQ_repo_version_stack_version UNIQUE (stack_id, version);
 
 -- altering tables by creating foreign keys----------
+-- Note, Oracle has a limitation of 32 chars in the FK name, and we should use the same FK name in all DB types.
 ALTER TABLE members ADD CONSTRAINT FK_members_group_id FOREIGN KEY (group_id) REFERENCES groups (group_id);
 ALTER TABLE members ADD CONSTRAINT FK_members_user_id FOREIGN KEY (user_id) REFERENCES users (user_id);
 ALTER TABLE clusterconfig ADD CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id);
@@ -621,15 +620,13 @@ ALTER TABLE hostcomponentdesiredstate ADD CONSTRAINT hstcmpnntdesiredstatecmpnnt
 ALTER TABLE hostcomponentstate ADD CONSTRAINT hstcomponentstatecomponentname FOREIGN KEY (component_name, cluster_id, service_name) REFERENCES servicecomponentdesiredstate (component_name, cluster_id, service_name);
 ALTER TABLE hostcomponentstate ADD CONSTRAINT FK_hostcomponentstate_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
 ALTER TABLE hoststate ADD CONSTRAINT FK_hoststate_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
-ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_name FOREIGN KEY (host_name) REFERENCES hosts (host_name);
--- ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
+ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
 ALTER TABLE host_version ADD CONSTRAINT FK_host_version_repovers_id FOREIGN KEY (repo_version_id) REFERENCES repo_version (repo_version_id);
 ALTER TABLE servicecomponentdesiredstate ADD CONSTRAINT srvccmponentdesiredstatesrvcnm FOREIGN KEY (service_name, cluster_id) REFERENCES clusterservices (service_name, cluster_id);
 ALTER TABLE servicedesiredstate ADD CONSTRAINT servicedesiredstateservicename FOREIGN KEY (service_name, cluster_id) REFERENCES clusterservices (service_name, cluster_id);
 ALTER TABLE execution_command ADD CONSTRAINT FK_execution_command_task_id FOREIGN KEY (task_id) REFERENCES host_role_command (task_id);
 ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_stage_id FOREIGN KEY (stage_id, request_id) REFERENCES stage (stage_id, request_id);
-ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_host_name FOREIGN KEY (host_name) REFERENCES hosts (host_name);
--- ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
+ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
 ALTER TABLE role_success_criteria ADD CONSTRAINT role_success_criteria_stage_id FOREIGN KEY (stage_id, request_id) REFERENCES stage (stage_id, request_id);
 ALTER TABLE stage ADD CONSTRAINT FK_stage_request_id FOREIGN KEY (request_id) REFERENCES request (request_id);
 ALTER TABLE request ADD CONSTRAINT FK_request_schedule_id FOREIGN KEY (request_schedule_id) REFERENCES requestschedule (schedule_id);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ee79dd21/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 436e438..25685e5 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -159,8 +159,7 @@ CREATE TABLE hoststate (
 CREATE TABLE host_version (
   id NUMBER(19) NOT NULL,
   repo_version_id NUMBER(19) NOT NULL,
-  host_name VARCHAR2(255) NOT NULL,
-  --host_id NUMBER(19) NOT NULL,
+  host_id NUMBER(19) NOT NULL,
   state VARCHAR2(32) NOT NULL,
   PRIMARY KEY (id));
 
@@ -219,8 +218,7 @@ CREATE TABLE host_role_command (
   retry_allowed NUMBER(1) DEFAULT 0 NOT NULL,
   event CLOB NULL,
   exitcode NUMBER(10) NOT NULL,
-  host_name VARCHAR2(255) NOT NULL,
-  --host_id NUMBER(19) NOT NULL,
+  host_id NUMBER(19) NOT NULL,
   last_attempt_time NUMBER(19) NOT NULL,
   request_id NUMBER(19) NOT NULL,
   role VARCHAR2(255) NULL,
@@ -597,6 +595,7 @@ ALTER TABLE repo_version ADD CONSTRAINT UQ_repo_version_display_name UNIQUE (dis
 ALTER TABLE repo_version ADD CONSTRAINT UQ_repo_version_stack_version UNIQUE (stack_id, version);
 
 --------altering tables by creating foreign keys----------
+-- Note, Oracle has a limitation of 32 chars in the FK name, and we should use the same FK name in all DB types.
 ALTER TABLE members ADD CONSTRAINT FK_members_group_id FOREIGN KEY (group_id) REFERENCES groups (group_id);
 ALTER TABLE members ADD CONSTRAINT FK_members_user_id FOREIGN KEY (user_id) REFERENCES users (user_id);
 ALTER TABLE clusterconfig ADD CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id);
@@ -611,15 +610,13 @@ ALTER TABLE hostcomponentdesiredstate ADD CONSTRAINT hstcmpnntdesiredstatecmpnnt
 ALTER TABLE hostcomponentstate ADD CONSTRAINT hstcomponentstatecomponentname FOREIGN KEY (component_name, cluster_id, service_name) REFERENCES servicecomponentdesiredstate (component_name, cluster_id, service_name);
 ALTER TABLE hostcomponentstate ADD CONSTRAINT FK_hostcomponentstate_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
 ALTER TABLE hoststate ADD CONSTRAINT FK_hoststate_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
-ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_name FOREIGN KEY (host_name) REFERENCES hosts (host_name);
---ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
+ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
 ALTER TABLE host_version ADD CONSTRAINT FK_host_version_repovers_id FOREIGN KEY (repo_version_id) REFERENCES repo_version (repo_version_id);
 ALTER TABLE servicecomponentdesiredstate ADD CONSTRAINT srvccmponentdesiredstatesrvcnm FOREIGN KEY (service_name, cluster_id) REFERENCES clusterservices (service_name, cluster_id);
 ALTER TABLE servicedesiredstate ADD CONSTRAINT servicedesiredstateservicename FOREIGN KEY (service_name, cluster_id) REFERENCES clusterservices (service_name, cluster_id);
 ALTER TABLE execution_command ADD CONSTRAINT FK_execution_command_task_id FOREIGN KEY (task_id) REFERENCES host_role_command (task_id);
 ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_stage_id FOREIGN KEY (stage_id, request_id) REFERENCES stage (stage_id, request_id);
-ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_host_name FOREIGN KEY (host_name) REFERENCES hosts (host_name);
---ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
+ALTER TABLE host_role_command ADD CONSTRAINT FK_host_role_command_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id);
 ALTER TABLE role_success_criteria ADD CONSTRAINT role_success_criteria_stage_id FOREIGN KEY (stage_id, request_id) REFERENCES stage (stage_id, request_id);
 ALTER TABLE stage ADD CONSTRAINT FK_stage_request_id FOREIGN KEY (request_id) REFERENCES request (request_id);
 ALTER TABLE request ADD CONSTRAINT FK_request_schedule_id FOREIGN KEY (request_schedule_id) REFERENCES requestschedule (schedule_id);