Author: swagle
Date: Thu Mar 14 17:31:50 2013
New Revision: 1456565

URL: http://svn.apache.org/r1456565
Log:
AMBARI-1626. API support to upgrade host component. (Sumit Mohanty via swagle)

Modified:
    incubator/ambari/trunk/CHANGES.txt
    
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
    
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostRequest.java
    
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
    
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
    
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
    incubator/ambari/trunk/ambari-server/src/main/resources/properties.json
    
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
    
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java

Modified: incubator/ambari/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Thu Mar 14 17:31:50 2013
@@ -12,6 +12,8 @@ Trunk (unreleased changes):
 
  NEW FEATURES
 
+ AMBARI-1626. API support to upgrade host component. (Sumit Mohanty via swagle)
+
  AMBARI-1601. Server level action support. (Sumit Mohanty via swagle)
 
  AMBARI-1620. Add heatmaps for Host and Hbase section. (jaimin)

Modified: 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
 Thu Mar 14 17:31:50 2013
@@ -2812,10 +2812,6 @@ public class AmbariManagementControllerI
             h.addDesiredConfig(c.getClusterId(), cr.getServiceName(), 
baseConfig);
 
         }
-
-
-
-
       }
 
       //todo: if attempt was made to update a property other than those
@@ -2894,7 +2890,7 @@ public class AmbariManagementControllerI
 
       if (!hostComponentNames.containsKey(request.getClusterName())) {
         hostComponentNames.put(request.getClusterName(),
-            new HashMap<String, Map<String,Set<String>>>());
+            new HashMap<String, Map<String, Set<String>>>());
       }
       if (!hostComponentNames.get(request.getClusterName())
           .containsKey(request.getServiceName())) {
@@ -2906,7 +2902,7 @@ public class AmbariManagementControllerI
           .containsKey(request.getComponentName())) {
         hostComponentNames.get(request.getClusterName())
             .get(request.getServiceName()).put(request.getComponentName(),
-                new HashSet<String>());
+            new HashSet<String>());
       }
       if (hostComponentNames.get(request.getClusterName())
           .get(request.getServiceName()).get(request.getComponentName())
@@ -2918,12 +2914,11 @@ public class AmbariManagementControllerI
           .get(request.getServiceName()).get(request.getComponentName())
           .add(request.getHostname());
 
-
       Service s = cluster.getService(request.getServiceName());
       ServiceComponent sc = s.getServiceComponent(
-        request.getComponentName());
+          request.getComponentName());
       ServiceComponentHost sch = sc.getServiceComponentHost(
-        request.getHostname());
+          request.getHostname());
       State oldState = sch.getState();
       State newState = null;
       if (request.getDesiredState() != null) {
@@ -2937,7 +2932,7 @@ public class AmbariManagementControllerI
       if (request.getConfigVersions() != null) {
         safeToUpdateConfigsForServiceComponentHost(sch, oldState, newState);
 
-        for (Entry<String,String> entry :
+        for (Entry<String, String> entry :
             request.getConfigVersions().entrySet()) {
           Config config = cluster.getConfig(
               entry.getKey(), entry.getValue());
@@ -2975,6 +2970,27 @@ public class AmbariManagementControllerI
 
       seenNewStates.add(newState);
 
+      boolean upgradeRequest = checkIfUpgradeRequestAndValidate(request, 
cluster, s, sc, sch);
+
+      if (!processingUpgradeRequest && upgradeRequest) {
+        processingUpgradeRequest = true;
+        // this needs to be the first request
+        if (numberOfRequestsProcessed > 1) {
+          throw new AmbariException("An upgrade request cannot be combined 
with " +
+              "other non-upgrade requests.");
+        }
+        fromStackVersion = sch.getStackVersion();
+      }
+
+      if (processingUpgradeRequest) {
+        if (!upgradeRequest) {
+          throw new AmbariException("An upgrade request cannot be combined 
with " +
+              "other non-upgrade requests.");
+        }
+        sch.setState(State.UPGRADING);
+        sch.setDesiredStackVersion(cluster.getCurrentStackVersion());
+      }
+
       State oldSchState = sch.getState();
       if (newState == oldSchState) {
         sch.setDesiredState(newState);
@@ -3038,7 +3054,7 @@ public class AmbariManagementControllerI
       if (request.getConfigVersions() != null) {
         Map<String, Config> updated = new HashMap<String, Config>();
 
-        for (Entry<String,String> entry : 
request.getConfigVersions().entrySet()) {
+        for (Entry<String, String> entry : 
request.getConfigVersions().entrySet()) {
           Config config = cluster.getConfig(
               entry.getKey(), entry.getValue());
           updated.put(config.getType(), config);
@@ -3053,8 +3069,13 @@ public class AmbariManagementControllerI
 
     Cluster cluster = clusters.getCluster(clusterNames.iterator().next());
 
-    List<Stage> stages = doStageCreation(cluster, null,
-        null, changedScHosts, null);
+    Map<String, String> requestParameters = null;
+    if (processingUpgradeRequest) {
+      requestParameters = new HashMap<String, String>();
+      requestParameters.put(Configuration.UPGRADE_TO_STACK, 
gson.toJson(cluster.getCurrentStackVersion()));
+      requestParameters.put(Configuration.UPGRADE_FROM_STACK, 
gson.toJson(fromStackVersion));
+    }
+    List<Stage> stages = doStageCreation(cluster, null, null, changedScHosts, 
requestParameters);
     persistStages(stages);
     updateServiceStates(null, null, changedScHosts);
     if (stages == null || stages.isEmpty()) {
@@ -3064,6 +3085,78 @@ public class AmbariManagementControllerI
     return getRequestStatusResponse(stages.get(0).getRequestId());
   }
 
+  private boolean checkIfUpgradeRequestAndValidate(ServiceComponentHostRequest 
request, Cluster cluster, Service s,
+                                                   ServiceComponent sc, 
ServiceComponentHost sch)
+      throws AmbariException {
+    boolean isUpgradeRequest = false;
+    String requestedStackIdString = request.getDesiredStackId();
+    StackId requestedStackId;
+
+    if (requestedStackIdString == null) {
+      return isUpgradeRequest;
+    }
+
+    try {
+      requestedStackId = new StackId(request.getDesiredStackId());
+    } catch (RuntimeException re) {
+      throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+          "Invalid desired stack id");
+    }
+
+    StackId clusterStackId = cluster.getCurrentStackVersion();
+    StackId currentSchStackId = sch.getStackVersion();
+    if (clusterStackId == null || clusterStackId.getStackName().equals("")) {
+      // cluster has not been upgraded yet
+      if (requestedStackId.compareTo(currentSchStackId) != 0) {
+        throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+            "Cluster has not been upgraded yet, component host cannot be 
upgraded");
+      }
+    } else {
+      // cluster is upgraded and sch can be independently upgraded
+      if 
(clusterStackId.getStackName().compareTo(requestedStackId.getStackName()) != 0) 
{
+        throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+            "Deployed stack name and requested stack names do not match");
+      }
+      if (clusterStackId.compareTo(requestedStackId) != 0) {
+        throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+            "Component host can only be upgraded to the same version as the 
cluster");
+      } else if (requestedStackId.compareTo(currentSchStackId) > 0) {
+        isUpgradeRequest = true;
+        if (sch.getState() != State.INSTALLED && sch.getState() != 
State.UPGRADING
+            && sch.getState() != State.UPGRADE_FAILED) {
+          throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+              "Component host is in an invalid state for upgrade");
+        }
+        // Ensure that the request only updates the stack id
+        if (request.getConfigVersions() != null) {
+          throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+              "Upgrade cannot be accompanied with config modification");
+        }
+        if (!request.getDesiredState().equals(State.INSTALLED.toString())) {
+          throw getHostComponentUpgradeException(request, cluster, s, sc, sch,
+              "The desired state for an upgrade request must be " + 
State.INSTALLED);
+        }
+      }
+    }
+
+    return isUpgradeRequest;
+  }
+
+  private AmbariException 
getHostComponentUpgradeException(ServiceComponentHostRequest request, Cluster 
cluster,
+                                                           Service s, 
ServiceComponent sc, ServiceComponentHost sch,
+                                                           String message) 
throws AmbariException {
+    return new AmbariException(message
+        + ", clusterName=" + cluster.getClusterName()
+        + ", clusterId=" + cluster.getClusterId()
+        + ", serviceName=" + s.getName()
+        + ", componentName=" + sc.getName()
+        + ", hostname=" + sch.getHostName()
+        + ", requestedStackId=" + request.getDesiredStackId()
+        + ", requestedState=" + request.getDesiredState()
+        + ", clusterStackId=" + cluster.getCurrentStackVersion()
+        + ", hostComponentCurrentStackId=" + sch.getStackVersion());
+  }
+
   @Override
   public synchronized void updateUsers(Set<UserRequest> requests) throws 
AmbariException {
     for (UserRequest request : requests) {

Modified: 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostRequest.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostRequest.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostRequest.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostRequest.java
 Thu Mar 14 17:31:50 2013
@@ -35,6 +35,8 @@ public class ServiceComponentHostRequest
 
   private String desiredState; // CREATE/UPDATE
 
+  private String desiredStackId; // UPDATE
+
   public ServiceComponentHostRequest(String clusterName,
                                      String serviceName,
                                      String componentName, String hostname,
@@ -119,6 +121,20 @@ public class ServiceComponentHostRequest
   }
 
   /**
+   * @return the desiredStackId
+   */
+  public String getDesiredStackId() {
+    return desiredStackId;
+  }
+
+  /**
+   * @param desiredStackId the desiredStackId to set
+   */
+  public void setDesiredStackId(String desiredStackId) {
+    this.desiredStackId = desiredStackId;
+  }
+
+  /**
    * @return the clusterName
    */
   public String getClusterName() {
@@ -132,7 +148,6 @@ public class ServiceComponentHostRequest
     this.clusterName = clusterName;
   }
 
-
   public String toString() {
     StringBuilder sb = new StringBuilder();
     sb.append("{"
@@ -141,6 +156,7 @@ public class ServiceComponentHostRequest
         + ", componentName=" + componentName
         + ", hostname=" + hostname
         + ", desiredState=" + desiredState
+        + ", desiredStackId=" + desiredStackId
         + "}");
     return sb.toString();
   }

Modified: 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
 Thu Mar 14 17:31:50 2013
@@ -39,6 +39,8 @@ public class ServiceComponentHostRespons
 
   private String stackVersion;
 
+  private String desiredStackVersion;
+
   private String desiredState;
   
   private String ha_status = "NA";
@@ -48,8 +50,8 @@ public class ServiceComponentHostRespons
                                       String componentName, String hostname,
                                       Map<String, String> configVersions,
                                       Map<String, String> desiredConfigs,
-                                      String liveState,
-                                      String stackVersion, String 
desiredState) {
+                                      String liveState, String stackVersion,
+                                      String desiredState, String 
desiredStackVersion) {
     super();
     this.clusterName = clusterName;
     this.serviceName = serviceName;
@@ -60,6 +62,7 @@ public class ServiceComponentHostRespons
     this.liveState = liveState;
     this.stackVersion = stackVersion;
     this.desiredState = desiredState;
+    this.desiredStackVersion = desiredStackVersion;
   }
 
   /**
@@ -161,6 +164,20 @@ public class ServiceComponentHostRespons
   }
 
   /**
+   * @return the desiredStackVersion
+   */
+  public String getDesiredStackVersion() {
+    return desiredStackVersion;
+  }
+
+  /**
+   * @param desiredStackVersion the desiredStackVersion to set
+   */
+  public void setDesiredStackVersion(String desiredStackVersion) {
+    this.desiredStackVersion = desiredStackVersion;
+  }
+
+  /**
    * @return the clusterName
    */
   public String getClusterName() {

Modified: 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
 Thu Mar 14 17:31:50 2013
@@ -40,15 +40,28 @@ class HostComponentResourceProvider exte
   // ----- Property ID constants ---------------------------------------------
 
   // Host Components
-  protected static final String HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID   = 
PropertyHelper.getPropertyId("HostRoles", "cluster_name");
-  protected static final String HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID   = 
PropertyHelper.getPropertyId("HostRoles", "service_name");
-  protected static final String HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID = 
PropertyHelper.getPropertyId("HostRoles", "component_name");
-  protected static final String HOST_COMPONENT_HOST_NAME_PROPERTY_ID      = 
PropertyHelper.getPropertyId("HostRoles", "host_name");
-  protected static final String HOST_COMPONENT_STATE_PROPERTY_ID          = 
PropertyHelper.getPropertyId("HostRoles", "state");
-  protected static final String HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID  = 
PropertyHelper.getPropertyId("HostRoles", "desired_state");
-  protected static final String HOST_COMPONENT_CONFIGS_PROPERTY_ID          = 
PropertyHelper.getPropertyId("HostRoles", "configs");
-  protected static final String HOST_COMPONENT_DESIRED_CONFIGS_PROPERTY_ID  = 
PropertyHelper.getPropertyId("HostRoles", "desired_configs");
-  protected static final String HOST_COMPONENT_HIGH_AVAILABILITY_PROPERTY_ID  
= PropertyHelper.getPropertyId("HostRoles", "ha_status");
+  protected static final String HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "cluster_name");
+  protected static final String HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "service_name");
+  protected static final String HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "component_name");
+  protected static final String HOST_COMPONENT_HOST_NAME_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "host_name");
+  protected static final String HOST_COMPONENT_STATE_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "state");
+  protected static final String HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "desired_state");
+  protected static final String HOST_COMPONENT_CONFIGS_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "configs");
+  protected static final String HOST_COMPONENT_DESIRED_CONFIGS_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "desired_configs");
+  protected static final String HOST_COMPONENT_HIGH_AVAILABILITY_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "ha_status");
+  protected static final String HOST_COMPONENT_STACK_ID_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "stack_id");
+  protected static final String HOST_COMPONENT_DESIRED_STACK_ID_PROPERTY_ID
+      = PropertyHelper.getPropertyId("HostRoles", "desired_stack_id");
 
   private static Set<String> pkPropertyIds =
       new HashSet<String>(Arrays.asList(new String[]{
@@ -132,6 +145,10 @@ class HostComponentResourceProvider exte
       setResourceProperty(resource, HOST_COMPONENT_HOST_NAME_PROPERTY_ID, 
response.getHostname(), requestedIds);
       setResourceProperty(resource, HOST_COMPONENT_STATE_PROPERTY_ID, 
response.getLiveState(), requestedIds);
       setResourceProperty(resource, HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID, 
response.getDesiredState(), requestedIds);
+      setResourceProperty(resource, HOST_COMPONENT_STACK_ID_PROPERTY_ID,
+          response.getStackVersion(), requestedIds);
+      setResourceProperty(resource, 
HOST_COMPONENT_DESIRED_STACK_ID_PROPERTY_ID,
+          response.getDesiredStackVersion(), requestedIds);
       setResourceProperty(resource, 
HOST_COMPONENT_HIGH_AVAILABILITY_PROPERTY_ID, response.getHa_status(), 
requestedIds);
       setResourceProperty(resource, HOST_COMPONENT_CONFIGS_PROPERTY_ID,
           response.getConfigs(), requestedIds);
@@ -227,6 +244,8 @@ class HostComponentResourceProvider exte
         (String) properties.get(HOST_COMPONENT_HOST_NAME_PROPERTY_ID),
         null,
         (String) properties.get(HOST_COMPONENT_STATE_PROPERTY_ID));
+    serviceComponentHostRequest.setDesiredStackId(
+        (String) properties.get(HOST_COMPONENT_STACK_ID_PROPERTY_ID));
 
     Map<String, String> configMappings =
         ConfigurationResourceProvider.getConfigPropertyValues(properties);

Modified: 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
 Thu Mar 14 17:31:50 2013
@@ -1121,8 +1121,9 @@ public class ServiceComponentHostImpl im
           desiredConfigs,
           getState().toString(),
           getStackVersion().getStackId(),
-          getDesiredState().toString());
-      r.setHa_status(ha_status);
+          getDesiredState().toString(),
+          getDesiredStackVersion().getStackId());
+          r.setHa_status(ha_status);
       return r;
     }
     finally {

Modified: 
incubator/ambari/trunk/ambari-server/src/main/resources/properties.json
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/resources/properties.json?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/resources/properties.json 
(original)
+++ incubator/ambari/trunk/ambari-server/src/main/resources/properties.json Thu 
Mar 14 17:31:50 2013
@@ -57,6 +57,8 @@
         "HostRoles/desired_state",
         "HostRoles/configs",
         "HostRoles/desired_configs",
+        "HostRoles/stack_id",
+        "HostRoles/desired_stack_id",
         "_"
     ],
     "Configuration":[

Modified: 
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
 Thu Mar 14 17:31:50 2013
@@ -2891,6 +2891,312 @@ public class AmbariManagementControllerT
   }
 
   @Test
+  public void testServiceComponentHostUpdateStackId() throws AmbariException {
+    String clusterName = "foo1";
+    createCluster(clusterName);
+    String serviceName1 = "HDFS";
+    createService(clusterName, serviceName1, null);
+    String componentName1 = "NAMENODE";
+    String componentName2 = "DATANODE";
+    createServiceComponent(clusterName, serviceName1, componentName1,
+        State.INIT);
+    createServiceComponent(clusterName, serviceName1, componentName2,
+        State.INIT);
+    String host1 = "h1";
+    clusters.addHost(host1);
+    clusters.getHost("h1").setOsType("centos5");
+    clusters.getHost("h1").persist();
+    String host2 = "h2";
+    clusters.addHost(host2);
+    clusters.getHost("h2").setOsType("centos5");
+    clusters.getHost("h2").persist();
+    clusters.mapHostToCluster(host1, clusterName);
+    clusters.mapHostToCluster(host2, clusterName);
+
+    Set<ServiceComponentHostRequest> set1 =
+        new HashSet<ServiceComponentHostRequest>();
+    ServiceComponentHostRequest r1 =
+        new ServiceComponentHostRequest(clusterName, serviceName1,
+            componentName1, host1, null, State.INIT.toString());
+    ServiceComponentHostRequest r2 =
+        new ServiceComponentHostRequest(clusterName, serviceName1,
+            componentName1, host2, null, State.INIT.toString());
+    ServiceComponentHostRequest r3 =
+        new ServiceComponentHostRequest(clusterName, serviceName1,
+            componentName2, host1, null, State.INIT.toString());
+
+    set1.add(r1);
+    set1.add(r2);
+    set1.add(r3);
+    controller.createHostComponents(set1);
+
+    Cluster c1 = clusters.getCluster(clusterName);
+    Service s1 = c1.getService(serviceName1);
+    ServiceComponent sc1 = s1.getServiceComponent(componentName1);
+    ServiceComponent sc2 = s1.getServiceComponent(componentName2);
+    ServiceComponentHost sch1 = sc1.getServiceComponentHost(host1);
+    ServiceComponentHost sch2 = sc1.getServiceComponentHost(host2);
+    ServiceComponentHost sch3 = sc2.getServiceComponentHost(host1);
+
+    s1.setDesiredState(State.INSTALLED);
+    sc1.setDesiredState(State.INSTALLED);
+    sc2.setDesiredState(State.INSTALLED);
+
+    ServiceComponentHostRequest req1;
+    ServiceComponentHostRequest req2;
+    ServiceComponentHostRequest req3;
+    Set<ServiceComponentHostRequest> reqs =
+        new HashSet<ServiceComponentHostRequest>();
+
+    StackId newStack = new StackId("HDP-0.2");
+    StackId oldStack = new StackId("HDP-0.1");
+    c1.setCurrentStackVersion(newStack);
+    c1.setDesiredStackVersion(newStack);
+    sch1.setState(State.INSTALLED);
+    sch2.setState(State.UPGRADE_FAILED);
+    sch1.setDesiredState(State.INSTALLED);
+    sch2.setDesiredState(State.INSTALLED);
+
+    sch1.setStackVersion(oldStack);
+    sch2.setStackVersion(oldStack);
+    sch1.setDesiredStackVersion(newStack);
+    sch2.setDesiredStackVersion(oldStack);
+
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.INSTALLED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    req2 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host2,
+        null, State.INSTALLED.toString());
+    req2.setDesiredStackId("HDP-0.2");
+    reqs.add(req2);
+
+    RequestStatusResponse resp = controller.updateHostComponents(reqs);
+    List<Stage> stages = actionDB.getAllStages(resp.getRequestId());
+    Assert.assertEquals(1, stages.size());
+    Assert.assertEquals(2, stages.get(0).getOrderedHostRoleCommands().size());
+    Assert.assertEquals(State.UPGRADING, sch1.getState());
+    Assert.assertEquals(State.UPGRADING, sch2.getState());
+    sch1.refresh();
+    Assert.assertTrue(sch1.getDesiredStackVersion().compareTo(newStack) == 0);
+    sch2.refresh();
+    Assert.assertTrue(sch2.getDesiredStackVersion().compareTo(newStack) == 0);
+    for (HostRoleCommand command : stages.get(0).getOrderedHostRoleCommands()) 
{
+      ExecutionCommand execCommand = 
command.getExecutionCommandWrapper().getExecutionCommand();
+      
Assert.assertTrue(execCommand.getCommandParams().containsKey("source_stack_version"));
+      
Assert.assertTrue(execCommand.getCommandParams().containsKey("target_stack_version"));
+      Assert.assertEquals(RoleCommand.UPGRADE, execCommand.getRoleCommand());
+    }
+
+    sch1.setState(State.INSTALLED);
+    sch1.setDesiredState(State.INSTALLED);
+    sch2.setState(State.UPGRADE_FAILED);
+    sch2.setDesiredState(State.INSTALLED);
+    sch3.setState(State.UPGRADE_FAILED);
+    sch3.setDesiredState(State.INSTALLED);
+
+    sch3.setStackVersion(oldStack);
+    sch3.setDesiredStackVersion(newStack);
+
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.INSTALLED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    req2 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host2,
+        null, State.INSTALLED.toString());
+    req2.setDesiredStackId("HDP-0.2");
+    reqs.add(req2);
+    req3 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName2, host1,
+        null, State.INSTALLED.toString());
+    req3.setDesiredStackId("HDP-0.2");
+    reqs.add(req3);
+
+    resp = controller.updateHostComponents(reqs);
+    stages = actionDB.getAllStages(resp.getRequestId());
+    Assert.assertEquals(2, stages.size());
+    Assert.assertEquals(2, stages.get(0).getOrderedHostRoleCommands().size());
+    Assert.assertEquals(State.UPGRADING, sch1.getState());
+    Assert.assertEquals(State.UPGRADING, sch2.getState());
+    Assert.assertEquals(State.UPGRADING, sch3.getState());
+    sch1.refresh();
+    Assert.assertTrue(sch1.getDesiredStackVersion().compareTo(newStack) == 0);
+    sch2.refresh();
+    Assert.assertTrue(sch2.getDesiredStackVersion().compareTo(newStack) == 0);
+    sch3.refresh();
+    Assert.assertTrue(sch3.getDesiredStackVersion().compareTo(newStack) == 0);
+    for (Stage stage : stages) {
+      for (HostRoleCommand command : stage.getOrderedHostRoleCommands()) {
+        ExecutionCommand execCommand = 
command.getExecutionCommandWrapper().getExecutionCommand();
+        
Assert.assertTrue(execCommand.getCommandParams().containsKey("source_stack_version"));
+        
Assert.assertTrue(execCommand.getCommandParams().containsKey("target_stack_version"));
+        Assert.assertEquals("{\"stackName\":\"HDP\",\"stackVersion\":\"0.2\"}",
+            execCommand.getCommandParams().get("target_stack_version"));
+        Assert.assertEquals(RoleCommand.UPGRADE, execCommand.getRoleCommand());
+      }
+    }
+  }
+
+  @Test
+  public void testServiceComponentHostUpdateStackIdError() throws 
AmbariException {
+    String clusterName = "foo1";
+    createCluster(clusterName);
+    String serviceName1 = "HDFS";
+    createService(clusterName, serviceName1, null);
+    String componentName1 = "NAMENODE";
+    createServiceComponent(clusterName, serviceName1, componentName1,
+        State.INIT);
+    String host1 = "h1";
+    clusters.addHost(host1);
+    clusters.getHost("h1").setOsType("centos5");
+    clusters.getHost("h1").persist();
+    String host2 = "h2";
+    clusters.addHost(host2);
+    clusters.getHost("h2").setOsType("centos5");
+    clusters.getHost("h2").persist();
+    clusters.mapHostToCluster(host1, clusterName);
+    clusters.mapHostToCluster(host2, clusterName);
+
+    Set<ServiceComponentHostRequest> set1 =
+        new HashSet<ServiceComponentHostRequest>();
+    ServiceComponentHostRequest r1 =
+        new ServiceComponentHostRequest(clusterName, serviceName1,
+            componentName1, host1, null, State.INIT.toString());
+    ServiceComponentHostRequest r2 =
+        new ServiceComponentHostRequest(clusterName, serviceName1,
+            componentName1, host2, null, State.INIT.toString());
+
+    set1.add(r1);
+    set1.add(r2);
+    controller.createHostComponents(set1);
+
+    Cluster c1 = clusters.getCluster(clusterName);
+    Service s1 = c1.getService(serviceName1);
+    ServiceComponent sc1 = s1.getServiceComponent(componentName1);
+    ServiceComponentHost sch1 = sc1.getServiceComponentHost(host1);
+    ServiceComponentHost sch2 = sc1.getServiceComponentHost(host2);
+
+    s1.setDesiredState(State.INIT);
+    sc1.setDesiredState(State.INIT);
+
+    ServiceComponentHostRequest req1;
+    ServiceComponentHostRequest req2;
+    Set<ServiceComponentHostRequest> reqs =
+        new HashSet<ServiceComponentHostRequest>();
+
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.STARTED.toString());
+    req1.setDesiredStackId("invalid stack id");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "Invalid desired stack id");
+
+    c1.setCurrentStackVersion(null);
+    sch1.setStackVersion(new StackId("HDP-0.1"));
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.STARTED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "Cluster has not been upgraded 
yet");
+
+    c1.setCurrentStackVersion(new StackId("HDP2-0.1"));
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.STARTED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "Deployed stack name and 
requested stack names");
+
+    c1.setCurrentStackVersion(new StackId("HDP-0.2"));
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.STARTED.toString());
+    req1.setDesiredStackId("HDP-0.3");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "Component host can only be 
upgraded to the same version");
+
+    c1.setCurrentStackVersion(new StackId("HDP-0.2"));
+    sch1.setState(State.STARTED);
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.STARTED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "Component host is in an invalid 
state for upgrade");
+
+    c1.setCurrentStackVersion(new StackId("HDP-0.2"));
+    sch1.setState(State.UPGRADE_FAILED);
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        new HashMap<String, String>(), State.STARTED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "Upgrade cannot be accompanied 
with config");
+
+    c1.setCurrentStackVersion(new StackId("HDP-0.2"));
+    sch1.setState(State.UPGRADING);
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.STARTED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    updateHostAndCompareExpectedFailure(reqs, "The desired state for an 
upgrade request must be");
+
+    c1.setCurrentStackVersion(new StackId("HDP-0.2"));
+    sch1.setState(State.INSTALLED);
+    sch1.setDesiredState(State.INSTALLED);
+    sch2.setState(State.INSTALLED);
+    sch2.setDesiredState(State.INSTALLED);
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, State.INSTALLED.toString());
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    req2 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host2,
+        null, State.STARTED.toString());
+    reqs.add(req2);
+    updateHostAndCompareExpectedFailure(reqs, "An upgrade request cannot be 
combined with other");
+
+    c1.setCurrentStackVersion(new StackId("HDP-0.2"));
+    sch1.setState(State.UPGRADING);
+    reqs.clear();
+    req1 = new ServiceComponentHostRequest(clusterName, serviceName1,
+        componentName1, host1,
+        null, null);
+    req1.setDesiredStackId("HDP-0.2");
+    reqs.add(req1);
+    RequestStatusResponse resp = controller.updateHostComponents(reqs);
+    Assert.assertNull(resp);
+  }
+
+  private void 
updateHostAndCompareExpectedFailure(Set<ServiceComponentHostRequest> reqs,
+                                                   String expectedMessage) {
+    try {
+      controller.updateHostComponents(reqs);
+      fail("Expected failure: " + expectedMessage);
+    } catch (Exception e) {
+      LOG.info("Actual exception message: " + e.getMessage());
+      Assert.assertTrue(e.getMessage().contains(expectedMessage));
+    }
+  }
+
+  @Test
   public void testStartClientComponent() {
     // FIXME write test after meta data integration
     // start should fail
@@ -3918,7 +4224,6 @@ public class AmbariManagementControllerT
     clusters.mapHostToCluster(host1, clusterName);
     clusters.mapHostToCluster(host2, clusterName);
 
-
     // null service should work
     createServiceComponentHost(clusterName, null, componentName1,
         host1, null);

Modified: 
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java?rev=1456565&r1=1456564&r2=1456565&view=diff
==============================================================================
--- 
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
 (original)
+++ 
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
 Thu Mar 14 17:31:50 2013
@@ -28,6 +28,8 @@ import org.apache.ambari.server.controll
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
 import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.junit.Test;
@@ -101,12 +103,31 @@ public class HostComponentResourceProvid
     AmbariManagementController managementController = 
createMock(AmbariManagementController.class);
 
     Set<ServiceComponentHostResponse> allResponse = new 
HashSet<ServiceComponentHostResponse>();
+    StackId stackId = new StackId("HDP-0.1");
+    StackId stackId2 = new StackId("HDP-0.2");
     allResponse.add(new ServiceComponentHostResponse(
-        "Cluster100", "Service100", "Component100", "Host100", null, null, "", 
"", "" ));
+        "Cluster100", "Service100", "Component100", "Host100", null, null, 
State.INSTALLED.toString(),
+        stackId.getStackId(), State.STARTED.toString(),
+        stackId2.getStackId()));
     allResponse.add(new ServiceComponentHostResponse(
-        "Cluster100", "Service100", "Component101", "Host100", null, null, "", 
"", "" ));
+        "Cluster100", "Service100", "Component101", "Host100", null, null, 
State.INSTALLED.toString(),
+        stackId.getStackId(), State.STARTED.toString(),
+        stackId2.getStackId()));
     allResponse.add(new ServiceComponentHostResponse(
-        "Cluster100", "Service100", "Component102", "Host100", null, null, "", 
"", "" ));
+        "Cluster100", "Service100", "Component102", "Host100", null, null, 
State.INSTALLED.toString(),
+        stackId.getStackId(), State.STARTED.toString(),
+        stackId2.getStackId()));
+    Map<String, String> expectedNameValues = new HashMap<String, String>();
+    expectedNameValues.put(
+        HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, 
"Cluster100");
+    expectedNameValues.put(
+        HostComponentResourceProvider.HOST_COMPONENT_STATE_PROPERTY_ID, 
State.INSTALLED.toString());
+    expectedNameValues.put(
+        HostComponentResourceProvider.HOST_COMPONENT_STACK_ID_PROPERTY_ID, 
stackId.getStackId());
+    expectedNameValues.put(
+        
HostComponentResourceProvider.HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID, 
State.STARTED.toString());
+    expectedNameValues.put(
+        
HostComponentResourceProvider.HOST_COMPONENT_DESIRED_STACK_ID_PROPERTY_ID, 
stackId2.getStackId());
 
     // set expectations
     expect(managementController.getHostComponents(
@@ -126,6 +147,10 @@ public class HostComponentResourceProvid
 
     
propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID);
     
propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+    
propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_STATE_PROPERTY_ID);
+    
propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_STACK_ID_PROPERTY_ID);
+    
propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID);
+    
propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_DESIRED_STACK_ID_PROPERTY_ID);
 
     Predicate predicate = new PredicateBuilder().property(
         
HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").toPredicate();
@@ -135,14 +160,14 @@ public class HostComponentResourceProvid
     Assert.assertEquals(3, resources.size());
     Set<String> names = new HashSet<String>();
     for (Resource resource : resources) {
-      String clusterName = (String) resource.getPropertyValue(
-          
HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID);
-      Assert.assertEquals("Cluster100", clusterName);
+      for (String key : expectedNameValues.keySet()) {
+        Assert.assertEquals(expectedNameValues.get(key), 
resource.getPropertyValue(key));
+      }
       names.add((String) resource.getPropertyValue(
           
HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID));
     }
     // Make sure that all of the response objects got moved into resources
-    for (ServiceComponentHostResponse response : allResponse ) {
+    for (ServiceComponentHostResponse response : allResponse) {
       Assert.assertTrue(names.contains(response.getComponentName()));
     }
 
@@ -150,7 +175,7 @@ public class HostComponentResourceProvid
     verify(managementController);
   }
 
-  
+
   @Test
   public void testGetResources_return_ha_status_property() throws Exception {
     Resource.Type type = Resource.Type.HostComponent;
@@ -158,7 +183,7 @@ public class HostComponentResourceProvid
     Set<ServiceComponentHostResponse> allResponse = new 
HashSet<ServiceComponentHostResponse>();
      for (Role role : Role.values()) {
         allResponse.add(new ServiceComponentHostResponse(
-        "Cluster100", "Service100", role.toString(), "Host100", null, null, 
"", "", "" ));
+        "Cluster100", "Service100", role.toString(), "Host100", null, null, 
"", "", "", ""));
      }
     
 
@@ -203,9 +228,7 @@ public class HostComponentResourceProvid
     
     verify(managementController);
   }
- 
-  
-  
+
   @Test
   public void testUpdateResources() throws Exception {
     Resource.Type type = Resource.Type.HostComponent;
@@ -215,7 +238,7 @@ public class HostComponentResourceProvid
 
     Set<ServiceComponentHostResponse> nameResponse = new 
HashSet<ServiceComponentHostResponse>();
     nameResponse.add(new ServiceComponentHostResponse(
-        "Cluster102", "Service100", "Component100", "Host100", null, null, 
"STARTED", "", ""));
+        "Cluster102", "Service100", "Component100", "Host100", null, null, 
"STARTED", "", "", ""));
 
     // set expectations
     expect(managementController.getHostComponents(


Reply via email to