You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2014/11/18 13:15:52 UTC

ambari git commit: AMBARI-8351. Restart ganglia starts off claiming aborted - completes anyway (dlysnichenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 4955e5a19 -> 70c640772


AMBARI-8351. Restart ganglia starts off claiming aborted - completes anyway (dlysnichenko)


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

Branch: refs/heads/trunk
Commit: 70c640772dfaf55fed45027be9fc953b09028953
Parents: 4955e5a
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Tue Nov 18 14:15:06 2014 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Tue Nov 18 14:15:06 2014 +0200

----------------------------------------------------------------------
 .../AmbariCustomCommandExecutionHelper.java     | 105 ++++++++++++--
 .../AmbariCustomCommandExecutionHelperTest.java | 144 ++++++++++++++++++-
 2 files changed, 234 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/70c64077/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index 0762d52..4103621 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -48,17 +48,12 @@ import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.internal.RequestOperationLevel;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
+import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.CommandScriptDefinition;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.CustomCommandDefinition;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.HostComponentAdminState;
-import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.PropertyInfo.PropertyType;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.Service;
@@ -68,6 +63,15 @@ import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.CommandScriptDefinition;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.CustomCommandDefinition;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.HostComponentAdminState;
+import org.apache.ambari.server.state.MaintenanceState;
+
 import org.apache.ambari.server.state.stack.OsFamily;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent;
 import org.apache.ambari.server.utils.StageUtils;
@@ -232,11 +236,20 @@ public class AmbariCustomCommandExecutionHelper {
               }
             }
     );
-    if (! ignoredHosts.isEmpty()) {
+
+    // Filter unhealthy hosts
+    Set<String> filteredHosts = filterUnhealthHosts(candidateHosts, actionExecutionContext, resourceFilter);
+
+    if (!ignoredHosts.isEmpty()) {
       String message = String.format("Some hosts (%s) have been ignored " +
                       "because components on them are in Maintenance state.",
               ignoredHosts);
       LOG.debug(message);
+    } else if (!filteredHosts.isEmpty()) {
+      String message = String.format("Some hosts (%s) have been ignored " +
+            "because they are in unknown state",
+         filteredHosts);
+      LOG.warn(message);
     } else if (candidateHosts.isEmpty()) {
       String message = "Invalid request : No hosts specified.";
       throw new AmbariException(message);
@@ -245,9 +258,9 @@ public class AmbariCustomCommandExecutionHelper {
     StackId stackId = cluster.getDesiredStackVersion();
     AmbariMetaInfo ambariMetaInfo = managementController.getAmbariMetaInfo();
     ServiceInfo serviceInfo = ambariMetaInfo.getService(
-        stackId.getStackName(), stackId.getStackVersion(), serviceName);
+       stackId.getStackName(), stackId.getStackVersion(), serviceName);
     StackInfo stackInfo = ambariMetaInfo.getStack
-        (stackId.getStackName(), stackId.getStackVersion());
+       (stackId.getStackName(), stackId.getStackVersion());
 
     CustomCommandDefinition customCommandDefinition = null;
     ComponentInfo ci = serviceInfo.getComponentByName(componentName);
@@ -877,4 +890,74 @@ public class AmbariCustomCommandExecutionHelper {
 
     return repoInfo;
   }
+
+  private ServiceComponent getServiceComponent ( ActionExecutionContext actionExecutionContext,
+                                                RequestResourceFilter resourceFilter){
+    try {
+      Cluster cluster = clusters.getCluster(actionExecutionContext.getClusterName());
+      Service service = cluster.getService(resourceFilter.getServiceName());
+
+      return service.getServiceComponent(resourceFilter.getComponentName());
+    } catch (Exception e) {
+      LOG.debug(String.format( "Unknown error appears during getting service component: %s", e.getMessage()));
+    }
+    return null;
+  }
+
+  /**
+   * Filter host according to status of host/host components
+   * @param hostname Host name to check
+   * @param actionExecutionContext Received request to execute a command
+   * @param resourceFilter Resource filter
+   * @return True if host need to be filtered, False if Not
+   * @throws AmbariException
+   */
+  private boolean filterUnhealthHostItem(String hostname,
+                                         ActionExecutionContext actionExecutionContext,
+                                         RequestResourceFilter resourceFilter) throws AmbariException {
+
+    RequestOperationLevel operationLevel = actionExecutionContext.getOperationLevel();
+    ServiceComponent serviceComponent = getServiceComponent(actionExecutionContext, resourceFilter);
+    if (serviceComponent != null && operationLevel != null
+                                && operationLevel.getLevel() == Resource.Type.Service // compare operation is allowed only for Service operation level
+                                && actionExecutionContext.getResourceFilters().size() > 1  // Check if operation was started in a chain
+                                && !serviceComponent.isMasterComponent()
+       ){
+
+      return !(clusters.getHost(hostname).getState() == HostState.HEALTHY);
+    } else if (serviceComponent != null && operationLevel != null
+                                        && operationLevel.getLevel() == Resource.Type.Host  // compare operation is allowed only for host component operation level
+                                        && actionExecutionContext.getResourceFilters().size() > 1  // Check if operation was started in a chain
+                                        && serviceComponent.getServiceComponentHosts().containsKey(hostname)  // Check if host is assigned to host component
+                                        && !serviceComponent.isMasterComponent()
+       ){
+
+      State hostState = serviceComponent.getServiceComponentHosts().get(hostname).getState();
+
+      return hostState == State.UNKNOWN;
+    }
+    return false;
+  }
+
+
+  /**
+   * Filter hosts according to status of host/host components
+   * @param hosts Host name set to filter
+   * @param actionExecutionContext Received request to execute a command
+   * @param resourceFilter Resource filter
+   * @return Set of excluded hosts
+   * @throws AmbariException
+   */
+  private Set<String> filterUnhealthHosts(Set<String> hosts,
+                                          ActionExecutionContext actionExecutionContext,
+                                          RequestResourceFilter resourceFilter) throws AmbariException {
+    Set<String> removedHosts = new HashSet<String>();
+    for (String hostname : hosts) {
+      if (filterUnhealthHostItem(hostname, actionExecutionContext, resourceFilter)){
+        removedHosts.add(hostname);
+      }
+    }
+    hosts.removeAll(removedHosts);
+    return removedHosts;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/70c64077/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
index 898efbf..5e933d2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.controller;
 
 import static org.mockito.Matchers.any;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -35,8 +36,10 @@ import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.internal.ComponentResourceProviderTest;
+import org.apache.ambari.server.controller.internal.RequestOperationLevel;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 import org.apache.ambari.server.controller.internal.ServiceResourceProviderTest;
+import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.state.Clusters;
@@ -143,7 +146,133 @@ public class AmbariCustomCommandExecutionHelperTest {
     }
   }
 
-  
+  @Test
+  public void testHostsFilterHealthy(){
+    try {
+      createClusterFixture();
+
+      Map<String, String> requestProperties = new HashMap<String, String>() {
+        {
+          put("context" , "Restart all components for GANGLIA");
+          put("operation_level/level", "SERVICE");
+          put("operation_level/service_name", "GANGLIA");
+          put("operation_level/cluster_name", "c1");
+        }
+      };
+
+      ExecuteActionRequest actionRequest = new ExecuteActionRequest(
+         "c1", "RESTART", null,
+         Arrays.asList(
+            new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER", Collections.singletonList("c6401")),
+            new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6401")),
+            new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6402"))
+         ),
+         new RequestOperationLevel(Resource.Type.Service, "c1", "GANGLIA", null, null),
+         new HashMap<String, String>(){{}},
+         false);
+
+      controller.createAction(actionRequest, requestProperties);
+
+      //clusters.getHost("c6402").setState(HostState.HEARTBEAT_LOST);
+
+      Mockito.verify(am, Mockito.times(1)).sendActions(stagesCaptor.capture(), any(ExecuteActionRequest.class));
+
+      List<Stage> stages = stagesCaptor.getValue();
+      Assert.assertEquals(1, stages.size());
+
+      Stage stage = stages.get(0);
+       // Check if was generated command, one for each host
+      Assert.assertEquals(2, stage.getHostRoleCommands().size());
+    }catch (Exception e) {
+      Assert.fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void testHostsFilterUnhealthyHost(){
+    try {
+      createClusterFixture();
+
+      // Set custom status to host
+      clusters.getHost("c6402").setState(HostState.HEARTBEAT_LOST);
+      Map<String, String> requestProperties = new HashMap<String, String>() {
+        {
+          put("context" , "Restart all components for GANGLIA");
+          put("operation_level/level", "SERVICE");
+          put("operation_level/service_name", "GANGLIA");
+          put("operation_level/cluster_name", "c1");
+        }
+      };
+
+      ExecuteActionRequest actionRequest = new ExecuteActionRequest(
+         "c1", "RESTART", null,
+         Arrays.asList(
+            new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER", Collections.singletonList("c6401")),
+            new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6401")),
+            new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6402"))
+         ),
+         new RequestOperationLevel(Resource.Type.Service, "c1", "GANGLIA", null, null),
+         new HashMap<String, String>(){{}},
+         false);
+
+      controller.createAction(actionRequest, requestProperties);
+
+      Mockito.verify(am, Mockito.times(1)).sendActions(stagesCaptor.capture(), any(ExecuteActionRequest.class));
+
+      List<Stage> stages = stagesCaptor.getValue();
+      Assert.assertEquals(1, stages.size());
+
+      Stage stage = stages.get(0);
+      // Check if was generated command for one health host
+      Assert.assertEquals(1, stage.getHostRoleCommands().size());
+    }catch (Exception e) {
+      Assert.fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void testHostsFilterUnhealthyComponent(){
+    try {
+      createClusterFixture();
+
+      // Set custom status to host
+      clusters.getCluster("c1").getService("GANGLIA").getServiceComponent("GANGLIA_MONITOR").getServiceComponentHost("c6402")
+         .setState(State.UNKNOWN);
+      Map<String, String> requestProperties = new HashMap<String, String>() {
+        {
+          put("context" , "Restart all components for GANGLIA");
+          put("operation_level/level", "SERVICE");
+          put("operation_level/service_name", "GANGLIA");
+          put("operation_level/cluster_name", "c1");
+        }
+      };
+
+      ExecuteActionRequest actionRequest = new ExecuteActionRequest(
+         "c1", "RESTART", null,
+         Arrays.asList(
+            new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER", Collections.singletonList("c6401")),
+            new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6401")),
+            new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6402"))
+         ),
+         new RequestOperationLevel(Resource.Type.Host, "c1", "GANGLIA", null, null),
+         new HashMap<String, String>(){{}},
+         false);
+
+      controller.createAction(actionRequest, requestProperties);
+
+      Mockito.verify(am, Mockito.times(1)).sendActions(stagesCaptor.capture(), any(ExecuteActionRequest.class));
+
+      List<Stage> stages = stagesCaptor.getValue();
+      Assert.assertEquals(1, stages.size());
+
+      Stage stage = stages.get(0);
+      // Check if was generated command for one health host
+      Assert.assertEquals(1, stage.getHostRoleCommands().size());
+    }catch (Exception e) {
+      Assert.fail(e.getMessage());
+    }
+  }
+
   private void createClusterFixture() throws AmbariException {
     createCluster("c1");
     addHost("c6401","c1");
@@ -151,14 +280,21 @@ public class AmbariCustomCommandExecutionHelperTest {
     
     clusters.getCluster("c1");
     createService("c1", "YARN", null);
-    
-    createServiceComponent("c1","YARN","RESOURCEMANAGER", State.INIT);
-    createServiceComponent("c1","YARN","NODEMANAGER", State.INIT);
+    createService("c1", "GANGLIA", null);
+
+    createServiceComponent("c1", "YARN","RESOURCEMANAGER", State.INIT);
+    createServiceComponent("c1", "YARN", "NODEMANAGER", State.INIT);
+    createServiceComponent("c1", "GANGLIA", "GANGLIA_SERVER", State.INIT);
+    createServiceComponent("c1", "GANGLIA", "GANGLIA_MONITOR", State.INIT);
     
     createServiceComponentHost("c1","YARN","RESOURCEMANAGER","c6401", null);
     createServiceComponentHost("c1","YARN","NODEMANAGER","c6401", null);
+    createServiceComponentHost("c1","GANGLIA","GANGLIA_SERVER","c6401", State.INIT);
+    createServiceComponentHost("c1","GANGLIA","GANGLIA_MONITOR","c6401", State.INIT);
     
     createServiceComponentHost("c1","YARN","NODEMANAGER","c6402", null);
+    createServiceComponentHost("c1","GANGLIA","GANGLIA_MONITOR","c6402", State.INIT);
+
   }
   private void addHost(String hostname, String clusterName) throws AmbariException {
     clusters.addHost(hostname);