This is an automated email from the ASF dual-hosted git repository.

jluniya pushed a commit to branch branch-feature-AMBARI-14714
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by 
this push:
     new 7675ce8  [AMBARI-22883] A new REST API: GET 
/api/v1/hosts?format=summary or /api/v1/clusters/… (#285)
7675ce8 is described below

commit 7675ce84aeb2604c5c6c5b9480e91bda9ccc6e72
Author: sduan <sd...@hortonworks.com>
AuthorDate: Thu Feb 22 11:46:49 2018 -0800

    [AMBARI-22883] A new REST API: GET /api/v1/hosts?format=summary or 
/api/v1/clusters/… (#285)
    
    * A new REST API: GET /api/v1/hosts?format=summary or 
/api/v1/clusters/{cluster_name}/hosts?format=summary is supported with this 
implementation and return the number of hosts running each possible operating 
system. More aggregation info of hosts can be also added in this code structure.
    
    * A new REST API: GET /api/v1/hosts?format=summary or 
/api/v1/clusters/{cluster_name}/hosts?format=summary is supported with this 
implementation and return the number of hosts running each possible operating 
system. More aggregation info of hosts can be also added in this code 
structure. (Rebased)
    
    * A new REST API: GET /api/v1/hosts?format=summary or 
/api/v1/clusters/{cluster_name}/hosts?format=summary is supported with this 
implementation and return the number of hosts running each possible operating 
system. More aggregation info of hosts can be also added in this code 
structure. (Rebased)
---
 .../ambari/server/api/handlers/ReadHandler.java    |  1 +
 .../api/query/render/HostSummaryRenderer.java      | 99 ++++++++++++++++++++++
 .../resources/DetachedHostResourceDefinition.java  | 11 +++
 .../api/resources/HostResourceDefinition.java      | 10 +++
 .../ambari/server/api/services/HostService.java    |  4 +-
 .../ambari/server/controller/HostResponse.java     | 38 +++++++++
 .../controller/internal/DefaultProviderModule.java |  2 +
 .../controller/internal/HostResourceProvider.java  | 17 ++--
 8 files changed, 176 insertions(+), 6 deletions(-)

diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
index 077c1cc..0e307b2 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
@@ -121,4 +121,5 @@ public class ReadHandler implements RequestHandler {
       query.addProperty(propertyId, entry.getValue());
     }
   }
+
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/HostSummaryRenderer.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/HostSummaryRenderer.java
new file mode 100644
index 0000000..3d6b843
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/HostSummaryRenderer.java
@@ -0,0 +1,99 @@
+/*
+ * 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.api.query.render;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultImpl;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.internal.HostResourceProvider;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * HostSummaryRenderere
+ *
+ * This renderer is to summarize the properties of all hosts within a cluster 
and returns
+ * a list of proerpties summary information: i.e
+ *
+ * summary:[
+ *  {
+ *    "operating_systems" : {
+ *      "centos6" : 5,
+ *      "centos7" : 10
+ *    }
+ *  }
+ * ]
+ *
+ */
+public class HostSummaryRenderer extends DefaultRenderer {
+
+  // A list of host properties to be summarized
+  enum HostSummaryProperties {
+    OPERATINGSYSTEMS("operating_systems");
+
+    private final String property;
+    HostSummaryProperties(String property) {
+      this.property = property;
+    }
+    public String getProperty() {
+      return property;
+    }
+  }
+
+  @Override
+  public Result finalizeResult(Result queryResult) {
+    TreeNode<Resource> queryResultTree = queryResult.getResultTree();
+    // Iterate over all returned flattened hosts and build the summary info
+    List<Object> summary = new ArrayList<>();
+    // Build all summary info
+    buildFinalizedSummary(queryResultTree, summary);
+    // Create finalized result
+    return buildFinalizedResult(summary);
+  }
+
+  private void buildFinalizedSummary(TreeNode<Resource> queryResultTree, 
List<Object> summary) {
+    // Build osSummary info at this time
+    Map<String, Map<String, Integer>> osSummary = new HashMap<>();
+    summary.add(osSummary);
+    Map<String, Integer> osTypeCount = new HashMap<>();
+    osSummary.put(HostSummaryProperties.OPERATINGSYSTEMS.getProperty(), 
osTypeCount);
+    for (TreeNode<Resource> node : queryResultTree.getChildren()) {
+      Resource resource = node.getObject();
+      String osType = (String) 
resource.getPropertyValue(HostResourceProvider.HOST_OS_TYPE_PROPERTY_ID);
+      if (StringUtils.isNotBlank(osType)) {
+        osTypeCount.put(osType, osTypeCount.getOrDefault(osTypeCount, 0) + 1);
+      }
+    }
+  }
+
+  private Result buildFinalizedResult(List<Object> summary) {
+    Result result = new ResultImpl(true);
+    Resource resource = new ResourceImpl(Resource.Type.Host);
+    TreeNode<Resource> summaryTree = result.getResultTree();
+    summaryTree.addChild(resource, HostResourceProvider.SUMMARY_PROPERTY_ID);
+    resource.setProperty(HostResourceProvider.SUMMARY_PROPERTY_ID, summary);
+    return result;
+  }
+}
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/DetachedHostResourceDefinition.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/DetachedHostResourceDefinition.java
index 1cc4211..35e237c 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/DetachedHostResourceDefinition.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/DetachedHostResourceDefinition.java
@@ -19,6 +19,8 @@
 
 package org.apache.ambari.server.api.resources;
 
+import org.apache.ambari.server.api.query.render.HostSummaryRenderer;
+import org.apache.ambari.server.api.query.render.Renderer;
 import org.apache.ambari.server.controller.spi.Resource;
 
 
@@ -40,4 +42,13 @@ public class DetachedHostResourceDefinition extends 
BaseResourceDefinition {
   public String getSingularName() {
     return "host";
   }
+
+  @Override
+  public Renderer getRenderer(String name) {
+    if (name.equals("summary")) {
+      return new HostSummaryRenderer();
+    }
+    return super.getRenderer(name);
+  }
+
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
index d22b5f6..46ca04a 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
@@ -24,6 +24,8 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.ambari.server.api.query.render.HostSummaryRenderer;
+import org.apache.ambari.server.api.query.render.Renderer;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 
@@ -55,6 +57,14 @@ public class HostResourceDefinition extends 
BaseResourceDefinition {
   }
 
   @Override
+  public Renderer getRenderer(String name) {
+    if (name.equals("summary")) {
+      return new HostSummaryRenderer();
+    }
+    return super.getRenderer(name);
+  }
+
+  @Override
   public Set<SubResourceDefinition> getSubResourceDefinitions() {
     Set<SubResourceDefinition> subs = new HashSet<>();
     subs.add(new SubResourceDefinition(Resource.Type.HostComponent));
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
index 58d1d1d..aa9089e 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
@@ -28,6 +28,7 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
@@ -133,7 +134,8 @@ public class HostService extends BaseService {
     @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = 
MSG_PERMISSION_DENIED),
     @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = 
MSG_SERVER_ERROR),
   })
-  public Response getHosts(String body, @Context HttpHeaders headers, @Context 
UriInfo ui) {
+  public Response getHosts(String body, @Context HttpHeaders headers, @Context 
UriInfo ui,
+                           @ApiParam(value = "summary", required = false) 
@QueryParam("format") String format) {
     return handleRequest(headers, body, ui, Request.Type.GET,
         createHostResource(m_clusterName, null));
   }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/HostResponse.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/HostResponse.java
index 9d02a0b..2c40b05 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/HostResponse.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/HostResponse.java
@@ -146,6 +146,29 @@ public class HostResponse {
 
   private MaintenanceState maintenanceState;
 
+  /**
+   * Summary information of all hosts in a cluster or multiple clusters
+   *
+   * The response json schema is:
+   * {
+   * "Hosts" : {
+   *     "cluster_name" : "c1",
+   *     "summary" : [
+   *       {
+   *         "operating_systems" : [
+   *           {
+   *             "centos6" : 2
+   *           },
+   *           {
+   *             "centos7" : 5
+   *           }
+   *         ]
+   *       }
+   *     ]
+   * }
+   */
+  private List<Object> hostsSummary;
+
   public HostResponse(String hostname, String clusterName,
                       String ipv4, int cpuCount, int phCpuCount, String 
osArch, String osType,
                       long totalMemBytes,
@@ -422,6 +445,21 @@ public class HostResponse {
   }
 
   /**
+   * Set the hostsSummary
+   */
+  public void setHostsSummary(List<Object> hostsSummary) {
+    this.hostsSummary = hostsSummary;
+  }
+
+  /**
+   * Get the aggregation info of hosts in a cluster or in multiple clusters
+   */
+  @ApiModelProperty(name = HostResourceProvider.SUMMARY_PROPERTY_ID)
+  public List<Object> getHostsSummary() {
+    return hostsSummary;
+  }
+
+  /**
    * Set the detailed recovery report
    */
   public void setRecoveryReport(RecoveryReport recoveryReport) {
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
index 1dbe903..b7f2501 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
@@ -132,6 +132,8 @@ public class DefaultProviderModule extends 
AbstractProviderModule {
         return new ArtifactResourceProvider(managementController);
       case RemoteCluster:
         return new RemoteClusterResourceProvider();
+      case Host:
+        return new HostResourceProvider(managementController);
       default:
         LOGGER.debug("Delegating creation of resource provider for: {} to the 
AbstractControllerResourceProvider", type.getInternalType());
         return AbstractControllerResourceProvider.getResourceProvider(type, 
managementController);
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
index 7ecbfdc1..79f4233 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
@@ -116,6 +116,7 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   public static final String STATE_PROPERTY_ID = "host_state";
   public static final String TOTAL_MEM_PROPERTY_ID = "total_mem";
   public static final String ATTRIBUTES_PROPERTY_ID = "attributes";
+  public static final String SUMMARY_PROPERTY_ID = "summary";
 
   public static final String HOST_CLUSTER_NAME_PROPERTY_ID = RESPONSE_KEY + 
PropertyHelper.EXTERNAL_PATH_SEP + CLUSTER_NAME_PROPERTY_ID;
   public static final String HOST_CPU_COUNT_PROPERTY_ID = RESPONSE_KEY + 
PropertyHelper.EXTERNAL_PATH_SEP + CPU_COUNT_PROPERTY_ID;
@@ -139,7 +140,7 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   public static final String HOST_RECOVERY_SUMMARY_PROPERTY_ID = RESPONSE_KEY 
+ PropertyHelper.EXTERNAL_PATH_SEP + RECOVERY_SUMMARY_PROPERTY_ID;
   public static final String HOST_STATE_PROPERTY_ID = RESPONSE_KEY + 
PropertyHelper.EXTERNAL_PATH_SEP + STATE_PROPERTY_ID;
   public static final String HOST_TOTAL_MEM_PROPERTY_ID = RESPONSE_KEY + 
PropertyHelper.EXTERNAL_PATH_SEP + TOTAL_MEM_PROPERTY_ID;
-  public static final String HOST_ATTRIBUTES_PROPERTY_ID = 
PropertyHelper.getPropertyId(RESPONSE_KEY,ATTRIBUTES_PROPERTY_ID);
+  public static final String HOST_ATTRIBUTES_PROPERTY_ID = 
PropertyHelper.getPropertyId(RESPONSE_KEY, ATTRIBUTES_PROPERTY_ID);
 
   public static final String BLUEPRINT_PROPERTY_ID = "blueprint";
   public static final String HOST_GROUP_PROPERTY_ID = "host_group";
@@ -154,6 +155,7 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   public static Map<Resource.Type, String> keyPropertyIds = 
ImmutableMap.<Resource.Type, String>builder()
       .put(Resource.Type.Host, HOST_HOST_NAME_PROPERTY_ID)
       .put(Resource.Type.Cluster, HOST_CLUSTER_NAME_PROPERTY_ID)
+      .put(Resource.Type.HostComponent, HOST_OS_TYPE_PROPERTY_ID)
       .build();
 
   /**
@@ -195,7 +197,7 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   /**
    * Create a  new resource provider for the given management controller.
    *
-   * @param managementController  the management controller
+   * @param managementController the management controller
    */
   @AssistedInject
   HostResourceProvider(@Assisted AmbariManagementController 
managementController) {
@@ -214,9 +216,9 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   @Override
   protected RequestStatus createResourcesAuthorized(final Request request)
       throws SystemException,
-          UnsupportedPropertyException,
-          ResourceAlreadyExistsException,
-          NoSuchParentResourceException {
+      UnsupportedPropertyException,
+      ResourceAlreadyExistsException,
+      NoSuchParentResourceException {
 
     RequestStatusResponse createResponse = null;
     if (isHostGroupRequest(request)) {
@@ -238,6 +240,11 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   @Override
   protected Set<Resource> getResourcesAuthorized(Request request, Predicate 
predicate)
       throws SystemException, UnsupportedPropertyException, 
NoSuchResourceException, NoSuchParentResourceException {
+    return getHostResource(request, predicate);
+  }
+
+  private Set<Resource> getHostResource(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, 
NoSuchResourceException, NoSuchParentResourceException {
 
     final Set<HostRequest> requests = new HashSet<>();
 

-- 
To stop receiving notification emails like this one, please contact
jlun...@apache.org.

Reply via email to