Przeglądaj źródła

AMBARI-780. Make FSM related changes for heartbeat handler. (Contributed by hitesh)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1392503 13f79535-47bb-0310-9956-ffa450edef68
Hitesh Shah 13 lat temu
rodzic
commit
6cd0903448
66 zmienionych plików z 783 dodań i 474 usunięć
  1. 2 0
      AMBARI-666-CHANGES.txt
  2. 1 1
      ambari-api/src/main/java/org/apache/ambari/api/controller/internal/ResourceProviderImpl.java
  3. 1 1
      ambari-api/src/test/java/webserver/StartServer.java
  4. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessor.java
  5. 7 7
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
  6. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBInMemoryImpl.java
  7. 4 4
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
  8. 13 13
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
  9. 11 11
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostAction.java
  10. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
  11. 10 10
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
  12. 4 4
      ambari-server/src/main/java/org/apache/ambari/server/agent/ActionQueue.java
  13. 4 4
      ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java
  14. 9 9
      ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java
  15. 5 5
      ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java
  16. 19 19
      ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
  17. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeat.java
  18. 6 6
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
  19. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java
  20. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
  21. 6 6
      ambari-server/src/main/java/org/apache/ambari/server/agent/Register.java
  22. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationCommand.java
  23. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java
  24. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/agent/StatusCommand.java
  25. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java
  26. 11 11
      ambari-server/src/main/java/org/apache/ambari/server/api/rest/BootStrapResource.java
  27. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/api/rest/HealthCheck.java
  28. 7 7
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java
  29. 6 6
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java
  30. 10 10
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSResponse.java
  31. 9 9
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java
  32. 73 0
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapPostStatus.java
  33. 11 11
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapStatus.java
  34. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/FifoLinkedHashMap.java
  35. 9 9
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java
  36. 7 7
      ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
  37. 8 8
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
  38. 18 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RoleEntity.java
  39. 18 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserEntity.java
  40. 23 23
      ambari-server/src/main/java/org/apache/ambari/server/security/CertificateManager.java
  41. 6 6
      ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java
  42. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/security/SignCertResponse.java
  43. 4 4
      ambari-server/src/main/java/org/apache/ambari/server/security/unsecured/rest/CertificateDownload.java
  44. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/security/unsecured/rest/CertificateSign.java
  45. 24 38
      ambari-server/src/main/java/org/apache/ambari/server/state/live/Cluster.java
  46. 28 0
      ambari-server/src/main/java/org/apache/ambari/server/state/live/ClusterFactory.java
  47. 75 58
      ambari-server/src/main/java/org/apache/ambari/server/state/live/ClusterImpl.java
  48. 37 12
      ambari-server/src/main/java/org/apache/ambari/server/state/live/Clusters.java
  49. 50 27
      ambari-server/src/main/java/org/apache/ambari/server/state/live/ClustersImpl.java
  50. 10 10
      ambari-server/src/main/java/org/apache/ambari/server/state/live/host/HostImpl.java
  51. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/state/live/host/HostStatusUpdatesReceivedEvent.java
  52. 11 0
      ambari-server/src/main/java/org/apache/ambari/server/state/live/svccomphost/ServiceComponentHost.java
  53. 16 1
      ambari-server/src/main/java/org/apache/ambari/server/state/live/svccomphost/ServiceComponentHostImpl.java
  54. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyList.java
  55. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyMap.java
  56. 2 2
      ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyMapAdapter.java
  57. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyVal.java
  58. 8 8
      ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java
  59. 11 11
      ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
  60. 12 12
      ambari-server/src/test/java/org/apache/ambari/server/bootstrap/BootStrapResourceTest.java
  61. 9 9
      ambari-server/src/test/java/org/apache/ambari/server/bootstrap/BootStrapTest.java
  62. 14 14
      ambari-server/src/test/java/org/apache/ambari/server/security/CertGenerationTest.java
  63. 24 11
      ambari-server/src/test/java/org/apache/ambari/server/state/live/TestClusterImpl.java
  64. 81 1
      ambari-server/src/test/java/org/apache/ambari/server/state/live/TestClustersImpl.java
  65. 7 7
      ambari-server/src/test/java/org/apache/ambari/server/state/live/host/TestHostImpl.java
  66. 11 11
      ambari-server/src/test/java/org/apache/ambari/server/state/live/svccomphost/TestServiceComponentHostImpl.java

+ 2 - 0
AMBARI-666-CHANGES.txt

@@ -182,6 +182,8 @@ AMBARI-666 branch (unreleased changes)
 
   BUG FIXES
 
+  AMBARI-780. Make FSM related changes for heartbeat handler. (hitesh)
+
   AMBARI-774. Renable and fix AgentResourceTest. (mahadev) 
 
   AMBARI-773. Change Host FSM as per new requirements of heartbeat handler. (hitesh)

+ 1 - 1
ambari-api/src/main/java/org/apache/ambari/api/controller/internal/ResourceProviderImpl.java

@@ -51,7 +51,7 @@ public abstract class ResourceProviderImpl implements ResourceProvider {
   }
 
   public static ResourceProvider getResourceProvider(Resource.Type type, Set<PropertyId> propertyIds, ManagementController managementController)  {
-  
+
     switch (type) {
       case Cluster:
         return new ClusterResourceProvider(propertyIds, managementController);

+ 1 - 1
ambari-api/src/test/java/webserver/StartServer.java

@@ -79,4 +79,4 @@ public class StartServer {
     System.err.println("Usage: java StartServer [-p portNum] [-d abs path to ambari db file]");
     System.err.println("Default Values: portNum=9998, ambariDb=/var/db/hmc/data/data.db");
   }
-}
+}

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessor.java

@@ -55,4 +55,4 @@ public interface ActionDBAccessor {
 
   public void persistActions(List<Stage> stages);
 
-}
+}

+ 7 - 7
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java

@@ -22,13 +22,13 @@ import java.util.List;
 import org.apache.ambari.server.Role;
 
 public class ActionDBAccessorImpl implements ActionDBAccessor {
-  
+
   private long stageId = 0;
-  
+
   public ActionDBAccessorImpl() {
     //this.stageId = greatest stage id in the database + 1
   }
-  
+
   /* (non-Javadoc)
    * @see org.apache.ambari.server.actionmanager.ActionDBAccessor#persistAction(org.apache.ambari.server.actionmanager.HostAction)
    */
@@ -51,7 +51,7 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
   public List<Stage> getAllStages(String requestId) {
     return null;
   }
-  
+
   /* (non-Javadoc)
    * @see org.apache.ambari.server.actionmanager.ActionDBAccessor#getQueuedStages()
    */
@@ -59,7 +59,7 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
   public List<Stage> getQueuedStages() {
     return null;
   }
-  
+
   /* (non-Javadoc)
    * @see org.apache.ambari.server.actionmanager.ActionDBAccessor#getNotQueuedStages()
    */
@@ -67,7 +67,7 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
   public List<Stage> getNotQueuedStages() {
     return null;
   }
-  
+
   /* (non-Javadoc)
    * @see org.apache.ambari.server.actionmanager.ActionDBAccessor#getNextStageId()
    */
@@ -106,6 +106,6 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
   @Override
   public void persistActions(List<Stage> stages) {
     // TODO Auto-generated method stub
-    
+
   }
 }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBInMemoryImpl.java

@@ -27,7 +27,7 @@ import org.apache.ambari.server.Role;
 public class ActionDBInMemoryImpl implements ActionDBAccessor {
 
   List<Stage> stageList = new ArrayList<Stage>();
- 
+
   @Override
   public void persistAction(HostAction ha) {
     // TODO Auto-generated method stub

+ 4 - 4
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java

@@ -46,15 +46,15 @@ public class ActionManager {
         actionQueue, fsm, 2);
     this.fsm = fsm;
   }
-  
+
   public void initialize() {
     scheduler.start();
   }
-  
+
   public void shutdown() {
     scheduler.stop();
   }
-  
+
   public void sendActions(List<Stage> stages) {
     db.persistActions(stages);
   }
@@ -75,6 +75,6 @@ public class ActionManager {
 
   public void handleLostHost(String host) {
     // TODO Auto-generated method stub
-    
+
   }
 }

+ 13 - 13
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java

@@ -31,11 +31,11 @@ import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostEvent
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-//This class encapsulates the action scheduler thread. 
+//This class encapsulates the action scheduler thread.
 //Action schedule frequently looks at action database and determines if
 //there is an action that can be scheduled.
 class ActionScheduler implements Runnable {
-  
+
   private static Log LOG = LogFactory.getLog(ActionScheduler.class);
   private final long actionTimeout;
   private final long sleepTime;
@@ -45,7 +45,7 @@ class ActionScheduler implements Runnable {
   private final short maxAttempts;
   private final ActionQueue actionQueue;
   private final Clusters fsmObject;
-  
+
   public ActionScheduler(long sleepTimeMilliSec, long actionTimeoutMilliSec,
       ActionDBAccessor db, ActionQueue actionQueue, Clusters fsmObject,
       int maxAttempts) {
@@ -56,12 +56,12 @@ class ActionScheduler implements Runnable {
     this.fsmObject = fsmObject;
     this.maxAttempts = (short) maxAttempts;
   }
-  
+
   public void start() {
     schedulerThread = new Thread(this);
     schedulerThread.start();
   }
-  
+
   public void stop() {
     shouldRun = false;
     schedulerThread.interrupt();
@@ -81,19 +81,19 @@ class ActionScheduler implements Runnable {
       }
     }
   }
-  
+
   private void doWork() throws AmbariException {
     List<Stage> stages = db.getPendingStages();
     if (stages == null || stages.isEmpty()) {
       //Nothing to do
       return;
     }
-    
+
     //First discover completions and timeouts.
     boolean operationFailure = false;
     for (Stage s : stages) {
       Map<Role, Map<String, HostRoleCommand>> roleToHrcMap = getInvertedRoleMap(s);
-      
+
       //Iterate for completion
       boolean moveToNextStage = true;
       for (Role r: roleToHrcMap.keySet()) {
@@ -223,7 +223,7 @@ class ActionScheduler implements Runnable {
     }
     return roleToHrcMap;
   }
-  
+
   static class RoleStatus {
     int numQueued = 0;
     int numSucceeded = 0;
@@ -233,12 +233,12 @@ class ActionScheduler implements Runnable {
     int numAborted = 0;
     final int totalHosts;
     final float successFactor;
-    
+
     RoleStatus(int total, float successFactor) {
       this.totalHosts = total;
       this.successFactor = successFactor;
     }
-    
+
     boolean isRoleSuccessful() {
       if (successFactor <= (1.0*numSucceeded)/totalHosts) {
         return true;
@@ -246,11 +246,11 @@ class ActionScheduler implements Runnable {
         return false;
       }
     }
-    
+
     boolean isRoleInProgress() {
       return (numPending+numQueued > 0);
     }
-    
+
     boolean isRoleFailed() {
       if ((!isRoleInProgress()) && (!isRoleSuccessful())) {
         return false;

+ 11 - 11
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostAction.java

@@ -26,7 +26,7 @@ import org.apache.ambari.server.agent.ExecutionCommand;
 /**
  * Encapsulates entire task for a host for a stage or action. This class
  * contains all the information to generate an
- * {@link org.apache.ambari.server.agent.ExecutionCommand} that will be 
+ * {@link org.apache.ambari.server.agent.ExecutionCommand} that will be
  * scheduled for a host.
  */
 public class HostAction {
@@ -35,7 +35,7 @@ public class HostAction {
   private long startTime = -1;
   private long lastAttemptTime = -1;
   private short attemptCount = 0;
-  
+
   /**
    * This object will be serialized and sent to the agent.
    */
@@ -45,14 +45,14 @@ public class HostAction {
     //generate manifest
     return null;
   }
-  
+
   public HostAction(String host) {
     this.host = host;
     roles = new ArrayList<HostRoleCommand>();
     commandToHost = new ExecutionCommand();
     commandToHost.setHostName(host);
   }
-  
+
   public HostAction(HostAction ha) {
     this.host = ha.host;
     this.roles = ha.roles;
@@ -61,31 +61,31 @@ public class HostAction {
     this.attemptCount = ha.attemptCount;
     this.commandToHost = ha.commandToHost;
   }
-  
+
   public void addHostRoleCommand(HostRoleCommand cmd) {
     roles.add(cmd);
   }
-  
+
   public List<HostRoleCommand> getRoleCommands() {
     return roles;
   }
-  
+
   public long getStartTime() {
     return startTime;
   }
-  
+
   public long getLastAttemptTime() {
     return this.lastAttemptTime;
   }
-  
+
   public void setLastAttemptTime(long t) {
     this.lastAttemptTime = t;
   }
-  
+
   public void incrementAttemptCount() {
     this.attemptCount ++;
   }
-  
+
   public short getAttemptCount() {
     return this.attemptCount;
   }

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java

@@ -44,11 +44,11 @@ public class HostRoleCommand {
   public HostRoleStatus getStatus() {
     return status;
   }
-  
+
   public ServiceComponentHostEvent getEvent() {
     return event;
   }
-  
+
   void setStatus(HostRoleStatus status) {
     this.status = status;
   }

+ 10 - 10
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java

@@ -30,20 +30,20 @@ public class Stage {
   private final long requestId;
   private final String clusterName;
   private long stageId = -1;
-  
+
   //Map of roles to successFactors for this stage. Default is 1 i.e. 100%
   private Map<Role, Float> successFactors = new HashMap<Role, Float>();
 
   //Map of host to host-roles
   private Map<String, HostAction> hostActions = new TreeMap<String, HostAction>();
   private final String logDir;
-  
+
   public Stage(long requestId, String logDir, String clusterName) {
     this.requestId = requestId;
     this.logDir = logDir;
     this.clusterName = clusterName;
   }
-  
+
   public synchronized void setStageId(long stageId) {
     if (this.stageId != -1) {
       throw new RuntimeException("Attempt to set stageId again! Not allowed.");
@@ -53,24 +53,24 @@ public class Stage {
       this.hostActions.get(host).setCommandId(this.requestId, this.stageId);
     }
   }
-  
+
   public synchronized long getStageId() {
     return stageId;
   }
-  
+
   public String getActionId() {
     return "" + requestId + "-" + stageId;
   }
-  
+
   synchronized void addHostAction(String host, HostAction ha) {
     ha.setCommandId(requestId, stageId);
     hostActions.put(host, ha);
   }
-  
+
   synchronized HostAction getHostAction(String host) {
     return hostActions.get(host);
   }
-  
+
   /**
    * Returns an internal data structure, please don't modify it.
    * TODO: Ideally should return an iterator.
@@ -78,7 +78,7 @@ public class Stage {
   synchronized Map<String, HostAction> getHostActions() {
     return hostActions;
   }
-  
+
   synchronized float getSuccessFactor(Role r) {
     Float f = successFactors.get(r);
     if (f == null) {
@@ -96,7 +96,7 @@ public class Stage {
     // TODO Auto-generated method stub
     return getHostAction(hostName).getManifest();
   }
-  
+
   public String getClusterName() {
     return clusterName;
   }

+ 4 - 4
ambari-server/src/main/java/org/apache/ambari/server/agent/ActionQueue.java

@@ -29,15 +29,15 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 public class ActionQueue {
-  
+
   private static Log LOG = LogFactory.getLog(ActionQueue.class);
-  
+
   Map<String, Queue<AgentCommand>> hostQueues;
 
   public ActionQueue() {
     hostQueues = new TreeMap<String, Queue<AgentCommand>>();
   }
-  
+
   private synchronized Queue<AgentCommand> getQueue(String hostname) {
     return hostQueues.get(hostname);
   }
@@ -47,7 +47,7 @@ public class ActionQueue {
   }
 
   public void enqueue(String hostname, AgentCommand cmd) {
-    
+
     Queue<AgentCommand> q = getQueue(hostname);
     if (q == null) {
       q = new LinkedList<AgentCommand>();

+ 4 - 4
ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java

@@ -28,18 +28,18 @@ import javax.xml.bind.annotation.XmlType;
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {})
 public abstract class AgentCommand {
-  
+
   @XmlElement
   private AgentCommandType commandType;
-  
+
   public AgentCommand() {
     this.commandType = AgentCommandType.STATUS_COMMAND;
   }
-  
+
   public AgentCommand(AgentCommandType type) {
     this.commandType = type;
   }
-  
+
   @XmlType
   @XmlEnum
   public enum AgentCommandType {

+ 9 - 9
ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java

@@ -37,38 +37,38 @@ public class CommandReport {
   String status;
   @XmlElement
   int exitCode;
-  
+
   @XmlElement
   private String clusterName;
- 
+
   public String getActionId() {
     return this.actionId;
   }
- 
+
   public void setActionId(String actionId) {
     this.actionId = actionId;
   }
-  
+
   public String getStdErr() {
     return this.stderr;
   }
-  
+
   public void setStdErr(String stderr) {
     this.stderr = stderr;
   }
-  
+
   public int getExitCode() {
     return this.exitCode;
   }
-  
+
   public void setExitCode(int exitCode) {
     this.exitCode = exitCode;
   }
-  
+
   public String getStdOut() {
     return this.stdout;
   }
-  
+
   public void setStdOut(String stdout) {
     this.stdout = stdout;
   }

+ 5 - 5
ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java

@@ -37,7 +37,7 @@ public class ComponentStatus {
   String serviceName;
   @XmlElement
   String clusterName;
-  
+
   public String getComponentName() {
     return this.componentName;
   }
@@ -45,19 +45,19 @@ public class ComponentStatus {
   public void setComponentName(String componentName) {
     this.componentName = componentName;
   }
-  
+
   public String getMessage() {
     return this.msg;
   }
-  
+
   public void setMessage(String msg) {
     this.msg = msg;
   }
-  
+
   public String getStatus() {
     return this.status;
   }
-  
+
   public void setStatus(String status) {
     this.status = status;
   }

+ 19 - 19
ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java

@@ -33,50 +33,50 @@ import org.apache.ambari.server.utils.JaxbMapKeyValAdapter;
 
 
 /**
- * Execution commands are scheduled by action manager, and these are 
+ * Execution commands are scheduled by action manager, and these are
  * persisted in the database for recovery.
  */
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {})
 public class ExecutionCommand extends AgentCommand {
-  
+
   public ExecutionCommand() {
     super(AgentCommandType.EXECUTION_COMMAND);
   }
-  
+
   @XmlElement
   private String clusterName;
-  
+
   @XmlElement
   private String commandId;
-  
+
   @XmlElement
   private String hostname;
-  
+
   @XmlElement
   @XmlJavaTypeAdapter(JaxbMapKeyValAdapter.class)
   private Map<String, String> params = null;
-  
+
   @XmlElement
   @XmlJavaTypeAdapter(JaxbMapKeyListAdapter.class)
   private Map<String, List<String>> clusterHostInfo = null;
-  
+
   @XmlElement
   private List<RoleExecution> rolesCommands;
-  
+
   @XmlElement
   @XmlJavaTypeAdapter(JaxbMapKeyMapAdapter.class)
   private Map<String, Map<String, String>> configurations;
-  
+
   public String getCommandId() {
     return this.commandId;
   }
-  
+
   public void setCommandId(String commandId) {
     this.commandId = commandId;
   }
-  
+
   @Override //Object
   public boolean equals(Object other) {
     if (!(other instanceof ExecutionCommand)) {
@@ -86,32 +86,32 @@ public class ExecutionCommand extends AgentCommand {
     return (this.commandId == o.commandId &&
             this.hostname == o.hostname);
   }
-  
+
   @Override //Object
   public int hashCode() {
     return (hostname + commandId).hashCode();
   }
-  
+
   public void setHostName(String host) {
     this.hostname = host;
   }
-  
+
   @XmlRootElement
   @XmlAccessorType(XmlAccessType.FIELD)
   @XmlType(name = "", propOrder = {})
   static class RoleExecution {
-    
+
     @XmlElement
     private String role;
-    
+
     //These params are at role level
     @XmlElement
     @XmlJavaTypeAdapter(JaxbMapKeyValAdapter.class)
     private Map<String, String> roleParams = null;
-    
+
     @XmlElement
     private String cmd;
-    
+
     public String getRole() {
       return role;
     }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeat.java

@@ -49,7 +49,7 @@ public class HeartBeat {
   List<ComponentStatus> componentStatus = new ArrayList<ComponentStatus>();
   @XmlElement
   HostStatus nodeStatus;
-  
+
   public long getResponseId() {
     return responseId;
   }

+ 6 - 6
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java

@@ -43,12 +43,12 @@ import com.google.inject.Singleton;
  */
 @Singleton
 public class HeartBeatHandler {
-  
+
   private final Clusters clusterFsm;
   private final ActionQueue actionQueue;
   private final ActionManager actionManager;
   private HeartbeatMonitor heartbeatMonitor;
-  
+
   @Inject
   public HeartBeatHandler(Clusters fsm, ActionQueue aq, ActionManager am) {
     this.clusterFsm = fsm;
@@ -56,11 +56,11 @@ public class HeartBeatHandler {
     this.actionManager = am;
     this.heartbeatMonitor = new HeartbeatMonitor(fsm, aq, am, 60000);
   }
-  
+
   public void start() {
     heartbeatMonitor.start();
   }
-  
+
   public HeartBeatResponse handleHeartBeat(HeartBeat heartbeat) throws AmbariException {
 
     HeartBeatResponse response = new HeartBeatResponse();
@@ -85,7 +85,7 @@ public class HeartBeatHandler {
     actionManager.actionResponse(hostname, reports);
 
     // Examine heartbeart for component status
-    List<Cluster> clusters = clusterFsm.getClusters(hostname);
+    List<Cluster> clusters = clusterFsm.getClustersForHost(hostname);
     for (Cluster cl : clusters) {
       for (ComponentStatus status : heartbeat.componentStatus) {
         if (status.getClusterName() == cl.getClusterName()) {
@@ -108,7 +108,7 @@ public class HeartBeatHandler {
     }
     return response;
   }
-  
+
   public RegistrationResponse handleRegistration(Register register)
       throws InvalidStateTransitonException, AmbariException {
     String hostname = register.getHostname();

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java

@@ -63,7 +63,7 @@ public class HeartBeatResponse {
   public List<AgentCommand> getAgentCommands() {
     return this.cmds;
   }
-  
+
   public void setAgentCommands(List<AgentCommand> cmds) {
     this.cmds = cmds;
   }

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java

@@ -41,7 +41,7 @@ public class HeartbeatMonitor implements Runnable {
   private final int threadWakeupInterval; //1 minute
   private volatile boolean shouldRun = true;
   private Thread monitorThread = null;
-  
+
   public HeartbeatMonitor(Clusters fsm, ActionQueue aq, ActionManager am,
       int threadWakeupInterval) {
     this.fsm = fsm;
@@ -58,7 +58,7 @@ public class HeartbeatMonitor implements Runnable {
     monitorThread = new Thread(this);
     monitorThread.start();
   }
-  
+
   @Override
   public void run() {
     while (shouldRun) {
@@ -83,7 +83,7 @@ public class HeartbeatMonitor implements Runnable {
     for (Host hostObj : allHosts) {
       String host = hostObj.getHostName();
       HostState hostState = hostObj.getState();
-      
+
       long lastHeartbeat = 0;
       try {
         lastHeartbeat = fsm.getHost(host).getLastHeartbeatTime();

+ 6 - 6
ambari-server/src/main/java/org/apache/ambari/server/agent/Register.java

@@ -44,7 +44,7 @@ public class Register {
   private String hostname;
   @XmlElement
   private HostInfo hardwareProfile;
-  
+
   public short getResponseId() {
     return responseId;
   }
@@ -60,7 +60,7 @@ public class Register {
   public String getHostname() {
     return hostname;
   }
- 
+
   public HostInfo getHardwareProfile() {
     return hardwareProfile;
   }
@@ -72,9 +72,9 @@ public class Register {
   public void setHostname(String hostname) {
     this.hostname = hostname;
   }
- 
+
   public void setHardwareProfile(HostInfo hardwareProfile) {
-    this.hardwareProfile = hardwareProfile;    
+    this.hardwareProfile = hardwareProfile;
   }
 
   @Override
@@ -82,8 +82,8 @@ public class Register {
     String ret = "responseId=" + responseId + "\n" +
              "timestamp=" + timestamp + "\n" +
              "hostname="  + hostname + "\n";
-      
-    if (hardwareProfile != null) 
+
+    if (hardwareProfile != null)
       ret = ret + "hardwareprofile=" + this.hardwareProfile.toString();
     return ret;
   }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationCommand.java

@@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlType;
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {})
 public class RegistrationCommand extends AgentCommand {
-  
+
   public RegistrationCommand() {
     super(AgentCommandType.REGISTRATION_COMMAND);
   }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java

@@ -35,7 +35,7 @@ import javax.xml.bind.annotation.XmlType;
 public class RegistrationResponse {
   @XmlElement
   private RegistrationStatus response;
-  
+
   private AgentCommand command = null;
 
   public RegistrationStatus getResponseStatus() {

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/agent/StatusCommand.java

@@ -38,13 +38,13 @@ public class StatusCommand extends AgentCommand {
   public StatusCommand() {
     super(AgentCommandType.STATUS_COMMAND);
   }
-  
+
   @XmlElement
   List<String> roles;
 
   @XmlElement
   private String clusterName;
-  
+
   public List<String> getRoles() {
     return roles;
   }

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java

@@ -53,7 +53,7 @@ public class AgentResource {
   static void init(HeartBeatHandler instance) {
     hh = instance;
   }
-  
+
   /**
    * Register information about the host (Internal API to be used for
    * Ambari Agent)
@@ -63,8 +63,8 @@ public class AgentResource {
    * @response.representation.406.doc Error in register message format
    * @response.representation.408.doc Request Timed out
    * @param message Register message
-   * @throws InvalidStateTransitonException 
-   * @throws AmbariException 
+   * @throws InvalidStateTransitonException
+   * @throws AmbariException
    * @throws Exception
    */
   @Path("register/{hostName}")

+ 11 - 11
ambari-server/src/main/java/org/apache/ambari/server/api/rest/BootStrapResource.java

@@ -38,18 +38,18 @@ import com.google.inject.Inject;
 
 @Path("/bootstrap")
 public class BootStrapResource {
-  
+
   private static BootStrapImpl bsImpl;
   private static Log LOG = LogFactory.getLog(BootStrapResource.class);
-  
+
   @Inject
   static void init(BootStrapImpl instance) {
     bsImpl = instance;
   }
   /**
    * Run bootstrap on a list of hosts.
-   * @response.representation.200.doc 
-   * 
+   * @response.representation.200.doc
+   *
    * @response.representation.200.mediaType application/json
    * @response.representation.406.doc Error in format
    * @response.representation.408.doc Request Timed out
@@ -57,15 +57,15 @@ public class BootStrapResource {
    */
   @POST
   @Consumes(MediaType.APPLICATION_JSON)
-  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
   public BSResponse bootStrap(SshHostInfo sshInfo) {
     return bsImpl.runBootStrap(sshInfo);
   }
-  
+
   /**
    * Current BootStrap Information thats running.
-   * @response.representation.200.doc 
-   * 
+   * @response.representation.200.doc
+   *
    * @response.representation.200.mediaType application/json
    * @response.representation.406.doc Error in format
    * @response.representation.408.doc Request Timed out
@@ -73,11 +73,11 @@ public class BootStrapResource {
    */
   @GET
   @Path("/{requestId}")
-  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
-  public BootStrapStatus getBootStrapStatus(@PathParam("requestId") 
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public BootStrapStatus getBootStrapStatus(@PathParam("requestId")
   long requestId) {
     BootStrapStatus status = bsImpl.getStatus(0);
-    if (status == null) 
+    if (status == null)
       throw new WebApplicationException(Response.Status.NO_CONTENT);
     return status;
   }

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/api/rest/HealthCheck.java

@@ -32,7 +32,7 @@ import javax.ws.rs.core.MediaType;
 public class HealthCheck {
   private  final String status = "RUNNING";
   // This method is called if TEXT_PLAIN is request
- 
+
   @GET
   @Produces(MediaType.TEXT_PLAIN)
   public String plainTextCheck() {

+ 7 - 7
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java

@@ -33,31 +33,31 @@ import javax.xml.bind.annotation.XmlType;
 public class BSHostStatus {
   @XmlElement
   private String status;
-  @XmlElement 
+  @XmlElement
   private String hostName;
   @XmlElement
   private String log;
-  
+
   public void setStatus(String status) {
     this.status = status;
   }
-  
+
   public String getStatus() {
     return this.status;
   }
-  
+
   public void setHostName(String hostName) {
     this.hostName = hostName;
   }
-  
+
   public String getHostName() {
     return this.hostName;
   }
-  
+
   public String getLog() {
     return this.log;
   }
-  
+
   public void setLog(String log) {
     this.log = log;
   }

+ 6 - 6
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java

@@ -37,18 +37,18 @@ class BSHostStatusCollector {
   static String logFileFilter = ".log";
   static String doneFileFilter = ".done";
   private static Log LOG = LogFactory.getLog(BSHostStatusCollector.class);
-  
+
   private List<String> hosts;
 
   public BSHostStatusCollector(File requestIdDir, List<String> hosts) {
     this.requestIdDir = requestIdDir;
     this.hosts = hosts;
   }
-  
+
   public List<BSHostStatus> getHostStatus() {
     return hostStatus;
   }
-  
+
   public void run() {
     LOG.info("Request directory " + requestIdDir);
     hostStatus = new ArrayList<BSHostStatus>();
@@ -64,9 +64,9 @@ class BSHostStatusCollector {
       status.setHostName(host);
       done = new File(requestIdDir, host + doneFileFilter);
       log = new File(requestIdDir, host + logFileFilter);
-      if (!done.exists()) 
+      if (!done.exists())
         status.setStatus("RUNNING");
-      else 
+      else
         status.setStatus("DONE");
       if (!log.exists()) {
         status.setLog("");
@@ -82,4 +82,4 @@ class BSHostStatusCollector {
       hostStatus.add(status);
     }
   }
-}
+}

+ 10 - 10
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSResponse.java

@@ -39,34 +39,34 @@ public class BSResponse {
     OK,
     ERROR
   }
-  
-  @XmlElement 
+
+  @XmlElement
   private BSRunStat status;
-  @XmlElement 
+  @XmlElement
   private String log;
-  @XmlElement 
+  @XmlElement
   private long requestId;
-  
+
   public long getRequestId() {
     return this.requestId;
   }
-  
+
   public void setRequestId(long requestId) {
     this.requestId = requestId;
   }
-  
+
   public BSRunStat getStatus() {
     return this.status;
   }
-  
+
   public void setStatus(BSRunStat status) {
     this.status  = status;
   }
-  
+
   public String getLog() {
     return this.log;
   }
-  
+
   public void setLog(String log) {
     this.log = log;
   }

+ 9 - 9
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java

@@ -57,14 +57,14 @@ public class BootStrapImpl {
   public BootStrapImpl(Configuration conf) {
     this.conf = conf;
     this.bootStrapDir = conf.getBootStrapDir();
-    this.bootScript = conf.getBootStrapScript();   
+    this.bootScript = conf.getBootStrapScript();
     this.bsStatus = new FifoLinkedHashMap<Long, BootStrapStatus>();
   }
 
   /**
    * Return {@link BootStrapStatus} for a given responseId.
    * @param requestId the responseId for which the status needs to be returned.
-   * @return status for a specific response id. A response Id of -1 means the 
+   * @return status for a specific response id. A response Id of -1 means the
    * latest responseId.
    */
   public synchronized BootStrapStatus getStatus(long requestId) {
@@ -85,7 +85,7 @@ public class BootStrapImpl {
 
 
   /**
-   * Run the bs script to ssh to a list of hosts 
+   * Run the bs script to ssh to a list of hosts
    * with a ssh key.
    */
   class BSRunner extends Thread {
@@ -119,7 +119,7 @@ public class BootStrapImpl {
     private class BSStatusCollector implements Runnable {
       @Override
       public void run() {
-        BSHostStatusCollector collector = new BSHostStatusCollector(requestIdDir, 
+        BSHostStatusCollector collector = new BSHostStatusCollector(requestIdDir,
             sshHostInfo.getHosts());
         collector.run();
         List<BSHostStatus> hostStatus = collector.getHostStatus();
@@ -178,7 +178,7 @@ public class BootStrapImpl {
       try {
         createRunDir();
         writeSshKeyFile(sshHostInfo.getSshKey());
-        /* Running command: 
+        /* Running command:
          * script hostlist bsdir sshkeyfile
          */
         commands[0] = this.bsScript;
@@ -188,13 +188,13 @@ public class BootStrapImpl {
         LOG.info("Host= " + hostString + " bs=" + this.bsScript + " requestDir=" +
             requestIdDir + " keyfile=" + this.sshKeyFile);
         Process process = Runtime.getRuntime().exec(commands);
-        /** Startup a scheduled executor service to look through the logs 
+        /** Startup a scheduled executor service to look through the logs
          */
         ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
         BSStatusCollector statusCollector = new BSStatusCollector();
-        ScheduledFuture<?> handle = scheduler.scheduleWithFixedDelay(statusCollector, 
+        ScheduledFuture<?> handle = scheduler.scheduleWithFixedDelay(statusCollector,
             0, 10, TimeUnit.SECONDS);
-        LOG.info("Kicking off the scheduler for polling on logs in " + 
+        LOG.info("Kicking off the scheduler for polling on logs in " +
             this.requestIdDir);
         try {
           int exitCode = process.waitFor();
@@ -259,7 +259,7 @@ public class BootStrapImpl {
       response.setLog("BootStrap in Progress: Cannot Run more than one.");
       response.setStatus(BSRunStat.ERROR);
       return response;
-    } 
+    }
     requestId++;
 
     bsRunner = new BSRunner(info, bootStrapDir.toString(),

+ 73 - 0
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapPostStatus.java

@@ -0,0 +1,73 @@
+/**
+ * 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.bootstrap;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Class captures immediate response to a bootstrap api call.
+ * If the api call is ok, the return should return that its ok.
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {})
+public class BootStrapPostStatus {
+  @XmlType(name="status")
+  @XmlEnum
+  public enum BSPostStat {
+    OK,
+    ERROR
+  }
+
+  @XmlElement
+  private BSPostStat postStatus;
+  @XmlElement
+  private String log;
+  @XmlElement
+  private long requestId;
+
+  public long getRequestId() {
+    return this.requestId;
+  }
+
+  public void setRequestId(long requestId) {
+    this.requestId = requestId;
+  }
+
+  public BSPostStat getStatus() {
+    return this.postStatus;
+  }
+
+  public void setStatus(BSPostStat status) {
+    this.postStatus  = status;
+  }
+
+  public String getLog() {
+    return this.log;
+  }
+
+  public void setLog(String log) {
+    this.log = log;
+  }
+}

+ 11 - 11
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapStatus.java

@@ -29,7 +29,7 @@ import javax.xml.bind.annotation.XmlType;
 
 
 /**
- * Status of a bootstrap operation. Operation is successful or error 
+ * Status of a bootstrap operation. Operation is successful or error
  * and explains all the info regarding the operation on each host.
  *
  */
@@ -44,36 +44,36 @@ public class BootStrapStatus {
     SUCCESS,
     ERROR
   }
-  
-  @XmlElement 
+
+  @XmlElement
   private BSStat status;
-  
+
   @XmlElement
   private List<BSHostStatus> hostsStatus;
-  
+
   @XmlElement
   private String log;
-  
+
   public void setStatus(BSStat status) {
     this.status = status;
   }
-  
+
   public BSStat getStatus() {
     return this.status;
   }
-  
+
   public void setHostsStatus(List<BSHostStatus> hostsStatus) {
     this.hostsStatus = hostsStatus;
   }
-  
+
   public List<BSHostStatus> getHostsStatus() {
     return this.hostsStatus;
   }
-  
+
   public void setLog(String log) {
     this.log = log;
   }
-  
+
   public String getLog() {
     return this.log;
   }

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/FifoLinkedHashMap.java

@@ -26,12 +26,12 @@ import java.util.Map;
  *
  */
 @SuppressWarnings("serial")
-public class FifoLinkedHashMap<K, V> extends 
+public class FifoLinkedHashMap<K, V> extends
 LinkedHashMap<K, V> {
   public static final int MAX_ENTRIES = 100;
-  protected boolean removeEldestEntry(Map.Entry<K, 
+  protected boolean removeEldestEntry(Map.Entry<K,
       V> eldest) {
     return size() > MAX_ENTRIES;
   }
 
-}
+}

+ 9 - 9
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/SshHostInfo.java

@@ -29,35 +29,35 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * Information that the API needs to provide to run bootstrap on hosts.
- * 
+ *
  */
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {})
 public class SshHostInfo {
-  
+
   @XmlElement
   private String sshKey;
-  
-  @XmlElement 
+
+  @XmlElement
   private List<String>  hosts = new ArrayList<String>();
-  
+
   public String getSshKey() {
     return sshKey;
   }
-  
+
   public void setSshKey(String sshKey) {
     this.sshKey = sshKey;
   }
-  
+
   public void setHosts(List<String> hosts) {
     this.hosts = hosts;
   }
-  
+
   public List<String> getHosts() {
     return this.hosts;
   }
-  
+
   public String hostListAsString() {
     String ret = "";
     if (this.hosts == null) {

+ 7 - 7
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -52,7 +52,7 @@ public class Configuration {
   public static final String SRVR_CRT_PASS_KEY = "security.server.crt_pass";
   public static final String PASSPHRASE_ENV_KEY = "security.server.passphrase_env_var";
   public static final String PASSPHRASE_KEY = "security.server.passphrase";
- 
+
   public static final String CLIENT_SECURITY_KEY = "client.security";
   public static final String LDAP_USE_SSL_KEY = "authorization.ldap.useSSL";
   public static final String LDAP_PRIMARY_URL_KEY = "authorization.ldap.primaryUrl";
@@ -70,8 +70,8 @@ public class Configuration {
   public static final String KSTR_NAME_DEFAULT = "keystore.p12";
   private static final String SRVR_CRT_PASS_FILE_DEFAULT ="pass.txt";
   private static final String PASSPHRASE_ENV_DEFAULT = "AMBARI_PASSPHRASE";
-  
-  
+
+
   private static final String CLIENT_SECURITY_DEFAULT = "local";
 
   private static final String LDAP_USER_SEARCH_FILTER_DEFAULT = "({attribute}={0})";
@@ -85,7 +85,7 @@ public class Configuration {
 
 
 
-  
+
   private static final Log LOG = LogFactory.getLog(Configuration.class);
 
   private static Configuration instance;
@@ -101,7 +101,7 @@ public class Configuration {
   }
 
   /**
-   * For Testing only. This is to be able to create Configuration object 
+   * For Testing only. This is to be able to create Configuration object
    * for testing.
    * @param properties properties to use for testing using the Conf object.
    */
@@ -122,7 +122,7 @@ public class Configuration {
     configsMap.put(LDAP_USER_DEFAULT_ROLE_KEY, properties.getProperty(LDAP_USER_DEFAULT_ROLE_KEY, LDAP_USER_DEFAULT_ROLE_DEFAULT));
 
     try {
-        File passFile = new File(configsMap.get(SRVR_KSTR_DIR_KEY) + File.separator 
+        File passFile = new File(configsMap.get(SRVR_KSTR_DIR_KEY) + File.separator
             + configsMap.get(SRVR_CRT_PASS_FILE_KEY));
         if (passFile.exists()) {
           String srvrCrtPass = FileUtils.readFileToString(passFile);
@@ -180,7 +180,7 @@ public class Configuration {
     }
     return bootscript;
   }
-  
+
   /**
    * Get the map with server config parameters.
    * Keys - public constants of this class

+ 8 - 8
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java

@@ -91,7 +91,7 @@ public class AmbariServer {
 
       webAppContext.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, springWebAppContext);
 
-      
+
       server.setHandler(webAppContext);
 
       certMan.initRootCert();
@@ -101,7 +101,7 @@ public class AmbariServer {
 
       ServletHolder rootServlet = root.addServlet(DefaultServlet.class, "/");
       rootServlet.setInitOrder(1);
-    
+
       root.addFilter(SecurityFilter.class, "/*", 1);
       //Secured connector for 2-way auth
       SslSocketConnector sslConnectorTwoWay = new SslSocketConnector();
@@ -119,11 +119,11 @@ public class AmbariServer {
       sslConnectorTwoWay.setKeystoreType("PKCS12");
       sslConnectorTwoWay.setTruststoreType("PKCS12");
       sslConnectorTwoWay.setNeedClientAuth(true);
-      
+
       //Secured connector for 1-way auth
       SslSocketConnector sslConnectorOneWay = new SslSocketConnector();
       sslConnectorOneWay.setPort(CLIENT_ONE_WAY);
-      
+
       sslConnectorOneWay.setKeystore(keystore);
       sslConnectorOneWay.setTruststore(keystore);
       sslConnectorOneWay.setPassword(srvrCrtPass);
@@ -132,8 +132,8 @@ public class AmbariServer {
       sslConnectorOneWay.setKeystoreType("PKCS12");
       sslConnectorOneWay.setTruststoreType("PKCS12");
       sslConnectorOneWay.setNeedClientAuth(false);
-      
-      
+
+
 
       server.addConnector(sslConnectorOneWay);
       server.addConnector(sslConnectorTwoWay);
@@ -161,7 +161,7 @@ public class AmbariServer {
               "org.apache.ambari.server.security.unsecured.rest");
       root.addServlet(cert, "/cert/*");
       cert.setInitOrder(4);
-      
+
       ServletHolder certs = new ServletHolder(ServletContainer.class);
       certs.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
         "com.sun.jersey.api.core.PackagesResourceConfig");
@@ -209,4 +209,4 @@ public class AmbariServer {
       LOG.error("Failed to run the Ambari Server", t);
     }
   }
-}
+}

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RoleEntity.java

@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package org.apache.ambari.server.orm.entities;
 
 import javax.persistence.Entity;

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserEntity.java

@@ -5,6 +5,24 @@ import java.sql.Timestamp;
 import java.util.Date;
 import java.util.Set;
 
+/**
+ * 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.
+ */
+
 @IdClass(UserEntityPK.class)
 @javax.persistence.Table(name = "users", schema = "ambari", catalog = "")
 @Entity

+ 23 - 23
ambari-server/src/main/java/org/apache/ambari/server/security/CertificateManager.java

@@ -73,11 +73,11 @@ public class CertificateManager {
     String srvrKstrDir = configsMap.get(Configuration.SRVR_KSTR_DIR_KEY);
     String srvrCrtName = configsMap.get(Configuration.SRVR_CRT_NAME_KEY);
     File certFile = new File(srvrKstrDir + File.separator + srvrCrtName);
-    
+
 	return certFile.exists();
 	}
-  
-  
+
+
   /**
    * Runs os command
    */
@@ -88,11 +88,11 @@ public class CertificateManager {
       try {
         process = Runtime.getRuntime().exec(command);
         BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
-        
+
         while ((line = br.readLine()) != null) {
           LOG.info(line);
         }
-        
+
         try {
           process.waitFor();
         }
@@ -103,19 +103,19 @@ public class CertificateManager {
       catch (IOException e){
         e.printStackTrace();
       }
-	  
+	
   }
-  
+
   private void generateServerCertificate() {
     LOG.info("Generation of server certificate");
-    
+
     Map<String, String> configsMap = configs.getConfigsMap();
     String srvrKstrDir = configsMap.get(Configuration.SRVR_KSTR_DIR_KEY);
     String srvrCrtName = configsMap.get(Configuration.SRVR_CRT_NAME_KEY);
     String srvrKeyName = configsMap.get(Configuration.SRVR_KEY_NAME_KEY);
     String kstrName = configsMap.get(Configuration.KSTR_NAME_KEY);
     String srvrCrtPass = configsMap.get(Configuration.SRVR_CRT_PASS_KEY);
-    
+
     Object[] scriptArgs = {srvrCrtPass, srvrKstrDir, srvrKeyName,
 			               srvrCrtName, kstrName};
 
@@ -139,16 +139,16 @@ public class CertificateManager {
    */
   public String getServerCert() {
     Map<String, String> configsMap = configs.getConfigsMap();
-    File certFile = new File(configsMap.get(Configuration.SRVR_KSTR_DIR_KEY) + File.separator + configsMap.get(Configuration.SRVR_CRT_NAME_KEY));  
+    File certFile = new File(configsMap.get(Configuration.SRVR_KSTR_DIR_KEY) + File.separator + configsMap.get(Configuration.SRVR_CRT_NAME_KEY));
     String srvrCrtContent = null;
     try {
       srvrCrtContent = FileUtils.readFileToString(certFile);
 	} catch (IOException e) {
         LOG.error(e.getMessage());
-	}   
+	}
     return srvrCrtContent;
 	}
-  
+
   /**
    * Signs agent certificate
    * Adds agent certificate to server keystore
@@ -157,19 +157,19 @@ public class CertificateManager {
   public String signAgentCrt(String agentHostname, String agentCrtReqContent, String passphraseAgent) {
     LOG.info("Signing of agent certificate");
     LOG.info("Verifying passphrase");
-    
-    
-    
+
+
+
     String passphraseSrvr = configs.getConfigsMap().get(Configuration.PASSPHRASE_KEY);
-    
+
     System.out.println(passphraseSrvr);
     System.out.println(passphraseAgent);
-    
+
     if (!passphraseAgent.equals(passphraseSrvr)) {
       LOG.warn("Incorrect passphrase from agent");
       return "";
     }
-    
+
     Map<String, String> configsMap = configs.getConfigsMap();
     String srvrKstrDir = configsMap.get(Configuration.SRVR_KSTR_DIR_KEY);
     String srvrCrtPass = configsMap.get(Configuration.SRVR_CRT_PASS_KEY);
@@ -177,8 +177,8 @@ public class CertificateManager {
     String srvrKeyName = configsMap.get(Configuration.SRVR_KEY_NAME_KEY);
     String agentCrtReqName = agentHostname + ".csr";
     String agentCrtName = agentHostname + ".crt";
-    
-    
+
+
     File agentCrtReqFile = new File(srvrKstrDir + File.separator + agentCrtReqName);
     try {
 		FileUtils.writeStringToFile(agentCrtReqFile, agentCrtReqContent);
@@ -190,9 +190,9 @@ public class CertificateManager {
     					   srvrCrtPass,srvrKeyName,srvrCrtName};
 
     String command = MessageFormat.format(SIGN_AGENT_CRT,scriptArgs);
-    
+
     LOG.error(command);
-    
+
 	runCommand(command);
 	
 	File agentCrtFile = new File(srvrKstrDir + File.separator + agentCrtName);
@@ -203,7 +203,7 @@ public class CertificateManager {
 		e.printStackTrace();
 		LOG.error("Error reading signed agent certificate");
 	}
-    
+
     return agentCrtContent;
 	}
 }

+ 6 - 6
ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java

@@ -46,9 +46,9 @@ public class SecurityFilter implements Filter {
 
     HttpServletRequest req = (HttpServletRequest) serReq;
     String reqUrl = req.getRequestURL().toString();
-    
+
     System.out.println("req url:" + reqUrl);
-    
+
     //req.getC
 	
     if (serReq.getLocalPort() == AmbariServer.CLIENT_ONE_WAY) {
@@ -69,12 +69,12 @@ public class SecurityFilter implements Filter {
   private boolean isRequestAllowed(String reqUrl) {
 	try {
       boolean isMatch = Pattern.matches("https://[A-z]*:[0-9]*/cert/ca[/]*", reqUrl);
-		 
+		
       if (isMatch)
     	  return true;
-		 
+		
 		 isMatch = Pattern.matches("https://[A-z]*:[0-9]*/certs/[A-z0-9-]*", reqUrl);
-		 
+		
 		 if (isMatch)
 			 return true;
 		
@@ -82,4 +82,4 @@ public class SecurityFilter implements Filter {
 	}
 	return false;
   }
-}
+}

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/security/SignCertResponse.java

@@ -45,7 +45,7 @@ public class SignCertResponse {
   private String result;
   @XmlElement
   private String signedCa;
-  
+
   public String getResult() {
     return result;
   }

+ 4 - 4
ambari-server/src/main/java/org/apache/ambari/server/security/unsecured/rest/CertificateDownload.java

@@ -33,17 +33,17 @@ import com.google.inject.Inject;
 public class CertificateDownload {
   private static Log LOG = LogFactory.getLog(CertificateDownload.class);
   private static CertificateManager certMan;
-  
+
   @Inject
   static void init(CertificateManager instance) {
     certMan = instance;
   }
-  
+
   @GET
   @Produces({MediaType.TEXT_PLAIN})
   public String downloadSrvrCrt() {
     return certMan.getServerCert();
   }
-  
-  
+
+
 }

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/security/unsecured/rest/CertificateSign.java

@@ -38,12 +38,12 @@ import com.google.inject.Inject;
 public class CertificateSign {
   private static Log LOG = LogFactory.getLog(CertificateSign.class);
   private static CertificateManager certMan;
-  
+
   @Inject
   static void init(CertificateManager instance) {
     certMan = instance;
   }
-  
+
   /**
    * Signs agent certificate
    * @response.representation.200.doc This API is invoked by Ambari agent running

+ 24 - 38
ambari-server/src/main/java/org/apache/ambari/server/state/live/Cluster.java

@@ -20,92 +20,78 @@ package org.apache.ambari.server.state.live;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitonException;
-import org.apache.ambari.server.state.live.host.HostEvent;
-import org.apache.ambari.server.state.live.host.HostState;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHost;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostEvent;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostState;
 
 public interface Cluster {
 
+  /**
+   * Get the cluster ID
+   */
+  public long getClusterId();
+
   /**
    * Get the Cluster Name
    */
   public String getClusterName();
 
   /**
-   * Add a new host to the cluster
-   * @throws AmbariException
+   * Set the Cluster Name
    */
-  public void addHost(String host) throws AmbariException;
-  
+  public void setClusterName(String clusterName);
+
   /**
    * Add a new ServiceComponentHost to the cluster
    * @param serviceName
    * @param componentName
-   * @param hostName
+   * @param hostname
    * @param isClient
    */
   public void addServiceComponentHost(String serviceName, String componentName,
-      String hostName, boolean isClient) throws AmbariException;
-
-  /**
-   * Get the State for a given Host
-   * @param hostName Host hostname for which to retrieve state
-   * @return
-   * @throws AmbariException
-   */
-  public HostState getHostState(String hostName) throws AmbariException;
-
-  /**
-   * Set the State for a given Host
-   * @param hostName Host's hostname for which state is to be set
-   * @param state HostState to set
-   */
-  public void setHostState(String hostName, HostState state)
-      throws AmbariException;
-
-  /**
-   * Send event to the given Host
-   * @param hostName Host's hostname
-   * @param event Event to be handled
-   */
-  public void handleHostEvent(String hostName, HostEvent event)
-      throws AmbariException, InvalidStateTransitonException;
+      String hostname, boolean isClient) throws AmbariException;
 
   /**
    * Get the State for a given ServiceComponentHost
    * @param service Service name
    * @param serviceComponent ServiceComponent name
-   * @param hostName Host name
+   * @param hostname Host name
    * @return ServiceComponentHostState
    */
   public ServiceComponentHostState getServiceComponentHostState(String service,
-      String serviceComponent, String hostName) throws AmbariException;
+      String serviceComponent, String hostname) throws AmbariException;
 
   /**
    * Set the State for a given ServiceComponentHost
    * @param service Service name
    * @param serviceComponent ServiceComponent name
-   * @param hostName Host name
+   * @param hostname Host name
    * @param state State to set
    */
   public void setServiceComponentHostState(String service,
-      String serviceComponent, String hostName,
+      String serviceComponent, String hostname,
       ServiceComponentHostState state) throws AmbariException;
 
   /**
    * Send an Event to a given ServiceComponentHost
    * @param service Service name
    * @param serviceComponent ServiceComponent name
-   * @param hostName Host name
+   * @param hostname Host name
    * @param event Event to be handled
    */
   public void handleServiceComponentHostEvent(String service,
-      String serviceComponent, String hostName,
+      String serviceComponent, String hostname,
       ServiceComponentHostEvent event)
           throws AmbariException, InvalidStateTransitonException;
 
+  /**
+   * Retrieve a ServiceComponentHost object
+   * @param serviceName Service name
+   * @param serviceComponentName ServiceComponent name
+   * @param hostname Host name
+   * @return
+   * @throws AmbariException
+   */
   public ServiceComponentHost getServiceComponentHost(String serviceName,
       String componentName, String hostname) throws AmbariException;
 

+ 28 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/live/ClusterFactory.java

@@ -0,0 +1,28 @@
+/**
+ * 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.state.live;
+
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+
+/**
+ * Factory interface for Guice injections
+ */
+public interface ClusterFactory {
+  Cluster create(ClusterEntity clusterEntity);
+}

+ 75 - 58
ambari-server/src/main/java/org/apache/ambari/server/state/live/ClusterImpl.java

@@ -19,16 +19,12 @@
 package org.apache.ambari.server.state.live;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.HostNotFoundException;
 import org.apache.ambari.server.ServiceComponentHostNotFoundException;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitonException;
-import org.apache.ambari.server.state.live.host.Host;
-import org.apache.ambari.server.state.live.host.HostEvent;
-import org.apache.ambari.server.state.live.host.HostImpl;
-import org.apache.ambari.server.state.live.host.HostState;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHost;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostEvent;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostImpl;
@@ -36,57 +32,77 @@ import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostState
 
 public class ClusterImpl implements Cluster {
 
-  private final String clusterName;
-  private Map<String, Host> hosts;
+  private final Clusters clusters;
+
+  private final long clusterId;
+
+  private String clusterName;
+
+  /**
+   * [ ServiceName -> [ ServiceComponentName -> [ HostName -> [ ... ] ] ] ]
+   */
   private Map<String, Map<String, Map<String, ServiceComponentHost>>>
       serviceComponentHosts;
 
-  public ClusterImpl(String clusterName) {
+  /**
+   * [ HostName -> [ ... ] ]
+   */
+  private Map<String, Map<String, Map<String, ServiceComponentHost>>>
+      serviceComponentHostsByHost;
+
+  public ClusterImpl(Clusters clusters, long clusterId, String clusterName) {
+    this.clusters = clusters;
+    this.clusterId = clusterId;
     this.clusterName = clusterName;
-    this.hosts = new HashMap<String, Host>();
     this.serviceComponentHosts = new HashMap<String,
         Map<String,Map<String,ServiceComponentHost>>>();
-  }
-
-  private Host getHost(String hostName) throws AmbariException {
-    if (!hosts.containsKey(hostName)) {
-      throw new HostNotFoundException(hostName);
-    }
-    return hosts.get(hostName);
+    this.serviceComponentHostsByHost = new HashMap<String,
+        Map<String,Map<String,ServiceComponentHost>>>();
   }
 
   public ServiceComponentHost getServiceComponentHost(String serviceName,
-      String serviceComponentName, String hostName) throws AmbariException {
+      String serviceComponentName, String hostname) throws AmbariException {
     if (!serviceComponentHosts.containsKey(serviceName)
         || !serviceComponentHosts.get(serviceName)
             .containsKey(serviceComponentName)
         || !serviceComponentHosts.get(serviceName).get(serviceComponentName)
-            .containsKey(hostName)) {
+            .containsKey(hostname)) {
       throw new ServiceComponentHostNotFoundException(serviceName,
-          serviceComponentName, hostName);
+          serviceComponentName, hostname);
     }
     return serviceComponentHosts.get(serviceName).get(serviceComponentName)
-        .get(hostName);
+        .get(hostname);
   }
 
   @Override
-  public String getClusterName() {
+  public synchronized String getClusterName() {
     return clusterName;
   }
 
   @Override
-  public synchronized void addHost(String hostName) throws AmbariException {
-    if (hosts.containsKey(hostName)) {
-      throw new AmbariException("Duplicate entry for Host"
-          + ", hostName=" + hostName);
-    }
-    hosts.put(hostName, new HostImpl(hostName));
+  public synchronized void setClusterName(String clusterName) {
+    this.clusterName = clusterName;
   }
 
   @Override
   public synchronized void addServiceComponentHost(String serviceName,
-      String componentName, String hostName, boolean isClient)
+      String componentName, String hostname, boolean isClient)
       throws AmbariException {
+    List<Cluster> cs = clusters.getClustersForHost(hostname);
+    boolean clusterFound = false;
+    for (Cluster c : cs) {
+      if (c.getClusterId() == this.clusterId) {
+        clusterFound = true;
+        break;
+      }
+    }
+    if (!clusterFound) {
+      throw new AmbariException("Host does not belong this cluster"
+          + ", hostname=" + hostname
+          + ", clusterName=" + clusterName
+          + ", clusterId=" + clusterId);
+    }
+
     if (!serviceComponentHosts.containsKey(serviceName)) {
       serviceComponentHosts.put(serviceName,
           new HashMap<String, Map<String,ServiceComponentHost>>());
@@ -97,59 +113,60 @@ public class ClusterImpl implements Cluster {
     }
 
     if (serviceComponentHosts.get(serviceName).get(componentName).
-        containsKey(hostName)) {
+        containsKey(hostname)) {
       throw new AmbariException("Duplicate entry for ServiceComponentHost"
           + ", serviceName=" + serviceName
           + ", serviceComponentName" + componentName
-          + ", hostName= " + hostName);
+          + ", hostname= " + hostname);
     }
-    serviceComponentHosts.get(serviceName).get(componentName).put(hostName,
-        new ServiceComponentHostImpl(componentName, hostName, isClient));
-  }
 
-  @Override
-  public HostState getHostState(String hostName) throws AmbariException{
-    return getHost(hostName).getState();
-  }
+    if (!serviceComponentHostsByHost.containsKey(hostname)) {
+      serviceComponentHostsByHost.put(hostname,
+          new HashMap<String, Map<String,ServiceComponentHost>>());
+    }
+    if (!serviceComponentHostsByHost.get(hostname).containsKey(serviceName)) {
+      serviceComponentHostsByHost.get(hostname).put(serviceName,
+          new HashMap<String, ServiceComponentHost>());
+    }
 
-  @Override
-  public void setHostState(String hostName, HostState state)
-      throws AmbariException {
-    getHost(hostName).setState(state);
-  }
+    ServiceComponentHost impl =
+        new ServiceComponentHostImpl(clusterId,
+            serviceName, componentName, hostname, isClient);
 
-  @Override
-  public void handleHostEvent(String hostName, HostEvent event)
-      throws AmbariException, InvalidStateTransitonException {
-    if (!hosts.containsKey(hostName)) {
-      throw new HostNotFoundException(hostName);
-    }
-    hosts.get(hostName).handleEvent(event);
+    serviceComponentHosts.get(serviceName).get(componentName).put(hostname,
+        impl);
+    serviceComponentHostsByHost.get(hostname).get(serviceName).put(
+        componentName, impl);
   }
 
   @Override
-  public ServiceComponentHostState getServiceComponentHostState(String service,
-      String serviceComponent, String hostName) throws AmbariException {
+  public synchronized ServiceComponentHostState getServiceComponentHostState(String service,
+      String serviceComponent, String hostname) throws AmbariException {
     return
-        getServiceComponentHost(service, serviceComponent, hostName).getState();
+        getServiceComponentHost(service, serviceComponent, hostname).getState();
   }
 
   @Override
-  public void setServiceComponentHostState(String service,
-      String serviceComponent, String hostName,
+  public synchronized void setServiceComponentHostState(String service,
+      String serviceComponent, String hostname,
       ServiceComponentHostState state) throws AmbariException {
-    getServiceComponentHost(service, serviceComponent, hostName)
+    getServiceComponentHost(service, serviceComponent, hostname)
       .setState(state);
   }
 
   @Override
-  public void handleServiceComponentHostEvent(String service,
-      String serviceComponent, String hostName,
+  public synchronized void handleServiceComponentHostEvent(String service,
+      String serviceComponent, String hostname,
       ServiceComponentHostEvent event)
       throws AmbariException, InvalidStateTransitonException {
-    getServiceComponentHost(service, serviceComponent, hostName)
+    getServiceComponentHost(service, serviceComponent, hostname)
       .handleEvent(event);
 
   }
 
+  @Override
+  public long getClusterId() {
+    return clusterId;
+  }
+
 }

+ 37 - 12
ambari-server/src/main/java/org/apache/ambari/server/state/live/Clusters.java

@@ -22,8 +22,11 @@ import java.util.List;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.state.live.host.Host;
-import org.apache.ambari.server.state.live.host.HostState;
 
+/**
+ * Single entity that tracks all clusters and hosts that are managed
+ * by the Ambari server
+ */
 public interface Clusters {
 
   /**
@@ -39,26 +42,48 @@ public interface Clusters {
    */
   public Cluster getCluster(String clusterName) throws AmbariException;
 
-  public boolean handleHeartbeat(String hostname, long timestamp);
-
-  public void updateStatus(String hostname, String status);
-
+  /**
+   * Get all hosts being tracked by the Ambari server
+   * @return
+   */
   public List<Host> getAllHosts();
 
-  public List<String> getHostComponents(String hostname);
-
-  public void handleRegistration(String hostname);
-
   /**
    * Returns all the cluster names for this hostname.
    * @param hostname
    * @return List of cluster names
+   * @throws AmbariException
    */
-  public List<Cluster> getClusters(String hostname);
+  public List<Cluster> getClustersForHost(String hostname)
+      throws AmbariException;
 
   /**
-   * Get a Host object
+   * Get a Host object managed by this server
+   * @param hostname Name of the host requested
+   * @return Host object
+   * @throws AmbariException
    */
-  public Host getHost(String host) throws AmbariException;
+  public Host getHost(String hostname) throws AmbariException;
+
+  /**
+   * Add a Host object to be managed by this server
+   * @param hostname Host to be added
+   * @throws AmbariException
+   */
+  public void addHost(String hostname) throws AmbariException;
+
+  /**
+   * Map host to the given cluster.
+   * A host can belong to multiple clusters.
+   * @param hostname
+   * @param clusterName
+   * @throws AmbariException
+   */
+  public void mapHostToCluster(String hostname, String clusterName)
+      throws AmbariException;
+
+  // TODO for Jitendra to fix in Heartbeat Handler as this function
+  // will not be supported
+  public List<String> getHostComponents(String hostname);
 
 }

+ 50 - 27
ambari-server/src/main/java/org/apache/ambari/server/state/live/ClustersImpl.java

@@ -18,23 +18,33 @@
 
 package org.apache.ambari.server.state.live;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
+import org.apache.ambari.server.HostNotFoundException;
 import org.apache.ambari.server.state.live.host.Host;
+import org.apache.ambari.server.state.live.host.HostImpl;
 
 public class ClustersImpl implements Clusters {
 
   private Map<String, Cluster> clusters;
-
-  // TODO
-  // private Map<String, Host> hosts;
+  private Map<Long, Cluster> clustersById;
+  private Map<String, Host> hosts;
+  private Map<String, Set<Cluster>> hostClusterMap;
 
   public ClustersImpl() {
     clusters = new HashMap<String, Cluster>();
+    clustersById = new HashMap<Long, Cluster>();
+    hosts = new HashMap<String, Host>();
+    hostClusterMap = new HashMap<String, Set<Cluster>>();
+
   }
 
   @Override
@@ -44,11 +54,18 @@ public class ClustersImpl implements Clusters {
       throw new AmbariException("Duplicate entry for Cluster"
           + ", clusterName= " + clusterName);
     }
-    clusters.put(clusterName, new ClusterImpl(clusterName));
+    // TODO persist cluster into DB
+    // retrieve new cluster id
+    // add cluster id -> cluster mapping into clustersById
+    long clusterId = 0;
+    Cluster impl = new ClusterImpl(this, clusterId, clusterName);
+    clusters.put(clusterName, impl);
+    clustersById.put(clusterId, impl);
   }
 
   @Override
-  public Cluster getCluster(String clusterName) throws AmbariException {
+  public synchronized Cluster getCluster(String clusterName)
+      throws AmbariException {
     if (!clusters.containsKey(clusterName)) {
       throw new ClusterNotFoundException(clusterName);
     }
@@ -56,43 +73,49 @@ public class ClustersImpl implements Clusters {
   }
 
   @Override
-  public boolean handleHeartbeat(String hostname, long timestamp) {
-    // TODO Auto-generated method stub
-    return false;
+  public synchronized List<Host> getAllHosts() {
+    return new ArrayList<Host>(hosts.values());
   }
 
   @Override
-  public void updateStatus(String hostname, String status) {
-    // TODO Auto-generated method stub
-    
-  }
-
-  @Override
-  public List<Host> getAllHosts() {
-    // TODO Auto-generated method stub
-    return null;
+  public synchronized List<Cluster> getClustersForHost(String hostname)
+      throws AmbariException {
+    if (!hostClusterMap.containsKey(hostname)) {
+      throw new HostNotFoundException(hostname);
+    }
+    List<Cluster> cList = new ArrayList<Cluster>();
+    cList.addAll(hostClusterMap.get(hostname));
+    return cList;
   }
 
   @Override
-  public List<String> getHostComponents(String hostname) {
-    // TODO Auto-generated method stub
-    return null;
+  public synchronized Host getHost(String hostname) throws AmbariException {
+    return hosts.get(hostname);
   }
 
   @Override
-  public void handleRegistration(String hostname) {
-    // TODO Auto-generated method stub
-    
+  public synchronized void addHost(String hostname) throws AmbariException {
+    if (hosts.containsKey(hostname)) {
+      throw new AmbariException("Duplicate entry for Host"
+          + ", hostName= " + hostname);
+    }
+    hosts.put(hostname, new HostImpl(hostname));
+    hostClusterMap.put(hostname, new HashSet<Cluster>());
   }
 
   @Override
-  public List<Cluster> getClusters(String hostname) {
-    // TODO Auto-generated method stub
-    return null;
+  public synchronized void mapHostToCluster(String hostname,
+      String clusterName) throws AmbariException {
+    getCluster(clusterName);
+    getHost(hostname);
+    if (!hostClusterMap.containsKey(hostname)) {
+      throw new HostNotFoundException(hostname);
+    }
+    hostClusterMap.get(hostname).add(getCluster(clusterName));
   }
 
   @Override
-  public Host getHost(String host) throws AmbariException {
+  public List<String> getHostComponents(String hostname) {
     // TODO Auto-generated method stub
     return null;
   }

+ 10 - 10
ambari-server/src/main/java/org/apache/ambari/server/state/live/host/HostImpl.java

@@ -136,12 +136,12 @@ public class HostImpl implements Host {
    // Transition from INIT state
    // when the initial registration request is received
    .addTransition(HostState.INIT, HostState.WAITING_FOR_HOST_STATUS_UPDATES,
-       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())       
-       
+       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())
+
    // Transition from WAITING_FOR_STATUS_UPDATES state
    // when the host has responded to its status update requests
    // TODO this will create problems if the host is not healthy
-   // TODO Based on discussion with Jitendra, ignoring this for now    
+   // TODO Based on discussion with Jitendra, ignoring this for now
    .addTransition(HostState.WAITING_FOR_HOST_STATUS_UPDATES, HostState.HEALTHY,
        HostEventType.HOST_STATUS_UPDATES_RECEIVED,
        new HostStatusUpdatesReceivedTransition())
@@ -168,10 +168,10 @@ public class HostImpl implements Host {
    .addTransition(HostState.HEALTHY, HostState.UNHEALTHY,
        HostEventType.HOST_HEARTBEAT_UNHEALTHY,
        new HostBecameUnhealthyTransition())
-   // if a new registration request is received   
+   // if a new registration request is received
    .addTransition(HostState.HEALTHY,
        HostState.WAITING_FOR_HOST_STATUS_UPDATES,
-       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())       
+       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())
 
    // Transitions from UNHEALTHY state
    // when a normal heartbeat is received
@@ -186,20 +186,20 @@ public class HostImpl implements Host {
    .addTransition(HostState.UNHEALTHY, HostState.HEARTBEAT_LOST,
        HostEventType.HOST_HEARTBEAT_LOST,
        new HostHeartbeatLostTransition())
-   // if a new registration request is received   
+   // if a new registration request is received
    .addTransition(HostState.UNHEALTHY,
        HostState.WAITING_FOR_HOST_STATUS_UPDATES,
-       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())       
+       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())
 
    // Transitions from HEARTBEAT_LOST state
    // when a heartbeat is not received within the configured timeout period
    .addTransition(HostState.HEARTBEAT_LOST, HostState.HEARTBEAT_LOST,
        HostEventType.HOST_HEARTBEAT_LOST)
-   // if a new registration request is received   
+   // if a new registration request is received
    .addTransition(HostState.HEARTBEAT_LOST,
        HostState.WAITING_FOR_HOST_STATUS_UPDATES,
-       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())       
-       
+       HostEventType.HOST_REGISTRATION_REQUEST, new HostRegistrationReceived())
+
    .installTopology();
 
   private final StateMachine<HostState, HostEventType, HostEvent> stateMachine;

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/live/host/HostStatusUpdatesReceivedEvent.java

@@ -21,7 +21,7 @@ package org.apache.ambari.server.state.live.host;
 public class HostStatusUpdatesReceivedEvent extends HostEvent {
 
   private final long timestamp;
-  
+
   // TODO need to add any additional information required for verification
   // tracking
   public HostStatusUpdatesReceivedEvent(String hostName,

+ 11 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/live/svccomphost/ServiceComponentHost.java

@@ -26,6 +26,17 @@ import org.apache.ambari.server.state.live.job.Job;
 
 public interface ServiceComponentHost {
 
+  /**
+   * Get the Cluster that this object maps to
+   */
+  public long getClusterId();
+
+  /**
+   * Get the Service this object maps to
+   * @return Name of the Service
+   */
+  public String getServiceName();
+
   /**
    * Get the ServiceComponent this object maps to
    * @return Name of the ServiceComponent

+ 16 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/live/svccomphost/ServiceComponentHostImpl.java

@@ -41,6 +41,8 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
 
   private ServiceComponentHostState state;
 
+  private final long clusterId;
+  private final String serviceName;
   private final String serviceComponentName;
   private final String hostName;
 
@@ -357,7 +359,8 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     }
   }
 
-  public ServiceComponentHostImpl(String serviceComponentName,
+  public ServiceComponentHostImpl(long clusterId,
+      String serviceName, String serviceComponentName,
       String hostName, boolean isClient) {
     super();
     if (isClient) {
@@ -368,6 +371,8 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     ReadWriteLock rwLock = new ReentrantReadWriteLock();
     this.readLock = rwLock.readLock();
     this.writeLock = rwLock.writeLock();
+    this.clusterId = clusterId;
+    this.serviceName = serviceName;
     this.serviceComponentName = serviceComponentName;
     this.hostName = hostName;
     this.state = new ServiceComponentHostState();
@@ -533,4 +538,14 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     }
   }
 
+  @Override
+  public long getClusterId() {
+    return clusterId;
+  }
+
+  @Override
+  public String getServiceName() {
+    return serviceName;
+  }
+
 }

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyList.java

@@ -25,8 +25,8 @@ public class JaxbMapKeyList {
   @XmlElement public String  key;
   @XmlElement public List<String> value;
 
-  private JaxbMapKeyList() {} 
-  
+  private JaxbMapKeyList() {}
+
   public JaxbMapKeyList(String key, List<String> value)
   {
     this.key   = key;

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyMap.java

@@ -25,8 +25,8 @@ public class JaxbMapKeyMap {
   @XmlElement public String  key;
   @XmlElement public List<JaxbMapKeyVal> value;
 
-  private JaxbMapKeyMap() {} 
-  
+  private JaxbMapKeyMap() {}
+
   public JaxbMapKeyMap(String key, List<JaxbMapKeyVal> value)
   {
     this.key   = key;

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyMapAdapter.java

@@ -28,7 +28,7 @@ public class JaxbMapKeyMapAdapter extends
     XmlAdapter<List<JaxbMapKeyMap>, Map<String, Map<String, String>>> {
 
   private static JaxbMapKeyValAdapter mapAdapter = new JaxbMapKeyValAdapter();
-  
+
   @Override
   public List<JaxbMapKeyMap> marshal(Map<String, Map<String, String>> map)
       throws Exception {
@@ -56,4 +56,4 @@ public class JaxbMapKeyMapAdapter extends
     }
     return map;
   }
-}
+}

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/utils/JaxbMapKeyVal.java

@@ -30,11 +30,11 @@ public class JaxbMapKeyVal {
   @XmlElement public String  key;
   @XmlElement public String value;
 
-  private JaxbMapKeyVal() {} 
-  
+  private JaxbMapKeyVal() {}
+
   public JaxbMapKeyVal(String key, String value)
   {
     this.key   = key;
     this.value = value;
   }
-}
+}

+ 8 - 8
ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionScheduler.java

@@ -56,36 +56,36 @@ public class TestActionScheduler {
    // ha.setManifest("1-977-manifest");
     s.addHostAction(hostname, ha);
     when(db.getPendingStages()).thenReturn(stages);
-    
+
     //Keep large number of attempts so that the task is not expired finally
     //Small action timeout to test rescheduling
     ActionScheduler scheduler = new ActionScheduler(1000, 100, db, aq, fsm, 10000);
     // Start the thread
     scheduler.start();
-    
+
     Thread.sleep(1000);
     List<AgentCommand> ac = aq.dequeueAll(hostname);
     assertEquals(1, ac.size());
     assertTrue(ac.get(0) instanceof ExecutionCommand);
     assertEquals("1-977", ((ExecutionCommand) (ac.get(0))).getCommandId());
-    
+
     //The action status has not changed, it should be queued again.
     Thread.sleep(1000);
     ac = aq.dequeueAll(hostname);
     assertEquals(1, ac.size());
     assertTrue(ac.get(0) instanceof ExecutionCommand);
     assertEquals("1-977", ((ExecutionCommand) (ac.get(0))).getCommandId());
-    
+
     //Now change the action status
     hrc.setStatus(HostRoleStatus.COMPLETED);
     ac = aq.dequeueAll(hostname);
-    
+
     //Wait for sometime, it shouldn't be scheduled this time.
     Thread.sleep(1000);
     ac = aq.dequeueAll(hostname);
     assertEquals(0, ac.size());
   }
-  
+
   /**
    * Test whether scheduler times out an action
    */
@@ -108,13 +108,13 @@ public class TestActionScheduler {
     // ha.setManifest("1-977-manifest");
     s.addHostAction(hostname, ha);
     when(db.getPendingStages()).thenReturn(stages);
-    
+
     //Keep large number of attempts so that the task is not expired finally
     //Small action timeout to test rescheduling
     ActionScheduler scheduler = new ActionScheduler(100, 100, db, aq, fsm, 3);
     // Start the thread
     scheduler.start();
-    
+
     Thread.sleep(500);
     //TODO timeoutHostRole must be called exactly once but in this case the state
     //in the db continues to be pending therefore it is processed multiple times.

+ 11 - 11
ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java

@@ -51,17 +51,17 @@ public class AgentResourceTest extends JerseyTest {
   HeartBeatHandler handler;
   ActionManager actionManager;
   Injector injector;
-  
+
   public AgentResourceTest() {
     super(new WebAppDescriptor.Builder(PACKAGE_NAME).servletClass(ServletContainer.class)
         .build());
   }
-  
+
   public class MockModule extends AbstractModule {
-    
+
     RegistrationResponse response = new RegistrationResponse();
     HeartBeatResponse hresponse = new HeartBeatResponse();
-    
+
     @Override
     protected void configure() {
       handler = mock(HeartBeatHandler.class);
@@ -81,9 +81,9 @@ public class AgentResourceTest extends JerseyTest {
       bind(ActionManager.class).toInstance(actionManager);
       bind(AgentCommand.class).to(ExecutionCommand.class);
       bind(HeartBeatHandler.class).toInstance(handler);
-    }    
+    }
   }
-  
+
   @Override
   public void setUp() throws Exception {
     super.setUp();
@@ -91,7 +91,7 @@ public class AgentResourceTest extends JerseyTest {
     injector = Guice.createInjector(new MockModule());
     injector.injectMembers(handler);
   }
-  
+
   private JSONObject createDummyJSONRegister() throws JSONException {
     JSONObject json = new JSONObject();
     json.append("responseId" , -1);
@@ -99,7 +99,7 @@ public class AgentResourceTest extends JerseyTest {
     json.append("hostname",   "dummyHost");
     return json;
   }
-  
+
   private JSONObject createDummyHeartBeat() throws JSONException {
     JSONObject json = new JSONObject();
     json.put("responseId", -1);
@@ -107,7 +107,7 @@ public class AgentResourceTest extends JerseyTest {
     json.put("hostname", "dummyHost");
     return json;
   }
-  
+
   @Test
   public void agentRegistration() throws UniformInterfaceException, JSONException {
     RegistrationResponse response;
@@ -117,14 +117,14 @@ public class AgentResourceTest extends JerseyTest {
     LOG.info("Returned from Server " + response.getResponseStatus());
     Assert.assertEquals(response.getResponseStatus(), RegistrationStatus.OK);
   }
-  
+
   @Test
   public void agentHeartBeat() throws UniformInterfaceException, JSONException {
     HeartBeatResponse response;
     WebResource resource = resource();
     response = resource.path("/heartbeat/dummyhost").type(MediaType.APPLICATION_JSON)
         .post(HeartBeatResponse.class, createDummyHeartBeat());
-    LOG.info("Returned from Server: " + "clusterid = " + response.getClusterId() 
+    LOG.info("Returned from Server: " + "clusterid = " + response.getClusterId()
         + " responseid=" +   response.getResponseId());
     Assert.assertEquals(response.getResponseId(), 0L);
   }

+ 12 - 12
ambari-server/src/test/java/org/apache/ambari/server/bootstrap/BootStrapResourceTest.java

@@ -51,17 +51,17 @@ import com.sun.jersey.test.framework.WebAppDescriptor;
  *  Testing bootstrap API.
  */
 public class BootStrapResourceTest extends JerseyTest {
-  
+
   static String PACKAGE_NAME = "org.apache.ambari.server.api.rest";
   private static Log LOG = LogFactory.getLog(AgentResourceTest.class);
   Injector injector;
   BootStrapImpl bsImpl;
-  
+
   public BootStrapResourceTest() {
     super(new WebAppDescriptor.Builder(PACKAGE_NAME).servletClass(ServletContainer.class)
         .build());
   }
-  
+
   public class MockModule extends AbstractModule {
     @Override
     protected void configure() {
@@ -70,22 +70,22 @@ public class BootStrapResourceTest extends JerseyTest {
       when(bsImpl.runBootStrap(any(SshHostInfo.class))).thenReturn(generateBSResponse());
       bind(BootStrapImpl.class).toInstance(bsImpl);
       requestStaticInjection(BootStrapResource.class);
-    }    
+    }
   }
-  
+
   @Override
   public void setUp() throws Exception {
     super.setUp();
     injector = Guice.createInjector(new MockModule());
   }
-  
+
   protected JSONObject createDummySshInfo() throws JSONException {
     JSONObject json = new JSONObject();
     json.put("sshkey", "awesome");
     json.put("hosts", new ArrayList<String>());
     return json;
   }
-  
+
   protected BSResponse generateBSResponse() {
     BSResponse response = new BSResponse();
     response.setLog("Logging");
@@ -93,7 +93,7 @@ public class BootStrapResourceTest extends JerseyTest {
     response.setStatus(BSRunStat.OK);
     return response;
   }
-  
+
   protected BootStrapStatus generateDummyBSStatus() {
     BootStrapStatus status = new BootStrapStatus();
     status.setLog("Logging ");
@@ -101,24 +101,24 @@ public class BootStrapResourceTest extends JerseyTest {
     status.setHostsStatus(new ArrayList<BSHostStatus>());
     return status;
   }
-  
+
   @Test
   public void bootStrapGet() throws UniformInterfaceException, JSONException {
     WebResource webResource = resource();
     BootStrapStatus status = webResource.path("/bootstrap/0").type(
         MediaType.APPLICATION_JSON)
         .get(BootStrapStatus.class);
-    LOG.info("GET Response from the API " + status.getLog() + " " + 
+    LOG.info("GET Response from the API " + status.getLog() + " " +
         status.getStatus());
     Assert.assertEquals(status.getStatus(), BSStat.ERROR);
   }
-  
+
   @Test
   public void bootStrapPost() throws UniformInterfaceException, JSONException {
     WebResource webResource = resource();
     JSONObject object = webResource.path("/bootstrap").type(
         MediaType.APPLICATION_JSON).post(JSONObject.class, createDummySshInfo());
-    
+
     Assert.assertEquals("OK", object.get("status"));
   }
 }

+ 9 - 9
ambari-server/src/test/java/org/apache/ambari/server/bootstrap/BootStrapTest.java

@@ -44,23 +44,23 @@ import org.junit.rules.TemporaryFolder;
 public class BootStrapTest extends TestCase {
   private static Log LOG = LogFactory.getLog(BootStrapTest.class);
   public TemporaryFolder temp = new TemporaryFolder();
-  
+
   @Before
   public void setUp() throws IOException {
     temp.create();
   }
-  
+
   @After
   public void tearDown() throws IOException {
     temp.delete();
   }
-  
+
   @Test
   public void testRun() throws Exception {
     Properties properties = new Properties();
     String bootdir =  temp.newFolder("bootdir").toString();
     LOG.info("Bootdir is " + bootdir);
-    properties.setProperty(Configuration.BOOTSTRAP_DIR, 
+    properties.setProperty(Configuration.BOOTSTRAP_DIR,
        bootdir);
     properties.setProperty(Configuration.BOOTSTRAP_SCRIPT, "echo");
     properties.setProperty(Configuration.SRVR_KSTR_DIR_KEY, "target" + File.separator + "classes");
@@ -84,14 +84,14 @@ public class BootStrapTest extends TestCase {
         Thread.sleep(100);
         num++;
     }
-    LOG.info("Status: log " + status.getLog() + " status=" + status.getStatus() 
+    LOG.info("Status: log " + status.getLog() + " status=" + status.getStatus()
         );
     /* Note its an echo command so it should echo host1,host2 */
     Assert.assertTrue(status.getLog().contains("host1,host2"));
     Assert.assertEquals(BSStat.SUCCESS, status.getStatus());
   }
-  
-  
+
+
   @Test
   public void testPolling() throws Exception {
     File tmpFolder = temp.newFolder("bootstrap");
@@ -115,8 +115,8 @@ public class BootStrapTest extends TestCase {
     Assert.assertEquals(polledHostStatus.get(1).getHostName(), "host2");
     Assert.assertEquals(polledHostStatus.get(1).getLog(), "err_log_2");
     Assert.assertEquals(polledHostStatus.get(1).getStatus(), "DONE");
-    
+
 
   }
-  
+
 }

+ 14 - 14
ambari-server/src/test/java/org/apache/ambari/server/security/CertGenerationTest.java

@@ -42,24 +42,24 @@ public class CertGenerationTest extends TestCase {
 	
   private static Log LOG = LogFactory.getLog(CertGenerationTest.class);
   public TemporaryFolder temp = new TemporaryFolder();
-  
+
   Injector injector;
-  
+
   private static CertificateManager certMan;
-  
+
   @Inject
   static void init(CertificateManager instance) {
     certMan = instance;
   }
 
-  
+
   private class SecurityModule extends AbstractModule {
     @Override
     protected void configure() {
       requestStaticInjection(CertGenerationTest.class);
     }
   }
-	  
+	
   @Before
   public void setUp() throws IOException {
     temp.create();
@@ -69,37 +69,37 @@ public class CertGenerationTest extends TestCase {
     FileOutputStream out = new FileOutputStream(temp.getRoot().getAbsolutePath() + File.separator + Configuration.CONFIG_FILE);
     props.store(out, "");
     out.close();
-  
+
     injector = Guice.createInjector(new SecurityModule());
     certMan = injector.getInstance(CertificateManager.class);
-  
+
     certMan.initRootCert();
   }
-	  
+	
   @After
   public void tearDown() throws IOException {
 	  temp.delete();
   }
-	  
+	
   @Test
   public void testServerCertGen() throws Exception {
-    
+
     File serverCrt = new File(temp.getRoot().getAbsoluteFile() +
     						  File.separator + Configuration.SRVR_CRT_NAME_DEFAULT);
     assertTrue(serverCrt.exists());
   }
-  
+
   @Test
   public void testServerKeyGen() throws Exception {
-    
+
     File serverKey = new File(temp.getRoot().getAbsoluteFile() +
     						  File.separator + Configuration.SRVR_KEY_NAME_DEFAULT);
     assertTrue(serverKey.exists());
   }
-  
+
   @Test
   public void testServerKeystoreGen() throws Exception {
-    
+
     File serverKeyStrore = new File(temp.getRoot().getAbsoluteFile() +
     						  File.separator + Configuration.KSTR_NAME_DEFAULT);
     assertTrue(serverKeyStrore.exists());

+ 24 - 11
ambari-server/src/test/java/org/apache/ambari/server/state/live/TestClusterImpl.java

@@ -56,7 +56,8 @@ public class TestClusterImpl {
     clusters.addCluster("c1");
     c1 = clusters.getCluster("c1");
     Assert.assertEquals("c1", c1.getClusterName());
-    c1.addHost(h1);
+    clusters.addHost(h1);
+    clusters.mapHostToCluster(h1, "c1");
     c1.addServiceComponentHost(s1, sc1, h1, false);
   }
 
@@ -68,10 +69,10 @@ public class TestClusterImpl {
 
   @Test
   public void testAddHost() throws AmbariException {
-    c1.addHost("h2");
+    clusters.addHost("h2");
 
     try {
-      c1.addHost("h2");
+      clusters.addHost("h2");
       fail("Duplicate add should fail");
     }
     catch (AmbariException e) {
@@ -82,6 +83,16 @@ public class TestClusterImpl {
 
   @Test
   public void testAddServiceComponentHost() throws AmbariException {
+    try {
+      c1.addServiceComponentHost("s2", "sc2", "h2", false);
+      fail("Expected failure on invalid cluster/host");
+    } catch (Exception e) {
+      // Expected
+    }
+
+    clusters.addCluster("c2");
+    clusters.addHost("h2");
+    clusters.mapHostToCluster("h2", "c2");
     c1.addServiceComponentHost("s2", "sc2", "h2", false);
 
     try {
@@ -96,13 +107,14 @@ public class TestClusterImpl {
 
   @Test
   public void testGetHostState() throws AmbariException {
-    Assert.assertEquals(HostState.INIT, c1.getHostState(h1));
+    Assert.assertEquals(HostState.INIT, clusters.getHost(h1).getState());
   }
 
   @Test
   public void testSetHostState() throws AmbariException {
-    c1.setHostState(h1, HostState.HEARTBEAT_LOST);
-    Assert.assertEquals(HostState.HEARTBEAT_LOST, c1.getHostState(h1));
+    clusters.getHost(h1).setState(HostState.HEARTBEAT_LOST);
+    Assert.assertEquals(HostState.HEARTBEAT_LOST,
+        clusters.getHost(h1).getState());
   }
 
   @Test
@@ -124,16 +136,17 @@ public class TestClusterImpl {
     AgentVersion agentVersion = new AgentVersion("0.0.x");
     long currentTime = 1001;
 
-    c1.handleHostEvent(h1, new HostRegistrationRequestEvent(h1, agentVersion,
-        currentTime, hostInfo));
+    clusters.getHost(h1).handleEvent(new HostRegistrationRequestEvent(
+        h1, agentVersion, currentTime, hostInfo));
 
     Assert.assertEquals(HostState.WAITING_FOR_HOST_STATUS_UPDATES,
-        c1.getHostState(h1));
+        clusters.getHost(h1).getState());
 
-    c1.setHostState(h1, HostState.HEARTBEAT_LOST);
+    clusters.getHost(h1).setState(HostState.HEARTBEAT_LOST);
 
     try {
-      c1.handleHostEvent(h1, new HostHealthyHeartbeatEvent(h1, currentTime));
+      clusters.getHost(h1).handleEvent(
+          new HostHealthyHeartbeatEvent(h1, currentTime));
       fail("Exception should be thrown on invalid event");
     }
     catch (InvalidStateTransitonException e) {

+ 81 - 1
ambari-server/src/test/java/org/apache/ambari/server/state/live/TestClustersImpl.java

@@ -19,10 +19,14 @@
 package org.apache.ambari.server.state.live;
 
 import static org.junit.Assert.fail;
+
+import java.util.List;
+
 import junit.framework.Assert;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
+import org.apache.ambari.server.state.live.host.Host;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -54,7 +58,7 @@ public class TestClustersImpl {
   }
 
   @Test
-  public void testAddCluster() throws AmbariException {
+  public void testAddAndGetCluster() throws AmbariException {
 
     String c1 = "foo";
     String c2 = "foo";
@@ -86,4 +90,80 @@ public class TestClustersImpl {
     Assert.assertEquals(c2, clusters.getCluster(c2).getClusterName());
 
   }
+
+
+  @Test
+  public void testAddAndGetHost() throws AmbariException {
+    String h1 = "h1";
+    String h2 = "h2";
+    String h3 = "h3";
+
+    clusters.addHost(h1);
+
+    try {
+      clusters.addHost(h1);
+      fail("Expected exception on duplicate host entry");
+    } catch (Exception e) {
+      // Expected
+    }
+
+    clusters.addHost(h2);
+    clusters.addHost(h3);
+
+    List<Host> hosts = clusters.getAllHosts();
+    Assert.assertEquals(3, hosts.size());
+
+    Assert.assertNotNull(clusters.getHost(h1));
+    Assert.assertNotNull(clusters.getHost(h2));
+    Assert.assertNotNull(clusters.getHost(h3));
+
+  }
+
+  @Test
+  public void testClusterHostMapping() throws AmbariException {
+    String c1 = "c1";
+    String c2 = "c2";
+    String h1 = "h1";
+    String h2 = "h2";
+    String h3 = "h3";
+
+    try {
+      clusters.mapHostToCluster(h1, c1);
+      fail("Expected exception for invalid cluster/host");
+    } catch (Exception e) {
+      // Expected
+    }
+
+    clusters.addCluster(c1);
+    clusters.addCluster(c2);
+    Assert.assertNotNull(clusters.getCluster(c1));
+    Assert.assertNotNull(clusters.getCluster(c2));
+    try {
+      clusters.mapHostToCluster(h1, c1);
+      fail("Expected exception for invalid host");
+    } catch (Exception e) {
+      // Expected
+    }
+
+    clusters.addHost(h1);
+    clusters.addHost(h2);
+    clusters.addHost(h3);
+    Assert.assertNotNull(clusters.getHost(h1));
+
+    clusters.mapHostToCluster(h1, c1);
+    clusters.mapHostToCluster(h1, c2);
+    clusters.mapHostToCluster(h2, c1);
+    clusters.mapHostToCluster(h2, c2);
+    clusters.mapHostToCluster(h1, c2);
+
+    List<Cluster> c = clusters.getClustersForHost(h3);
+    Assert.assertEquals(0, c.size());
+
+    c = clusters.getClustersForHost(h1);
+    Assert.assertEquals(2, c.size());
+
+    c = clusters.getClustersForHost(h2);
+    Assert.assertEquals(2, c.size());
+
+  }
 }

+ 7 - 7
ambari-server/src/test/java/org/apache/ambari/server/state/live/host/TestHostImpl.java

@@ -210,7 +210,7 @@ public class TestHostImpl {
       fail("Invalid event should have triggered an exception");
     } catch (Exception e) {
       // Expected
-    }       
+    }
     verifyHostState(host, HostState.HEARTBEAT_LOST);
 
     try {
@@ -218,20 +218,20 @@ public class TestHostImpl {
       fail("Invalid event should have triggered an exception");
     } catch (Exception e) {
       // Expected
-    }       
+    }
     verifyHostState(host, HostState.HEARTBEAT_LOST);
   }
-  
+
   @Test
   public void testHostRegistrationsInAnyState() throws Exception {
     HostImpl host = new HostImpl("foo");
     long counter = 0;
 
     registerHost(host);
-    
+
     ensureHostUpdatesReceived(host);
     registerHost(host);
-    
+
     ensureHostUpdatesReceived(host);
     sendHealthyHeartbeat(host, ++counter);
     verifyHostState(host, HostState.HEALTHY);
@@ -247,9 +247,9 @@ public class TestHostImpl {
     verifyHostState(host, HostState.HEARTBEAT_LOST);
     registerHost(host);
     ensureHostUpdatesReceived(host);
-    
+
     host.setState(HostState.INIT);
     registerHost(host);
-    
+
   }
 }

+ 11 - 11
ambari-server/src/test/java/org/apache/ambari/server/state/live/svccomphost/TestServiceComponentHostImpl.java

@@ -31,10 +31,12 @@ import org.junit.Test;
 
 public class TestServiceComponentHostImpl {
 
-  private ServiceComponentHostImpl createNewServiceComponentHost(String svcComponent,
+  private ServiceComponentHostImpl createNewServiceComponentHost(long clusterId,
+      String svc,
+      String svcComponent,
       String hostName, boolean isClient) {
-    ServiceComponentHostImpl impl = new ServiceComponentHostImpl(svcComponent,
-        hostName, isClient);
+    ServiceComponentHostImpl impl = new ServiceComponentHostImpl(clusterId, svc,
+        svcComponent, hostName, isClient);
     Assert.assertEquals(ServiceComponentHostLiveState.INIT,
         impl.getState().getLiveState());
     return impl;
@@ -42,8 +44,8 @@ public class TestServiceComponentHostImpl {
 
   @Test
   public void testNewServiceComponentHostImpl() {
-    createNewServiceComponentHost("svcComp", "h1", false);
-    createNewServiceComponentHost("svcComp", "h1", true);
+    createNewServiceComponentHost(1, "svc", "svcComp", "h1", false);
+    createNewServiceComponentHost(1, "svc", "svcComp", "h1", true);
   }
 
   private ServiceComponentHostEvent createEvent(ServiceComponentHostImpl impl,
@@ -53,8 +55,6 @@ public class TestServiceComponentHostImpl {
     return event;
   }
 
-
-
   private void runStateChanges(ServiceComponentHostImpl impl,
       ServiceComponentHostEventType startEvent,
       ServiceComponentHostLiveState startState,
@@ -160,8 +160,8 @@ public class TestServiceComponentHostImpl {
 
   @Test
   public void testClientStateFlow() throws Exception {
-    ServiceComponentHostImpl impl = createNewServiceComponentHost("svcComp",
-        "h1", true);
+    ServiceComponentHostImpl impl = createNewServiceComponentHost(1, "svc",
+        "svcComp", "h1", true);
 
     runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_INSTALL,
         ServiceComponentHostLiveState.INIT,
@@ -198,8 +198,8 @@ public class TestServiceComponentHostImpl {
 
   @Test
   public void testDaemonStateFlow() throws Exception {
-    ServiceComponentHostImpl impl = createNewServiceComponentHost("svcComp",
-        "h1", false);
+    ServiceComponentHostImpl impl = createNewServiceComponentHost(1, "svc",
+        "svcComp", "h1", false);
 
     runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_INSTALL,
         ServiceComponentHostLiveState.INIT,