Преглед изворни кода

AMBARI-1287. Monitor for component/service state for gsInstaller resource provider.

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1440745 13f79535-47bb-0310-9956-ffa450edef68
Tom Beerbower пре 12 година
родитељ
комит
151a81276d
17 измењених фајлова са 576 додато и 42 уклоњено
  1. 3 1
      CHANGES.txt
  2. 234 3
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/ClusterDefinition.java
  3. 11 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerClusterProvider.java
  4. 18 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerComponentProvider.java
  5. 24 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostComponentProvider.java
  6. 20 2
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostProvider.java
  7. 9 4
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerNoOpProvider.java
  8. 50 2
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerProviderModule.java
  9. 43 3
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerResourceProvider.java
  10. 18 2
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerServiceProvider.java
  11. 35 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerStateProvider.java
  12. 5 5
      ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerClusterProviderTest.java
  13. 5 5
      ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerComponentProviderTest.java
  14. 5 5
      ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostComponentProviderTest.java
  15. 30 5
      ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostProviderTest.java
  16. 30 5
      ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerServiceProviderTest.java
  17. 36 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/TestGSInstallerStateProvider.java

+ 3 - 1
CHANGES.txt

@@ -189,9 +189,11 @@ Trunk (unreleased changes):
  AMBARI-1270. Add predicate objects for checking empty resource category.
  (tbeerbower)
 
- AMBARI - 1286. Set version number property in gsInstaller cluster resource
+ AMBARI-1286. Set version number property in gsInstaller cluster resource
  provider. (tbeerbower)
 
+ AMBARI-1287. Monitor for component/service state for gsInstaller resource provider. (tbeerbower)
+
  BUG FIXES
 
  AMBARI-1281. Heatmap does not show up if the cluster was installed by going

+ 234 - 3
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/ClusterDefinition.java

@@ -44,19 +44,51 @@ public class ClusterDefinition {
   private final Map<String, Set<String>> components = new HashMap<String, Set<String>>();
   private final Map<String, Map<String, Set<String>>> hostComponents = new HashMap<String, Map<String, Set<String>>>();
 
+  private final GSInstallerStateProvider stateProvider;
   private String clusterName;
   private String versionId;
 
+  /**
+   * Index of host names to host component state.
+   */
+  private final Map<String, Set<HostComponentState>> hostStateMap = new HashMap<String, Set<HostComponentState>>();
+
+  /**
+   * Index of service names to host component state.
+   */
+  private final Map<String, Set<HostComponentState>> serviceStateMap = new HashMap<String, Set<HostComponentState>>();
+
+  /**
+   * Index of component names to host component state.
+   */
+  private final Map<String, Set<HostComponentState>> componentStateMap = new HashMap<String, Set<HostComponentState>>();
+
+  /**
+   * Index of host component names to host component state.
+   */
+  private final Map<String, HostComponentState> hostComponentStateMap = new HashMap<String, HostComponentState>();
+
+  /**
+   * Component name mapping to account for differences in what is provided by the gsInstaller
+   * and what is expected by the Ambari providers.
+   */
+  private static final Map<String, String> componentNameMap = new HashMap<String, String>();
+
+  static {
+    componentNameMap.put("GANGLIA", "GANGLIA_SERVER");
+  }
 
   // ----- Constructors ------------------------------------------------------
 
   /**
    * Create a cluster definition.
    */
-  public ClusterDefinition() {
-    clusterName = DEFAULT_CLUSTER_NAME;
-    versionId   = DEFAULT_VERSION_ID;
+  public ClusterDefinition(GSInstallerStateProvider stateProvider) {
+    this.stateProvider = stateProvider;
+    this.clusterName   = DEFAULT_CLUSTER_NAME;
+    this.versionId     = DEFAULT_VERSION_ID;
     readClusterDefinition();
+    setHostComponentState();
   }
 
 
@@ -126,6 +158,53 @@ public class ClusterDefinition {
     return resultSet == null ? Collections.<String>emptySet() : resultSet;
   }
 
+  /**
+   * Get the host state from the given host name.
+   *
+   * @param hostName  the host name
+   *
+   * @return the host state
+   */
+  public String getHostState(String hostName) {
+    return isHealthy(hostStateMap.get(hostName)) ? "HEALTHY" : "INIT";
+  }
+
+  /**
+   * Get the service state from the given service name.
+   *
+   * @param serviceName  the service name
+   *
+   * @return the service state
+   */
+  public String getServiceState(String serviceName) {
+    return isHealthy(serviceStateMap.get(serviceName)) ? "STARTED" : "INIT";
+  }
+
+  /**
+   * Get the component state from the give service name and component name.
+   *
+   * @param serviceName    the service name
+   * @param componentName  the component name
+   *
+   * @return the component state
+   */
+  public String getComponentState(String serviceName, String componentName) {
+    return isHealthy(componentStateMap.get(getComponentKey(serviceName, componentName))) ? "STARTED" : "INIT";
+  }
+
+  /**
+   * Get the host component name from the given host name, service name and component name.
+   *
+   * @param hostName       the host name
+   * @param serviceName    the service name
+   * @param componentName  the component name
+   *
+   * @return the host component state
+   */
+  public String getHostComponentState(String hostName, String serviceName, String componentName) {
+    return isHealthy(hostComponentStateMap.get(getHostComponentKey(hostName, serviceName, componentName))) ? "STARTED" : "INIT";
+  }
+
 
   // ----- helper methods ----------------------------------------------------
 
@@ -154,6 +233,11 @@ public class ClusterDefinition {
           String componentName = parts[1];
           String hostName      = parts[2];
 
+          // translate the component name if required
+          if (componentNameMap.containsKey(componentName)) {
+            componentName = componentNameMap.get(componentName);
+          }
+
           services.add(serviceName);
           Set<String> serviceComponents = components.get(serviceName);
           if (serviceComponents == null) {
@@ -182,4 +266,151 @@ public class ClusterDefinition {
       throw new IllegalStateException(msg, e);
     }
   }
+
+  /**
+   * Set the host component state maps.
+   */
+  private void setHostComponentState() {
+    for (Map.Entry<String, Map<String, Set<String>>> serviceEntry : hostComponents.entrySet()) {
+      String serviceName = serviceEntry.getKey();
+
+      for (Map.Entry<String, Set<String>> hostEntry : serviceEntry.getValue().entrySet()) {
+        String hostName = hostEntry.getKey();
+
+        for (String componentName : hostEntry.getValue()) {
+
+          HostComponentState state = new HostComponentState(hostName, componentName);
+
+          // add state to hosts
+          addState(hostName, hostStateMap, state);
+
+          // add state to services
+          addState(serviceName, serviceStateMap, state);
+
+          // add state to components
+          addState(getComponentKey(serviceName, componentName), componentStateMap, state);
+
+          // add state to host components
+          hostComponentStateMap.put(getHostComponentKey(hostName, serviceName, componentName), state);
+        }
+      }
+    }
+  }
+
+  /**
+   * Add the given host component state object to the given map of state objects.
+   *
+   * @param hostName  the host name
+   * @param stateMap  the map of state objects
+   * @param state     the state
+   */
+  private static void addState(String hostName, Map<String, Set<HostComponentState>> stateMap, HostComponentState state) {
+    Set<HostComponentState> states = stateMap.get(hostName);
+    if (states == null) {
+      states = new HashSet<HostComponentState>();
+      stateMap.put(hostName, states);
+    }
+    states.add(state);
+  }
+
+  /**
+   * Get a key from the given service name and component name.
+   *
+   * @param serviceName    the service name
+   * @param componentName  the component name
+   *
+   * @return the key
+   */
+  private String getComponentKey(String serviceName, String componentName) {
+    return serviceName + "." + componentName;
+  }
+
+  /**
+   * Get a key from the given host name, service name and component name.
+   *
+   * @param hostName       the host name
+   * @param serviceName    the service name
+   * @param componentName  the component name
+   *
+   * @return the key
+   */
+  private String getHostComponentKey(String hostName, String serviceName, String componentName) {
+    return hostName + "." + serviceName + "." + componentName;
+  }
+
+  /**
+   * Determine whether or not the host components associated
+   * with the given states are healthy.
+   *
+   * @param states  the states
+   *
+   * @return true if the associated host components are healthy
+   */
+  private boolean isHealthy(Set<HostComponentState> states) {
+    if (states != null) {
+      for (HostComponentState state : states) {
+        if (!state.isHealthy()) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Determine whether or not the host component associated
+   * with the given state is healthy.
+   *
+   * @param state  the state
+   *
+   * @return true if the associated host component is healthy
+   */
+  private boolean isHealthy(HostComponentState state) {
+    return state == null || state.isHealthy();
+  }
+
+
+  // ----- inner classes -----------------------------------------------------
+
+  /**
+   * A state object used to check the health of a host component.
+   */
+  private class HostComponentState {
+    private final String hostName;
+    private final String componentName;
+    private boolean healthy = true;
+    private long lastAccess;
+
+    /**
+     * Expiry for the health value.
+     */
+    private static final int EXPIRY = 15000;
+
+    // ----- Constructor -----------------------------------------------------
+
+    /**
+     * Constructor.
+     *
+     * @param hostName       the host name
+     * @param componentName  the component name
+     */
+    HostComponentState(String hostName, String componentName) {
+      this.hostName      = hostName;
+      this.componentName = componentName;
+    }
+
+    /**
+     * Determine whether or not the associated host component is healthy.
+     *
+     * @return true if the associated host component is healthy
+     */
+    public boolean isHealthy() {
+      if (System.currentTimeMillis() - lastAccess > EXPIRY) {
+        // health value has expired... get it again
+        healthy = stateProvider.isHealthy(hostName, componentName);
+        this.lastAccess = System.currentTimeMillis();
+      }
+      return healthy;
+    }
+  }
 }

+ 11 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerClusterProvider.java

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.controller.gsinstaller;
 
 import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
@@ -45,6 +47,14 @@ public class GSInstallerClusterProvider extends GSInstallerResourceProvider{
   }
 
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  @Override
+  public void updateProperties(Resource resource, Request request, Predicate predicate) {
+    // Do nothing
+  }
+
+
   // ----- helper methods ----------------------------------------------------
 
   /**
@@ -55,6 +65,7 @@ public class GSInstallerClusterProvider extends GSInstallerResourceProvider{
     ClusterDefinition clusterDefinition = getClusterDefinition();
     cluster.setProperty(CLUSTER_NAME_PROPERTY_ID, clusterDefinition.getClusterName());
     cluster.setProperty(CLUSTER_VERSION_PROPERTY_ID, clusterDefinition.getVersionId());
+
     addResource(cluster);
   }
 }

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerComponentProvider.java

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.controller.gsinstaller;
 
 import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
@@ -33,6 +35,7 @@ public class GSInstallerComponentProvider extends GSInstallerResourceProvider{
   protected static final String COMPONENT_CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("ServiceComponentInfo", "cluster_name");
   protected static final String COMPONENT_SERVICE_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("ServiceComponentInfo", "service_name");
   protected static final String COMPONENT_COMPONENT_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("ServiceComponentInfo", "component_name");
+  protected static final String COMPONENT_STATE_PROPERTY_ID           = PropertyHelper.getPropertyId("ServiceComponentInfo", "state");
 
 
   // ----- Constructors ------------------------------------------------------
@@ -48,6 +51,20 @@ public class GSInstallerComponentProvider extends GSInstallerResourceProvider{
   }
 
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  @Override
+  public void updateProperties(Resource resource, Request request, Predicate predicate) {
+
+    Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+    if (propertyIds.contains(COMPONENT_STATE_PROPERTY_ID)) {
+      String serviceName   = (String) resource.getPropertyValue(COMPONENT_SERVICE_NAME_PROPERTY_ID);
+      String componentName = (String) resource.getPropertyValue(COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+      resource.setProperty(COMPONENT_STATE_PROPERTY_ID, getClusterDefinition().getComponentState(serviceName, componentName));
+    }
+  }
+
+
   // ----- helper methods ----------------------------------------------------
 
   /**
@@ -63,6 +80,7 @@ public class GSInstallerComponentProvider extends GSInstallerResourceProvider{
         component.setProperty(COMPONENT_CLUSTER_NAME_PROPERTY_ID, clusterName);
         component.setProperty(COMPONENT_SERVICE_NAME_PROPERTY_ID, serviceName);
         component.setProperty(COMPONENT_COMPONENT_NAME_PROPERTY_ID, componentName);
+
         addResource(component);
       }
     }

+ 24 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostComponentProvider.java

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.controller.gsinstaller;
 
 import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
@@ -34,6 +36,8 @@ public class GSInstallerHostComponentProvider extends GSInstallerResourceProvide
   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");
 
 
   // ----- Constructors ------------------------------------------------------
@@ -49,6 +53,25 @@ public class GSInstallerHostComponentProvider extends GSInstallerResourceProvide
   }
 
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  @Override
+  public void updateProperties(Resource resource, Request request, Predicate predicate) {
+    Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+    if (propertyIds.contains(HOST_COMPONENT_STATE_PROPERTY_ID) ||
+        propertyIds.contains(HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID)) {
+      String serviceName   = (String) resource.getPropertyValue(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID);
+      String componentName = (String) resource.getPropertyValue(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+      String hostName      = (String) resource.getPropertyValue(HOST_COMPONENT_HOST_NAME_PROPERTY_ID);
+
+      String hostComponentState = getClusterDefinition().getHostComponentState(hostName, serviceName, componentName);
+
+      resource.setProperty(HOST_COMPONENT_STATE_PROPERTY_ID, hostComponentState);
+      resource.setProperty(HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID, hostComponentState);
+    }
+  }
+
+
   // ----- helper methods ----------------------------------------------------
 
   /**
@@ -67,6 +90,7 @@ public class GSInstallerHostComponentProvider extends GSInstallerResourceProvide
           hostComponent.setProperty(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID, serviceName);
           hostComponent.setProperty(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID, componentName);
           hostComponent.setProperty(HOST_COMPONENT_HOST_NAME_PROPERTY_ID, hostName);
+
           addResource(hostComponent);
         }
       }

+ 20 - 2
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostProvider.java

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.controller.gsinstaller;
 
 import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
@@ -34,6 +36,8 @@ public class GSInstallerHostProvider extends GSInstallerResourceProvider{
       PropertyHelper.getPropertyId("Hosts", "cluster_name");
   protected static final String HOST_NAME_PROPERTY_ID =
       PropertyHelper.getPropertyId("Hosts", "host_name");
+  protected static final String HOST_STATE_PROPERTY_ID =
+      PropertyHelper.getPropertyId("Hosts", "host_state");
 
 
   // ----- Constructors ------------------------------------------------------
@@ -49,19 +53,33 @@ public class GSInstallerHostProvider extends GSInstallerResourceProvider{
   }
 
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  @Override
+  public void updateProperties(Resource resource, Request request, Predicate predicate) {
+    Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+    if (propertyIds.contains(HOST_STATE_PROPERTY_ID)) {
+      String hostName = (String) resource.getPropertyValue(HOST_NAME_PROPERTY_ID);
+      resource.setProperty(HOST_STATE_PROPERTY_ID, getClusterDefinition().getHostState(hostName));
+    }
+  }
+
+
   // ----- helper methods ----------------------------------------------------
 
   /**
    * Create the resources based on the cluster definition.
    */
   private void initHostResources() {
-    String      clusterName = getClusterDefinition().getClusterName();
-    Set<String> hosts       = getClusterDefinition().getHosts();
+    ClusterDefinition clusterDefinition = getClusterDefinition();
+    String            clusterName       = clusterDefinition.getClusterName();
+    Set<String>       hosts             = clusterDefinition.getHosts();
 
     for (String hostName : hosts) {
       Resource host = new ResourceImpl(Resource.Type.Host);
       host.setProperty(HOST_CLUSTER_NAME_PROPERTY_ID, clusterName);
       host.setProperty(HOST_NAME_PROPERTY_ID, hostName);
+
       addResource(host);
     }
   }

+ 9 - 4
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerNoOpProvider.java

@@ -17,17 +17,22 @@
  */
 package org.apache.ambari.server.controller.gsinstaller;
 
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
-
-import java.util.Map;
-import java.util.Set;
 
 /**
  * A NO-OP resource provider for a gsInstaller defined cluster.
  */
 public class GSInstallerNoOpProvider extends GSInstallerResourceProvider{
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  @Override
+  public void updateProperties(Resource resource, Request request, Predicate predicate) {
+    // Do nothing
+  }
+
   // ----- Constructors ------------------------------------------------------
 
   public GSInstallerNoOpProvider(Resource.Type type, ClusterDefinition clusterDefinition) {

+ 50 - 2
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerProviderModule.java

@@ -22,19 +22,67 @@ import org.apache.ambari.server.controller.internal.AbstractProviderModule;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * A provider module implementation that uses the GSInstaller resource provider.
  */
-public class GSInstallerProviderModule extends AbstractProviderModule {
+public class GSInstallerProviderModule extends AbstractProviderModule implements GSInstallerStateProvider{
 
   private final ClusterDefinition clusterDefinition;
 
+  private static final Map<String, String> PORTS = new HashMap<String, String>();
+
+  static {
+    PORTS.put("NAMENODE", "50070");
+    PORTS.put("DATANODE", "50075");
+    PORTS.put("JOBTRACKER", "50030");
+    PORTS.put("TASKTRACKER", "50060");
+    PORTS.put("HBASE_MASTER", "60010");
+  }
+
+  private static final int TIMEOUT = 5000;
+
+
   // ----- Constructors ------------------------------------------------------
 
   public GSInstallerProviderModule() {
-    clusterDefinition = new ClusterDefinition();
+    clusterDefinition = new ClusterDefinition(this);
+  }
+
+
+  // ----- GSInstallerStateProvider ------------------------------------------
+
+  @Override
+  public boolean isHealthy(String hostName, String componentName) {
+    String port = PORTS.get(componentName);
+    if (port != null) {
+      StringBuilder sb = new StringBuilder();
+      sb.append("http://").append(hostName);
+      sb.append(":").append(port);
+
+      try {
+        HttpURLConnection connection = (HttpURLConnection) new URL(sb.toString()).openConnection();
+
+        connection.setRequestMethod("HEAD");
+        connection.setConnectTimeout(TIMEOUT);
+        connection.setReadTimeout(TIMEOUT);
+
+        int code = connection.getResponseCode();
+
+        return code >= 200 && code <= 399;
+      } catch (IOException exception) {
+        return false;
+      }
+    }
+    return true;
   }
 
+
   // ----- utility methods ---------------------------------------------------
 
   @Override

+ 43 - 3
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerResourceProvider.java

@@ -29,12 +29,14 @@ import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+
 /**
  * An abstract resource provider for a gsInstaller defined cluster.
  */
@@ -82,7 +84,9 @@ public abstract class GSInstallerResourceProvider implements ResourceProvider {
 
     for (Resource resource : resources) {
       if (predicate == null || predicate.evaluate(resource)) {
-        resultSet.add(new ResourceImpl(resource));
+        ResourceImpl newResource = new ResourceImpl(resource);
+        updateProperties(newResource, request, predicate);
+        resultSet.add(newResource);
       }
     }
     return resultSet;
@@ -113,6 +117,18 @@ public abstract class GSInstallerResourceProvider implements ResourceProvider {
   }
 
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  /**
+   * Update the resource with any properties handled by the resource provider.
+   *
+   * @param resource   the resource to update
+   * @param request    the request
+   * @param predicate  the predicate
+   */
+  public abstract void updateProperties(Resource resource, Request request, Predicate predicate);
+
+
   // ----- accessors ---------------------------------------------------------
 
   /**
@@ -128,10 +144,34 @@ public abstract class GSInstallerResourceProvider implements ResourceProvider {
   // ----- helper methods ----------------------------------------------------
 
   /**
-   * Add a resource to the set of resources provided by this provider.
+   * Get the set of property ids required to satisfy the given request.
    *
-   * @param resource  the resource to add
+   * @param request              the request
+   * @param predicate            the predicate
+   *
+   * @return the set of property ids needed to satisfy the request
    */
+  protected Set<String> getRequestPropertyIds(Request request, Predicate predicate) {
+    Set<String> propertyIds  = request.getPropertyIds();
+
+    // if no properties are specified, then return them all
+    if (propertyIds == null || propertyIds.isEmpty()) {
+      return new HashSet<String>(this.propertyIds);
+    }
+
+    propertyIds = new HashSet<String>(propertyIds);
+
+    if (predicate != null) {
+      propertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
+    }
+    return propertyIds;
+  }
+
+  /**
+  * Add a resource to the set of resources provided by this provider.
+  *
+  * @param resource  the resource to add
+  */
   protected void addResource(Resource resource) {
     resources.add(resource);
   }

+ 18 - 2
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerServiceProvider.java

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.controller.gsinstaller;
 
 import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
@@ -30,8 +32,9 @@ import java.util.Set;
 public class GSInstallerServiceProvider extends GSInstallerResourceProvider{
 
   // Services
-  protected static final String SERVICE_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "cluster_name");
-  protected static final String SERVICE_SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "service_name");
+  protected static final String SERVICE_CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("ServiceInfo", "cluster_name");
+  protected static final String SERVICE_SERVICE_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("ServiceInfo", "service_name");
+  protected static final String SERVICE_SERVICE_STATE_PROPERTY_ID   = PropertyHelper.getPropertyId("ServiceInfo", "state");
 
 
   // ----- Constructors ------------------------------------------------------
@@ -47,6 +50,18 @@ public class GSInstallerServiceProvider extends GSInstallerResourceProvider{
   }
 
 
+  // ----- GSInstallerResourceProvider ---------------------------------------
+
+  @Override
+  public void updateProperties(Resource resource, Request request, Predicate predicate) {
+    Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+    if (propertyIds.contains(SERVICE_SERVICE_STATE_PROPERTY_ID)) {
+      String serviceName = (String) resource.getPropertyValue(SERVICE_SERVICE_NAME_PROPERTY_ID);
+      resource.setProperty(SERVICE_SERVICE_STATE_PROPERTY_ID, getClusterDefinition().getServiceState(serviceName));
+    }
+  }
+
+
   // ----- helper methods ----------------------------------------------------
 
   /**
@@ -60,6 +75,7 @@ public class GSInstallerServiceProvider extends GSInstallerResourceProvider{
       Resource service = new ResourceImpl(Resource.Type.Service);
       service.setProperty(SERVICE_CLUSTER_NAME_PROPERTY_ID, clusterName);
       service.setProperty(SERVICE_SERVICE_NAME_PROPERTY_ID, serviceName);
+
       addResource(service);
     }
   }

+ 35 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerStateProvider.java

@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.gsinstaller;
+
+/**
+ * Interface to provide component state to the gsInstaller resource provider.
+ */
+public interface GSInstallerStateProvider {
+  /**
+   * Determine whether or not the host component identified by the given host name
+   * and component name is healthy.
+   *
+   * @param hostName       the host name
+   * @param componentName  the component name
+   *
+   * @return true if the host component is healthy
+   */
+  public boolean isHealthy(String hostName, String componentName);
+}

+ 5 - 5
ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerClusterProviderTest.java

@@ -35,7 +35,7 @@ public class GSInstallerClusterProviderTest {
 
   @Test
   public void testGetResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
 
     GSInstallerResourceProvider provider = new GSInstallerClusterProvider(clusterDefinition);
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), null);
@@ -45,7 +45,7 @@ public class GSInstallerClusterProviderTest {
 
   @Test
   public void testGetResourcesWithPredicate() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
 
     GSInstallerResourceProvider provider = new GSInstallerClusterProvider(clusterDefinition);
 
@@ -63,7 +63,7 @@ public class GSInstallerClusterProviderTest {
 
   @Test
   public void testCreateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerClusterProvider(clusterDefinition);
 
     try {
@@ -76,7 +76,7 @@ public class GSInstallerClusterProviderTest {
 
   @Test
   public void testUpdateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerClusterProvider(clusterDefinition);
 
     try {
@@ -89,7 +89,7 @@ public class GSInstallerClusterProviderTest {
 
   @Test
   public void testDeleteResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerClusterProvider(clusterDefinition);
 
     try {

+ 5 - 5
ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerComponentProviderTest.java

@@ -35,7 +35,7 @@ public class GSInstallerComponentProviderTest {
 
   @Test
   public void testGetResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerComponentProvider(clusterDefinition);
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), null);
     Assert.assertEquals(25, resources.size());
@@ -43,7 +43,7 @@ public class GSInstallerComponentProviderTest {
 
   @Test
   public void testGetResourcesWithPredicate() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerComponentProvider(clusterDefinition);
     Predicate predicate = new PredicateBuilder().property(GSInstallerComponentProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals("TASKTRACKER").toPredicate();
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
@@ -61,7 +61,7 @@ public class GSInstallerComponentProviderTest {
 
   @Test
   public void testCreateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerComponentProvider(clusterDefinition);
 
     try {
@@ -74,7 +74,7 @@ public class GSInstallerComponentProviderTest {
 
   @Test
   public void testUpdateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerComponentProvider(clusterDefinition);
 
     try {
@@ -87,7 +87,7 @@ public class GSInstallerComponentProviderTest {
 
   @Test
   public void testDeleteResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerComponentProvider(clusterDefinition);
 
     try {

+ 5 - 5
ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostComponentProviderTest.java

@@ -35,7 +35,7 @@ public class GSInstallerHostComponentProviderTest {
 
   @Test
   public void testGetResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostComponentProvider(clusterDefinition);
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), null);
     Assert.assertEquals(33, resources.size());
@@ -43,7 +43,7 @@ public class GSInstallerHostComponentProviderTest {
 
   @Test
   public void testGetResourcesWithPredicate() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostComponentProvider(clusterDefinition);
     Predicate predicate = new PredicateBuilder().property(GSInstallerHostComponentProvider.HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID).equals("MAPREDUCE").toPredicate();
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
@@ -56,7 +56,7 @@ public class GSInstallerHostComponentProviderTest {
 
   @Test
   public void testCreateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostComponentProvider(clusterDefinition);
 
     try {
@@ -69,7 +69,7 @@ public class GSInstallerHostComponentProviderTest {
 
   @Test
   public void testUpdateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostComponentProvider(clusterDefinition);
 
     try {
@@ -82,7 +82,7 @@ public class GSInstallerHostComponentProviderTest {
 
   @Test
   public void testDeleteResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostComponentProvider(clusterDefinition);
 
     try {

+ 30 - 5
ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerHostProviderTest.java

@@ -35,7 +35,7 @@ public class GSInstallerHostProviderTest {
 
   @Test
   public void testGetResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostProvider(clusterDefinition);
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), null);
     Assert.assertEquals(5, resources.size());
@@ -43,7 +43,7 @@ public class GSInstallerHostProviderTest {
 
   @Test
   public void testGetResourcesWithPredicate() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostProvider(clusterDefinition);
     Predicate predicate = new PredicateBuilder().property(GSInstallerHostProvider.HOST_NAME_PROPERTY_ID).equals("ip-10-190-97-104.ec2.internal").toPredicate();
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
@@ -59,9 +59,34 @@ public class GSInstallerHostProviderTest {
     Assert.assertTrue(resources.isEmpty());
   }
 
+  @Test
+  public void testGetResourcesCheckState() throws Exception {
+    TestGSInstallerStateProvider stateProvider = new TestGSInstallerStateProvider();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(stateProvider);
+    GSInstallerResourceProvider provider = new GSInstallerHostProvider(clusterDefinition);
+    Predicate predicate = new PredicateBuilder().property(GSInstallerHostProvider.HOST_NAME_PROPERTY_ID).equals("ip-10-190-97-104.ec2.internal").toPredicate();
+    Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
+    Assert.assertEquals(1, resources.size());
+
+    Resource resource = resources.iterator().next();
+
+    Assert.assertEquals("HEALTHY", resource.getPropertyValue(GSInstallerHostProvider.HOST_STATE_PROPERTY_ID));
+
+    stateProvider.setHealthy(false);
+
+    // need to wait for old state value to expire
+    Thread.sleep(15001);
+
+    resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
+    Assert.assertEquals(1, resources.size());
+
+    resource = resources.iterator().next();
+    Assert.assertEquals("INIT", resource.getPropertyValue(GSInstallerHostProvider.HOST_STATE_PROPERTY_ID));
+  }
+
   @Test
   public void testCreateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostProvider(clusterDefinition);
 
     try {
@@ -74,7 +99,7 @@ public class GSInstallerHostProviderTest {
 
   @Test
   public void testUpdateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostProvider(clusterDefinition);
 
     try {
@@ -87,7 +112,7 @@ public class GSInstallerHostProviderTest {
 
   @Test
   public void testDeleteResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerHostProvider(clusterDefinition);
 
     try {

+ 30 - 5
ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/GSInstallerServiceProviderTest.java

@@ -35,7 +35,7 @@ public class GSInstallerServiceProviderTest {
 
   @Test
   public void testGetResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerServiceProvider(clusterDefinition);
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), null);
     Assert.assertEquals(12, resources.size());
@@ -43,7 +43,7 @@ public class GSInstallerServiceProviderTest {
 
   @Test
   public void testGetResourcesWithPredicate() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerServiceProvider(clusterDefinition);
     Predicate predicate = new PredicateBuilder().property(GSInstallerServiceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("MAPREDUCE").toPredicate();
     Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
@@ -59,9 +59,34 @@ public class GSInstallerServiceProviderTest {
     Assert.assertTrue(resources.isEmpty());
   }
 
+  @Test
+  public void testGetResourcesCheckState() throws Exception {
+    TestGSInstallerStateProvider stateProvider = new TestGSInstallerStateProvider();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(stateProvider);
+    GSInstallerResourceProvider provider = new GSInstallerServiceProvider(clusterDefinition);
+    Predicate predicate = new PredicateBuilder().property(GSInstallerServiceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("MAPREDUCE").toPredicate();
+    Set<Resource> resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
+    Assert.assertEquals(1, resources.size());
+
+    Resource resource = resources.iterator().next();
+
+    Assert.assertEquals("STARTED", resource.getPropertyValue(GSInstallerServiceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID));
+
+    stateProvider.setHealthy(false);
+
+    // need to wait for old state value to expire
+    Thread.sleep(15001);
+
+    resources = provider.getResources(PropertyHelper.getReadRequest(), predicate);
+    Assert.assertEquals(1, resources.size());
+
+    resource = resources.iterator().next();
+    Assert.assertEquals("INIT", resource.getPropertyValue(GSInstallerServiceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID));
+  }
+
   @Test
   public void testCreateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerServiceProvider(clusterDefinition);
 
     try {
@@ -74,7 +99,7 @@ public class GSInstallerServiceProviderTest {
 
   @Test
   public void testUpdateResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerServiceProvider(clusterDefinition);
 
     try {
@@ -87,7 +112,7 @@ public class GSInstallerServiceProviderTest {
 
   @Test
   public void testDeleteResources() throws Exception {
-    ClusterDefinition clusterDefinition = new ClusterDefinition();
+    ClusterDefinition clusterDefinition = new ClusterDefinition(new TestGSInstallerStateProvider());
     GSInstallerResourceProvider provider = new GSInstallerServiceProvider(clusterDefinition);
 
     try {

+ 36 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/gsinstaller/TestGSInstallerStateProvider.java

@@ -0,0 +1,36 @@
+/**
+ * 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.controller.gsinstaller;
+
+/**
+ * Test gsInstaller state provider.
+ */
+public class TestGSInstallerStateProvider implements GSInstallerStateProvider {
+
+  private boolean healthy = true;
+
+  public void setHealthy(boolean healthy) {
+    this.healthy = healthy;
+  }
+
+  @Override
+  public boolean isHealthy(String hostName, String componentName) {
+    return healthy;
+  }
+}