浏览代码

AMBARI-4671. Support changing the cluster name of an existing hadoop cluster. (mahadev)

Mahadev Konar 10 年之前
父节点
当前提交
bc54512cf2

+ 19 - 5
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java

@@ -1144,17 +1144,23 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   private synchronized RequestStatusResponse updateCluster(ClusterRequest request)
       throws AmbariException {
 
-    if (request.getClusterName() == null
-        || request.getClusterName().isEmpty()) {
-      throw new IllegalArgumentException("Invalid arguments, cluster name"
-          + " should not be null");
+    if (request.getClusterId() == null
+        && (request.getClusterName() == null
+        || request.getClusterName().isEmpty())) {
+      throw new IllegalArgumentException("Invalid arguments, cluster id or cluster name should not be null");
     }
 
     LOG.info("Received a updateCluster request"
+        + ", clusterId=" + request.getClusterId()
         + ", clusterName=" + request.getClusterName()
         + ", request=" + request);
 
-    final Cluster cluster = clusters.getCluster(request.getClusterName());
+    final Cluster cluster;
+    if (request.getClusterId() == null) {
+      cluster = clusters.getCluster(request.getClusterName());
+    } else {
+      cluster = clusters.getClusterById(request.getClusterId());
+    }
     //save data to return configurations created
     List<ConfigurationResponse> configurationResponses =
       new LinkedList<ConfigurationResponse>();
@@ -1166,6 +1172,14 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       throw new IllegalArgumentException(msg);
     }
 
+    // set the new name of the cluster if change is requested
+    if (!cluster.getClusterName().equals(request.getClusterName())) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Received cluster name change request from " + cluster.getClusterName() + " to " + request.getClusterName());
+      }
+      cluster.setClusterName(request.getClusterName());
+    }
+
     // set or create configuration mapping (and optionally create the map of properties)
     if (null != request.getDesiredConfig()) {
       Set<Config> configs = new HashSet<Config>();

+ 86 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java

@@ -26,6 +26,7 @@ import static org.easymock.EasyMock.createStrictMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
+import static org.easymock.EasyMock.expectLastCall;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
@@ -65,6 +66,7 @@ import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.ServiceInfo;
+import javax.persistence.RollbackException;
 import org.easymock.Capture;
 import org.junit.Test;
 
@@ -281,6 +283,90 @@ public class AmbariManagementControllerImplTest {
     verify(injector, clusters, cluster, cluster2, response, response2);
   }
 
+  /**
+   * Ensure that when the cluster id is provided and the given cluster name is different from the cluster's name
+   * then the cluster rename logic is executed.
+   */
+  @Test
+  public void testUpdateClusters() throws Exception {
+    // member state mocks
+    Capture<AmbariManagementController> controllerCapture = new Capture<AmbariManagementController>();
+    Injector injector = createStrictMock(Injector.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    ActionManager actionManager = createNiceMock(ActionManager.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    ClusterRequest clusterRequest = createNiceMock(ClusterRequest.class);
+
+    // requests
+    Set<ClusterRequest> setRequests = Collections.singleton(clusterRequest);
+
+    // expectations
+    injector.injectMembers(capture(controllerCapture));
+    expect(injector.getInstance(Gson.class)).andReturn(null);
+    expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null);
+    expect(clusterRequest.getClusterName()).andReturn("clusterNew").times(4);
+    expect(clusterRequest.getClusterId()).andReturn(1L).times(4);
+    expect(clusters.getClusterById(1L)).andReturn(cluster);
+    expect(cluster.getClusterName()).andReturn("clusterOld").times(2);
+    cluster.setClusterName("clusterNew");
+    expectLastCall();
+
+    // replay mocks
+    replay(actionManager, cluster, clusters, injector, clusterRequest);
+
+    // test
+    AmbariManagementController controller = new AmbariManagementControllerImpl(actionManager, clusters, injector);
+    controller.updateClusters(setRequests, null);
+
+    // assert and verify
+    assertSame(controller, controllerCapture.getValue());
+    verify(actionManager, cluster, clusters, injector, clusterRequest);
+  }
+
+  /**
+   * Ensure that RollbackException is thrown outside the updateClusters method
+   * when a unique constraint violation occurs.
+   */
+  @Test
+  public void testUpdateClusters__RollbackException() throws Exception {
+    // member state mocks
+    Capture<AmbariManagementController> controllerCapture = new Capture<AmbariManagementController>();
+    Injector injector = createStrictMock(Injector.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    ActionManager actionManager = createNiceMock(ActionManager.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    ClusterRequest clusterRequest = createNiceMock(ClusterRequest.class);
+
+    // requests
+    Set<ClusterRequest> setRequests = Collections.singleton(clusterRequest);
+
+    // expectations
+    injector.injectMembers(capture(controllerCapture));
+    expect(injector.getInstance(Gson.class)).andReturn(null);
+    expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null);
+    expect(clusterRequest.getClusterName()).andReturn("clusterNew").times(4);
+    expect(clusterRequest.getClusterId()).andReturn(1L).times(4);
+    expect(clusters.getClusterById(1L)).andReturn(cluster);
+    expect(cluster.getClusterName()).andReturn("clusterOld").times(2);
+    cluster.setClusterName("clusterNew");
+    expectLastCall().andThrow(new RollbackException());
+
+    // replay mocks
+    replay(actionManager, cluster, clusters, injector, clusterRequest);
+
+    // test
+    AmbariManagementController controller = new AmbariManagementControllerImpl(actionManager, clusters, injector);
+    try {
+      controller.updateClusters(setRequests, null);
+      fail("Expected RollbackException");
+    } catch (RollbackException e) {
+      //expected
+    }
+    // assert and verify
+    assertSame(controller, controllerCapture.getValue());
+    verify(actionManager, cluster, clusters, injector, clusterRequest);
+  }
+
   @Test
   public void testGetHostComponents() throws Exception {
     // member state mocks