knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From smol...@apache.org
Subject [knox] branch master updated: KNOX-2343 - Enhanced API services' display on the Knox Home page (#355)
Date Wed, 01 Jul 2020 15:06:10 GMT
This is an automated email from the ASF dual-hosted git repository.

smolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new b804e2b  KNOX-2343 - Enhanced API services' display on the Knox Home page (#355)
b804e2b is described below

commit b804e2b01418c544eeb5d432de0df9a339d9f92d
Author: Sandor Molnar <smolnar@apache.org>
AuthorDate: Wed Jul 1 17:04:11 2020 +0200

    KNOX-2343 - Enhanced API services' display on the Knox Home page (#355)
---
 .../knox/gateway/service/definition/Metadata.java  | 14 ++++
 .../definition/{Metadata.java => Sample.java}      | 71 ++++++----------
 .../resources/services/ambari/2.2.0/service.xml    | 26 ++++++
 .../resources/services/atlas-api/2.0.0/service.xml | 21 +++++
 .../resources/services/cm-api/1.0.0/service.xml    | 16 ++++
 .../services/druid-broker/0.0.1/service.xml        | 21 +++++
 .../services/druid-coordinator/0.0.1/service.xml   | 22 +++++
 .../services/druid-overlord/0.0.1/service.xml      | 16 ++++
 .../services/druid-router/0.0.1/service.xml        | 21 +++++
 .../resources/services/hbase/0.98.0/service.xml    | 26 ++++++
 .../resources/services/oozie/4.0.0/service.xml     | 16 ++++
 .../resources/services/ranger/1.0.0/service.xml    | 16 ++++
 .../resources/services/storm/0.9.3/service.xml     | 16 ++++
 .../resources/services/webhcat/0.13.0/service.xml  | 16 ++++
 .../resources/services/webhdfs/2.4.0/service.xml   | 21 +++++
 .../resources/services/yarn-rm/2.5.0/service.xml   | 16 ++++
 .../services/zeppelinws/0.8.1/service.xml          | 21 +++++
 .../gateway/service/metadata/ServiceModel.java     | 55 ++++++++++--
 knox-homepage-ui/home/app/app.module.ts            |  6 +-
 .../home/app/topologies/{service.ts => sample.ts}  |  9 +-
 knox-homepage-ui/home/app/topologies/service.ts    |  2 +
 .../topologies/topology.information.component.html | 98 +++++++++++++++-------
 .../topologies/topology.information.component.ts   | 12 ++-
 knox-homepage-ui/package-lock.json                 | 16 ++--
 knox-homepage-ui/package.json                      |  2 +-
 25 files changed, 471 insertions(+), 105 deletions(-)

diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java
index 960971d..ed9d7e3 100644
--- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java
+++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java
@@ -17,7 +17,10 @@
  */
 package org.apache.knox.gateway.service.definition;
 
+import java.util.List;
+
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.commons.lang3.builder.EqualsBuilder;
@@ -32,6 +35,7 @@ public class Metadata {
   private String context;
   private String shortDesc;
   private String description;
+  private List<Sample> samples;
 
   @XmlElement(name = "type")
   public String getType() {
@@ -69,6 +73,16 @@ public class Metadata {
     this.description = description;
   }
 
+  @XmlElement(name = "sample")
+  @XmlElementWrapper(name = "samples")
+  public List<Sample> getSamples() {
+    return samples;
+  }
+
+  public void setSamples(List<Sample> samples) {
+    this.samples = samples;
+  }
+
   @Override
   public boolean equals(Object obj) {
     return EqualsBuilder.reflectionEquals(obj, this);
diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java
similarity index 51%
copy from gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java
copy to gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java
index 960971d..b69bce3 100644
--- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java
+++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java
@@ -20,68 +20,47 @@ package org.apache.knox.gateway.service.definition;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-@XmlType(name = "metadata")
-public class Metadata {
-
-  private String type;
-  private String context;
-  private String shortDesc;
+@XmlType(name = "sample")
+public class Sample {
   private String description;
+  private String method;
+  private String path;
+  private String value;
 
-  @XmlElement(name = "type")
-  public String getType() {
-    return type;
-  }
-
-  public void setType(String type) {
-    this.type = type;
-  }
-
-  @XmlElement(name = "context")
-  public String getContext() {
-    return context;
-  }
-
-  public void setContext(String context) {
-    this.context = context;
+  @XmlElement(name = "description")
+  public String getDescription() {
+    return description;
   }
 
-  @XmlElement(name = "shortDesc")
-  public String getShortDesc() {
-    return shortDesc;
+  public void setDescription(String description) {
+    this.description = description;
   }
 
-  public void setShortDesc(String shortDesc) {
-    this.shortDesc = shortDesc;
+  @XmlElement(name = "method")
+  public String getMethod() {
+    return method;
   }
 
-  @XmlElement(name = "description")
-  public String getDescription() {
-    return description;
+  public void setMethod(String method) {
+    this.method = method;
   }
 
-  public void setDescription(String description) {
-    this.description = description;
+  @XmlElement(name = "path")
+  public String getPath() {
+    return path;
   }
 
-  @Override
-  public boolean equals(Object obj) {
-    return EqualsBuilder.reflectionEquals(obj, this);
+  public void setPath(String path) {
+    this.path = path;
   }
 
-  @Override
-  public int hashCode() {
-    return HashCodeBuilder.reflectionHashCode(this);
+  @XmlElement(name = "value")
+  public String getValue() {
+    return value;
   }
 
-  @Override
-  public String toString() {
-    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+  public void setValue(String value) {
+    this.value = value;
   }
 
 }
diff --git a/gateway-service-definitions/src/main/resources/services/ambari/2.2.0/service.xml b/gateway-service-definitions/src/main/resources/services/ambari/2.2.0/service.xml
index 05da7ac..6e18736 100644
--- a/gateway-service-definitions/src/main/resources/services/ambari/2.2.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/ambari/2.2.0/service.xml
@@ -20,6 +20,32 @@
         <context>/ambari/api</context>
         <shortDesc>Apache Ambari API</shortDesc>
         <description>The Ambari API facilitates the management and monitoring of the resources of an Apache Hadoop cluster.</description>
+        <samples>
+            <sample>
+                <description>Fetch all Ambari-managed clusters</description>
+                <method>GET</method>
+                <path>v1/clusters</path>
+            </sample>
+            <sample>
+                <description>Get the DATANODE component resource for the HDFS service of the cluster named 'c1'</description>
+                <method>GET</method>
+                <path>v1/clusters/c1/services/HDFS/components/DATANODE</path>
+            </sample>
+            <sample>
+                <description>Create the HDFS service.</description>
+                <method>POST</method>
+                <path>v1/clusters/c1/services/HDFS</path>
+            </sample>
+            <sample>
+                <description>Delete the cluster named 'c1'</description>
+                <method>DELETE</method>
+                <path>v1/clusters/c1</path>
+            </sample>
+            <sample>
+                <description>See the Apache Ambari's REST API documentation here</description>
+                <value>https://github.com/apache/ambari/blob/trunk/ambari-server/docs/api/v1/index.md</value>
+            </sample>
+        </samples>
     </metadata>
     <policies>
         <policy role="webappsec"/>
diff --git a/gateway-service-definitions/src/main/resources/services/atlas-api/2.0.0/service.xml b/gateway-service-definitions/src/main/resources/services/atlas-api/2.0.0/service.xml
index 5ba13d0..e8ec387 100644
--- a/gateway-service-definitions/src/main/resources/services/atlas-api/2.0.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/atlas-api/2.0.0/service.xml
@@ -20,6 +20,27 @@
         <context>/atlas/api</context>
         <shortDesc>Atlas API</shortDesc>
         <description>Atlas exposes a variety of REST endpoints to work with types, entities, lineage and data discovery.</description>
+        <samples>
+            <sample>
+                <description>Retrieve data for the specified attribute search query</description>
+                <method>GET</method>
+                <path>v2/search/attribute</path>
+            </sample>
+            <sample>
+                <description>Attribute based search for entities satisfying the search parameters</description>
+                <method>POST</method>
+                <path>v2/search/basic</path>
+            </sample>
+            <sample>
+                <description>Bulk API to delete list of entities identified by its GUIDs</description>
+                <method>DELETE</method>
+                <path>v2/entity/bulk</path>
+            </sample>
+            <sample>
+                <description>You can check out Apache Atlas's REST API documentation (including a Swagger UI representation) here</description>
+                <value>https://atlas.apache.org/api/v2/</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/atlas/api/**"/>
diff --git a/gateway-service-definitions/src/main/resources/services/cm-api/1.0.0/service.xml b/gateway-service-definitions/src/main/resources/services/cm-api/1.0.0/service.xml
index cbbad9e..bf77630 100644
--- a/gateway-service-definitions/src/main/resources/services/cm-api/1.0.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/cm-api/1.0.0/service.xml
@@ -26,6 +26,22 @@
         <context>/cm-api</context>
         <shortDesc>Cloudera Manager REST API</shortDesc>
         <description>Cloudera Manager's REST API lets you work with existing tools, and programmatically manage your Hadoop clusters. The API is available in both Cloudera Express and Cloudera Enterprise, and comes with open-source client libraries.</description>
+        <samples>
+            <sample>
+                <description>Fetch all CM-managed clusters</description>
+                <method>GET</method>
+                <path>clusters</path>
+            </sample>
+            <sample>
+                <description>Fetches HDFS service details from cluster named 'c1'</description>
+                <method>GET</method>
+                <path>clusters/c1/services/HDFS</path>
+            </sample>
+            <sample>
+                <description>You can checkout CM's API (v41) document here</description>
+                <value>https://cloudera.github.io/cm_api//</value>
+            </sample>
+        </samples>
     </metadata>
   <routes>
     <route path="/cm-api/**">
diff --git a/gateway-service-definitions/src/main/resources/services/druid-broker/0.0.1/service.xml b/gateway-service-definitions/src/main/resources/services/druid-broker/0.0.1/service.xml
index ab089c0..34ccd60 100644
--- a/gateway-service-definitions/src/main/resources/services/druid-broker/0.0.1/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/druid-broker/0.0.1/service.xml
@@ -22,6 +22,27 @@
         <description>The Broker is the process to route queries to if you want to run a distributed cluster. 
             It understands the metadata published to ZooKeeper about what segments exist on what processes and routes queries such that they hit the right processes. 
             This process also merges the result sets from all of the individual processes together. On start up, Historical processes announce themselves and the segments they are serving in Zookeeper.</description>
+        <samples>
+            <sample>
+                <description>Fetch a list of queryable datasources</description>
+                <method>GET</method>
+                <path>druid/v2/datasources</path>
+            </sample>
+            <sample>
+                <description>Fetch the dimensions and metrics of the datasource</description>
+                <method>GET</method>
+                <path>druid/v2/datasources/{dataSourceName}</path>
+            </sample>
+            <sample>
+                <description>Fetch the metrics of the datasource</description>
+                <method>GET</method>
+                <path>druid/v2/datasources/{dataSourceName}/metrics</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Druid Broker's REST API documentation here</description>
+                <value>https://druid.apache.org/docs/latest/operations/api-reference.html#broker</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
     <route path="druid-broker/druid/broker/v1/{**}?{**}">
diff --git a/gateway-service-definitions/src/main/resources/services/druid-coordinator/0.0.1/service.xml b/gateway-service-definitions/src/main/resources/services/druid-coordinator/0.0.1/service.xml
index 244e50f..33fcdfa 100644
--- a/gateway-service-definitions/src/main/resources/services/druid-coordinator/0.0.1/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/druid-coordinator/0.0.1/service.xml
@@ -22,6 +22,28 @@
         <description>The Druid Coordinator process is primarily responsible for segment management and distribution. 
             More specifically, the Druid Coordinator process communicates to Historical processes to load or drop segments based on configurations. 
             The Druid Coordinator is responsible for loading new segments, dropping outdated segments, managing segment replication, and balancing segment load.</description>
+        <samples>
+            <sample>
+                <description>Fetch the current leader coordinator of the cluster</description>
+                <method>GET</method>
+                <path>druid/coordinator/v1/leader</path>
+            </sample>
+             <sample>
+                <description>Fetch the percentage of segments actually loaded in the cluster versus segments that should be loaded in the cluster</description>
+                <method>GET</method>
+                <path>druid/coordinator/v1/loadstatus</path>
+            </sample>
+            <sample>
+                <description>Marks as unused all segments belonging to a data source. Returns a JSON object of the form {"numChangedSegments": &lt;number&gt;} 
+                    with the number of segments in the database whose state has been changed (that is, the segments were marked as unused) as the result of this API call</description>
+                <method>DELETE</method>
+                <path>druid/coordinator/v1/datasources/{dataSourceName}</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Druid Coordinator's REST API documentation here</description>
+                <value>https://druid.apache.org/docs/latest/operations/api-reference.html#coordinator</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
     <route path="druid-coordinator/status">
diff --git a/gateway-service-definitions/src/main/resources/services/druid-overlord/0.0.1/service.xml b/gateway-service-definitions/src/main/resources/services/druid-overlord/0.0.1/service.xml
index 4968bc2..0dc6827 100644
--- a/gateway-service-definitions/src/main/resources/services/druid-overlord/0.0.1/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/druid-overlord/0.0.1/service.xml
@@ -21,6 +21,22 @@
         <shortDesc>Druid Overlord API</shortDesc>
         <description>The Overlord process is responsible for accepting tasks, coordinating task distribution, creating locks around tasks, and returning statuses to callers. 
             Overlord can be configured to run in one of two modes - local or remote (local being default).</description>
+        <samples>
+            <sample>
+                <description>Fetch the current leader Overlord of the cluster. If you have multiple Overlords, just one is leading at any given time. The others are on standby</description>
+                <method>GET</method>
+                <path>druid/indexer/v1/leader</path>
+            </sample>
+             <sample>
+                <description>Fetch a list of ALL tasks</description>
+                <method>GET</method>
+                <path>druid/indexer/v1/tasks</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Druid Overlord's REST API documentation here</description>
+                <value>https://druid.apache.org/docs/latest/operations/api-reference.html#overlord</value>
+            </sample>
+        </samples>
     </metadata>
   <routes>
     <route path="druid-overlord/druid/indexer/v1/{**}?{**}">
diff --git a/gateway-service-definitions/src/main/resources/services/druid-router/0.0.1/service.xml b/gateway-service-definitions/src/main/resources/services/druid-router/0.0.1/service.xml
index 3245132..cf716cc 100644
--- a/gateway-service-definitions/src/main/resources/services/druid-router/0.0.1/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/druid-router/0.0.1/service.xml
@@ -20,6 +20,27 @@
         <context>/druid-router</context>
         <shortDesc>Druid Router API</shortDesc>
         <description>The Apache Druid Router process can be used to route queries to different Broker processes. By default, the broker routes queries based on how Rules are set up</description>
+        <samples>
+            <sample>
+                <description>Fetch a list of queryable datasources</description>
+                <method>GET</method>
+                <path>druid/v2/datasources</path>
+            </sample>
+             <sample>
+                <description>Fetch the dimensions and metrics of the datasource</description>
+                <method>GET</method>
+                <path>druid/v2/datasources/{dataSourceName}</path>
+            </sample>
+            <sample>
+                <description>Fetch the metrics of the datasource</description>
+                <method>GET</method>
+                <path>druid/v2/datasources/{dataSourceName}/metrics</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Druid Router's REST API documentation here</description>
+                <value>https://druid.apache.org/docs/latest/operations/api-reference.html#router</value>
+            </sample>
+        </samples>
     </metadata>
   <policies>
     <policy role="webappsec"/>
diff --git a/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml b/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
index 8d3d611..ece3501 100644
--- a/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
@@ -20,6 +20,32 @@
         <context>/hbase</context>
         <shortDesc>Web HBase</shortDesc>
         <description>The HBase REST server exposes endpoints that provide CRUD (create, read, update, delete) operations for each HBase process, as well as tables, regions, and namespaces.</description>
+        <samples>
+            <sample>
+                <description>List all namespaces</description>
+                <method>GET</method>
+                <path>namespaces</path>
+            </sample>
+            <sample>
+                <description>Describe a specific namespace</description>
+                <method>GET</method>
+                <path>namespaces/special_ns</path>
+            </sample>
+            <sample>
+                <description>Create a new namespace</description>
+                <method>POST</method>
+                <path>namespaces/special_ns</path>
+            </sample>
+            <sample>
+                <description>Delete a namespace. The namespace must be empty.</description>
+                <method>DELETE</method>
+                <path>namespaces/special_ns</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Web HBase's REST API documentation here</description>
+                <value>https://hbase.apache.org/book.html#_using_rest_endpointsl</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/hbase/?**">
diff --git a/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml b/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
index e2c2526..5e355fc 100644
--- a/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
@@ -21,6 +21,22 @@
         <context>/oozie</context>
         <shortDesc>Oozie Web Services API</shortDesc>
         <description>Oozie is a workflow scheduler system to manage Apache Hadoop jobs. The Oozie Web Services API is a HTTP REST JSON API.</description>
+        <samples>
+            <sample>
+                <description>Fetch the supported Oozie protocol versions by the server</description>
+                <method>GET</method>
+                <path>oozie/versions</path>
+            </sample>
+             <sample>
+                <description>Fetch the system status</description>
+                <method>GET</method>
+                <path>oozie/v1/admin/status</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Oozie's REST API documentation here</description>
+                <value>https://oozie.apache.org/docs/4.0.1/WebServicesAPI.html</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/oozie/**?**">
diff --git a/gateway-service-definitions/src/main/resources/services/ranger/1.0.0/service.xml b/gateway-service-definitions/src/main/resources/services/ranger/1.0.0/service.xml
index db13e4b..947bb03 100644
--- a/gateway-service-definitions/src/main/resources/services/ranger/1.0.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/ranger/1.0.0/service.xml
@@ -21,6 +21,22 @@
         <shortDesc>Ranger Admin REST API</shortDesc>
         <description>Apache Ranger is a framework to enable, monitor and manage comprehensive data security across the Hadoop platform. 
             Apache Ranger currently provides a centralized security adminstration, fine grain access control and detailed auditing for user access within Apache Hadoop, Apache Hive, Apache HBase and other Apache components</description>
+        <samples>
+            <sample>
+                <description>Fetch all policies</description>
+                <method>GET</method>
+                <path>public/v2/api/policy</path>
+            </sample>
+            <sample>
+                <description>Delete a role named 'name1'</description>
+                <method>DELETE</method>
+                <path>roles/roles/name/name1</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Ranger's REST API documentation here</description>
+                <value>https://ranger.apache.org/apidocs/index.html</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/ranger/service/public/**"/>
diff --git a/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml b/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
index 3549e7e..00cc757 100644
--- a/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
@@ -21,6 +21,22 @@
         <shortDesc>Apache Storm API</shortDesc>
         <description>Apache Storm is a free and open source distributed realtime computation system. 
             Apache Storm makes it easy to reliably process unbounded streams of data, doing for realtime processing what Hadoop did for batch processing.</description>
+        <samples>
+            <sample>
+                <description>Fetch the cluster configuration</description>
+                <method>GET</method>
+                <path>api/v1/cluster/configuration</path>
+            </sample>
+            <sample>
+                <description>Fetch summary for a supervisors running on a host named 'supervisor-daemon-host-name'</description>
+                <method>GET</method>
+                <path>api/v1/supervisor?host=supervisor-daemon-host-name</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Storm's REST API documentation here</description>
+                <value>http://storm.apache.org/releases/current/STORM-UI-REST-API.html</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/storm/api/**"/>
diff --git a/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml b/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
index b5adb31..7b0625b 100644
--- a/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
@@ -21,6 +21,22 @@
         <context>/templeton</context>
         <shortDesc>WebHCat</shortDesc>
         <description>WebHCat is the REST API for HCatalog, a table and storage management layer for Hadoop.</description>
+        <samples>
+            <sample>
+                <description>List HCatalog databases</description>
+                <method>GET</method>
+                <path>ddl/database</path>
+            </sample>
+            <sample>
+                <description>List the tables in an HCatalog database named 'db1'</description>
+                <method>GET</method>
+                <path>ddl/database/db1</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache HCatalog's REST API documentation here</description>
+                <value>https://cwiki.apache.org/confluence/display/Hive/WebHCat+Reference</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/templeton/v1/?**"/>
diff --git a/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml b/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
index a6b9e1b..48a7d41 100644
--- a/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
@@ -21,6 +21,27 @@
         <context>/webhdfs</context>
         <shortDesc>Web HDFS</shortDesc>
         <description>An HTTP REST API which supports the complete FileSystem interface for HDFS.</description>
+        <samples>
+            <sample>
+                <description>List all files under 'testPath'</description>
+                <method>GET</method>
+                <path>v1/testPath?op=LISTSTATUS</path>
+            </sample>
+            <sample>
+                <description>Rename a File/Directory under </description>
+                <method>PUT</method>
+                <path>v1/testPath/testFile?op=RENAME&amp;destination=testPath/renamedFile</path>
+            </sample>
+            <sample>
+                <description>Get Home Directory</description>
+                <method>GET</method>
+                <path>v1/?op=GETHOMEDIRECTORY</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache WebHDFS's REST API documentation here</description>
+                <value>https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/WebHDFS.html</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/webhdfs/v1/?**">
diff --git a/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml b/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
index 722abc6..76bbb18 100644
--- a/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
@@ -21,6 +21,22 @@
         <context>/resourcemanager</context>
         <shortDesc>YARN Resource Manager</shortDesc>
         <description>The YARN Resource Manager Service (RM) is the central controlling authority for resource management and makes allocation decisions ResourceManager has two main components: Scheduler and ApplicationsManager.</description>
+        <samples>
+            <sample>
+                <description>Fetch cluster info</description>
+                <method>GET</method>
+                <path>ws/v1/cluster/info</path>
+            </sample>
+            <sample>
+                <description>Fetch cluster metrics</description>
+                <method>GET</method>
+                <path>ws/v1/cluster/metrics</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache YARN Resource Manager's REST API documentation here</description>
+                <value>https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/ResourceManagerRest.html</value>
+            </sample>
+        </samples>
     </metadata>
     <routes>
         <route path="/resourcemanager/v1/cluster/"/>
diff --git a/gateway-service-definitions/src/main/resources/services/zeppelinws/0.8.1/service.xml b/gateway-service-definitions/src/main/resources/services/zeppelinws/0.8.1/service.xml
index 2e42b33..a743cf2 100644
--- a/gateway-service-definitions/src/main/resources/services/zeppelinws/0.8.1/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/zeppelinws/0.8.1/service.xml
@@ -21,6 +21,27 @@
         <context>/zeppelin/ws</context>
         <shortDesc>Zeppelin WS API</shortDesc>
         <description>Apache Zeppelin is a web-based notebook that enables data-driven, interactive data analytics and collaborative documents with SQL, Scala and more.</description>
+        <samples>
+            <sample>
+                <description>Fetch the available notebooks on your server</description>
+                <method>GET</method>
+                <path>api/notebook</path>
+            </sample>
+            <sample>
+                <description>Fetch the status of all paragraphs by the given note id (e.g. 'note1')</description>
+                <method>GET</method>
+                <path>api/notebook/job/note1</path>
+            </sample>
+            <sample>
+                <description>Delete a note by the given note id (e.g. 'note1')</description>
+                <method>DELETE</method>
+                <path>api/notebook/note1</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Zeppelin WS's REST API documentation here</description>
+                <value>http://zeppelin.apache.org/docs/0.8.1/usage/rest_api/notebook.html</value>
+            </sample>
+        </samples>
     </metadata>
   <routes>
     <route path="/zeppelin/ws">
diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java
index 135684e..b00501c 100644
--- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java
+++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java
@@ -20,19 +20,24 @@ package org.apache.knox.gateway.service.metadata;
 import java.io.UncheckedIOException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.knox.gateway.service.definition.Metadata;
+import org.apache.knox.gateway.service.definition.Sample;
 import org.apache.knox.gateway.topology.Service;
 
 @XmlRootElement(name = "service")
@@ -40,6 +45,7 @@ import org.apache.knox.gateway.topology.Service;
 public class ServiceModel implements Comparable<ServiceModel> {
 
   static final String SERVICE_URL_TEMPLATE = "%s://%s:%s/%s/%s%s";
+  static final String CURL_SAMPLE_TEMPLATE = "curl -iv -X %s \"%s%s\"";
   static final String HIVE_SERVICE_NAME = "HIVE";
   static final String HIVE_SERVICE_URL_TEMPLATE = "jdbc:hive2://%s:%d/;ssl=true;transportMode=http;httpPath=%s/%s/hive";
 
@@ -122,22 +128,37 @@ public class ServiceModel implements Comparable<ServiceModel> {
     if (HIVE_SERVICE_NAME.equals(getServiceName())) {
       return String.format(Locale.ROOT, HIVE_SERVICE_URL_TEMPLATE, request.getServerName(), request.getServerPort(), gatewayPath, topologyName);
     } else {
+      return getServiceUrl(context);
+    }
+  }
+
+  private String getServiceUrl(String context) {
+    final String resolvedContext = resolvePlaceholdersFromBackendUrl(context);
+    return String.format(Locale.ROOT, SERVICE_URL_TEMPLATE, request.getScheme(), request.getServerName(), request.getServerPort(), gatewayPath, topologyName, resolvedContext);
+  }
+
+  private String resolvePlaceholdersFromBackendUrl(String resolveable) {
+    String toBeResolved = resolveable;
+    if (toBeResolved != null) {
       final String backendUrlString = getBackendServiceUrl();
-      if (context.indexOf("{{BACKEND_HOST}}") > -1) {
-        context = context.replace("{{BACKEND_HOST}}", backendUrlString);
+
+      if (toBeResolved.indexOf("{{BACKEND_HOST}}") > -1) {
+        toBeResolved = toBeResolved.replace("{{BACKEND_HOST}}", backendUrlString);
       }
-      if (context.indexOf("{{SCHEME}}") > -1 || context.indexOf("{{HOST}}") > -1 || context.indexOf("{{PORT}}") > -1) {
+
+      if (toBeResolved.indexOf("{{SCHEME}}") > -1 || toBeResolved.indexOf("{{HOST}}") > -1 || toBeResolved.indexOf("{{PORT}}") > -1) {
         try {
           final URL backendUrl = new URL(backendUrlString);
-          context = context.replace("{{SCHEME}}", backendUrl.getProtocol());
-          context = context.replace("{{HOST}}", backendUrl.getHost());
-          context = context.replace("{{PORT}}", String.valueOf(backendUrl.getPort()));
+          toBeResolved = toBeResolved.replace("{{SCHEME}}", backendUrl.getProtocol());
+          toBeResolved = toBeResolved.replace("{{HOST}}", backendUrl.getHost());
+          toBeResolved = toBeResolved.replace("{{PORT}}", String.valueOf(backendUrl.getPort()));
         } catch (MalformedURLException e) {
           throw new UncheckedIOException("Error while converting " + backendUrlString + " to a URL", e);
         }
       }
-      return String.format(Locale.ROOT, SERVICE_URL_TEMPLATE, request.getScheme(), request.getServerName(), request.getServerPort(), gatewayPath, topologyName, context);
     }
+
+    return toBeResolved;
   }
 
   String getBackendServiceUrl() {
@@ -145,6 +166,26 @@ public class ServiceModel implements Comparable<ServiceModel> {
     return backendServiceUrl == null ? "" : backendServiceUrl;
   }
 
+  @XmlElement(name = "sample")
+  @XmlElementWrapper(name = "samples")
+  public List<Sample> getSamples() {
+    final List<Sample> samples = new ArrayList<>();
+    if (serviceMetadata != null && serviceMetadata.getSamples() != null) {
+      serviceMetadata.getSamples().forEach(sample -> {
+        final Sample resolvedSample = new Sample();
+        resolvedSample.setDescription(sample.getDescription());
+        if (StringUtils.isNotBlank(sample.getValue())) {
+          resolvedSample.setValue(sample.getValue());
+        } else {
+          final String method = StringUtils.isBlank(sample.getMethod()) ? "GET" : sample.getMethod();
+          resolvedSample.setValue(String.format(Locale.ROOT, CURL_SAMPLE_TEMPLATE, method, getServiceUrl(), sample.getPath()));
+        }
+        samples.add(resolvedSample);
+      });
+    }
+    return samples;
+  }
+
   @Override
   public boolean equals(Object obj) {
     if (obj == this) {
diff --git a/knox-homepage-ui/home/app/app.module.ts b/knox-homepage-ui/home/app/app.module.ts
index d72bbe4..964e84e 100644
--- a/knox-homepage-ui/home/app/app.module.ts
+++ b/knox-homepage-ui/home/app/app.module.ts
@@ -15,10 +15,10 @@
  * limitations under the License.
  */
 import {NgModule} from '@angular/core';
-import {DataTableModule} from 'angular2-datatable';
 import {BrowserModule} from '@angular/platform-browser';
 import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http';
 import {MatGridListModule} from '@angular/material/grid-list';
+import {BsModalModule} from 'ng2-bs3-modal/ng2-bs3-modal';
 
 import {GeneralProxyInformationComponent} from './generalProxyInformation/general.proxy.information.component';
 import {TopologyInformationsComponent} from './topologies/topology.information.component';
@@ -28,8 +28,8 @@ import {HomepageService} from './homepage.service';
     imports: [BrowserModule,
         HttpClientModule,
         HttpClientXsrfModule,
-        DataTableModule,
-        MatGridListModule
+        MatGridListModule,
+        BsModalModule
     ],
     declarations: [GeneralProxyInformationComponent,
                    TopologyInformationsComponent
diff --git a/knox-homepage-ui/home/app/topologies/service.ts b/knox-homepage-ui/home/app/topologies/sample.ts
similarity index 84%
copy from knox-homepage-ui/home/app/topologies/service.ts
copy to knox-homepage-ui/home/app/topologies/sample.ts
index c3ae63d..2d92417 100644
--- a/knox-homepage-ui/home/app/topologies/service.ts
+++ b/knox-homepage-ui/home/app/topologies/sample.ts
@@ -15,12 +15,7 @@
  * limitations under the License.
  */
 
-export class Service {
+export class Sample {
     description: string;
-    serviceName: string;
-    version: string;
-    serviceUrl: string;
-    shortDesc: string;
-    type: string;
-    context: string;
+    value: string;
 }
diff --git a/knox-homepage-ui/home/app/topologies/service.ts b/knox-homepage-ui/home/app/topologies/service.ts
index c3ae63d..dca781a 100644
--- a/knox-homepage-ui/home/app/topologies/service.ts
+++ b/knox-homepage-ui/home/app/topologies/service.ts
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+import {Sample} from './sample';
 
 export class Service {
     description: string;
@@ -23,4 +24,5 @@ export class Service {
     shortDesc: string;
     type: string;
     context: string;
+    samples: Sample[];
 }
diff --git a/knox-homepage-ui/home/app/topologies/topology.information.component.html b/knox-homepage-ui/home/app/topologies/topology.information.component.html
index 4ba685f..281ce60 100644
--- a/knox-homepage-ui/home/app/topologies/topology.information.component.html
+++ b/knox-homepage-ui/home/app/topologies/topology.information.component.html
@@ -33,6 +33,8 @@
 
     <div class="table-responsive" *ngIf="this['showTopology_' + topology.topology]">
 
+        <h5 *ngIf="topology.uiServices.service.length > 0">UI Services</h5>
+
         <!-- UI services -->
         <mat-grid-list cols="4" rowHeight="130px">
             <mat-grid-tile *ngFor="let service of topology.uiServices.service" [colspan]="1" [rowspan]="1">
@@ -51,38 +53,72 @@
             </mat-grid-tile>
         </mat-grid-list>
 
+        <h5 *ngIf="topology.apiServices.service.length > 0">API Services</h5>
+
         <!-- API services -->
-        <table class="table table-hover" [mfData]="topology.apiServices.service" #api="mfDataTable" [mfRowsOnPage]="5">
-            <colgroup>
-                <col width="30%">
-                <col width="70%">
-            </colgroup>
-            <thead>
-                <tr *ngIf="topology.apiServices.service.length == 0"><th colspan="2">No API services found</th></tr>
-                <tr *ngIf="topology.apiServices.service.length > 0"><th colspan="2">API services</th></tr>
-            </thead>
-            <tbody>
-                <tr *ngFor="let service of api.data">
-                    <td>
-                        <span class="inline-glyph glyphicon glyphicon-info-sign btn btn-xs"
-                        title="{{service.description}}"
-                        data-toggle="tooltip"></span>
-                        {{service.shortDesc}} <span class="small" *ngIf="service.version">(v{{service.version}})</span>
-                    </td>
-                    <td>
-                        <a href="{{service.serviceUrl}}">{{service.serviceUrl}}</a>
-                    </td>
-                </tr>
-            </tbody>
-      <tfoot>
-          <tr>
-              <td colspan="4">
-                  <mfBootstrapPaginator [rowsOnPageSet]="[5,10,15]"></mfBootstrapPaginator>
-              </td>
-          </tr>
-      </tfoot>
-        </table>
+        <mat-grid-list cols="4" rowHeight="130px">
+            <mat-grid-tile *ngFor="let service of topology.apiServices.service" [colspan]="1" [rowspan]="1">
+                <span *ngIf="!this['enableServiceText_' + service.serviceName.toLowerCase()]" (click)="openApiServiceInformationModal(service)">
+                    <img src="assets/service-logos/{{service.serviceName.toLowerCase()}}.png" height="50px" (error)="enableServiceText('enableServiceText_' + service.serviceName.toLowerCase())"/>
+                </span>
+                <span *ngIf="this['enableServiceText_' + service.serviceName.toLowerCase()]" (click)="openApiServiceInformationModal(service)">
+                    {{service.shortDesc}}
+                </span>
+                <mat-grid-tile-footer class="tile-shortDesc">
+                    <h3>{{service.shortDesc}} <span class="small" *ngIf="service.version">(v{{service.version}})</span></h3>
+                </mat-grid-tile-footer>
+                <mat-grid-tile-footer class="tile-longDesc" style="height:100px;">
+                    <h3>{{service.description}}</h3>
+                </mat-grid-tile-footer>
+            </mat-grid-tile>
+        </mat-grid-list>
     </div>
 </ng-container>
 <hr />
-</div>
\ No newline at end of file
+</div>
+
+<bs-modal #apiServiceInformationModal>
+    <bs-modal-header [showDismiss]="true" *ngIf="selectedApiService">
+        <h4 class="modal-title">{{selectedApiService.shortDesc}}</h4>
+    </bs-modal-header>
+    <bs-modal-body *ngIf="selectedApiService">
+        <div class="panel panel-default table-responsive">
+            <table class="table table-sm">
+                <colgroup>
+                   <col width="25%">
+                   <col width="75%">
+               </colgroup>
+               <tr>
+                   <td style="font-weight: bold;">Knox Service Name</td>
+                   <td>{{selectedApiService.serviceName}} <span class="small" *ngIf="selectedApiService.version">(v{{selectedApiService.version}})</span></td>
+               </tr>
+               <tr>
+                   <td style="font-weight: bold;">Description</td>
+                   <td>{{selectedApiService.description}}</td>
+               </tr>
+               <tr>
+                   <td style="font-weight: bold;">Sample(s)</td>
+                   <td>
+                     <table class="table table-sm">
+                       <div *ngIf="selectedApiService.samples && selectedApiService.samples.sample.length > 0">
+                         <ng-container *ngFor="let sample of selectedApiService.samples.sample">
+                           <tr><td style="font-weight: bold;">{{sample.description}}</td></tr>
+                           <tr style="margin-bottom: 15px"><td>&nbsp;&nbsp;{{sample.value}}</tr>
+                         </ng-container>
+                       </div>
+                       <div *ngIf="!selectedApiService.samples || selectedApiService.samples.sample.length < 1">
+                         <tr><td style="font-weight: bold;">There is no any sample found in service metadata</td></tr>
+                         <tr>
+                           <td>&nbsp;You may check out the service's documentation and find out how to use its REST API. The service's URL is <a href="{{selectedApiService.serviceUrl}}" target="_blank">{{selectedApiService.serviceUrl}}</a></td>
+                         </tr>
+                       </div>
+                     </table>
+                   </td>
+               </tr>
+           </table>
+       </div>
+    </bs-modal-body>
+    <bs-modal-footer>
+        <button type="button" class="btn btn-primary btn-sm" (click)="apiServiceInformationModal.close()">Close</button>
+    </bs-modal-footer>
+</bs-modal>
diff --git a/knox-homepage-ui/home/app/topologies/topology.information.component.ts b/knox-homepage-ui/home/app/topologies/topology.information.component.ts
index f251a8f..c3a394c 100644
--- a/knox-homepage-ui/home/app/topologies/topology.information.component.ts
+++ b/knox-homepage-ui/home/app/topologies/topology.information.component.ts
@@ -14,8 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import {Component, OnInit} from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
 import {MatGridListModule} from '@angular/material/grid-list';
+import {BsModalComponent} from 'ng2-bs3-modal/ng2-bs3-modal';
 import {HomepageService} from '../homepage.service';
 import {TopologyInformation} from './topology.information';
 import {Service} from './service';
@@ -29,7 +30,11 @@ import {Service} from './service';
 
 export class TopologyInformationsComponent implements OnInit {
 
+    @ViewChild('apiServiceInformationModal')
+    apiServiceInformationModal: BsModalComponent;
+
     topologies: TopologyInformation[];
+    selectedApiService : Service;
 
     setTopologies(topologies: TopologyInformation[]) {
         this.topologies = topologies;
@@ -55,4 +60,9 @@ export class TopologyInformationsComponent implements OnInit {
         this.homepageService.getTopologies().then(topologies => this.setTopologies(topologies));
     }
 
+    openApiServiceInformationModal(apiService: Service) {
+        this.selectedApiService = apiService;
+        this.apiServiceInformationModal.open('lg');
+    }
+
 }
diff --git a/knox-homepage-ui/package-lock.json b/knox-homepage-ui/package-lock.json
index d6f75b8..0d16d41 100644
--- a/knox-homepage-ui/package-lock.json
+++ b/knox-homepage-ui/package-lock.json
@@ -390,14 +390,6 @@
       "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
       "dev": true
     },
-    "angular2-datatable": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/angular2-datatable/-/angular2-datatable-0.6.0.tgz",
-      "integrity": "sha1-ygCPdAh/DLh9pXCe0vLR0GF3JjI=",
-      "requires": {
-        "lodash": "^4.0.0"
-      }
-    },
     "ansi-html": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
@@ -4682,7 +4674,8 @@
     "lodash": {
       "version": "4.17.15",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+      "dev": true
     },
     "lodash.clonedeep": {
       "version": "4.5.0",
@@ -5119,6 +5112,11 @@
       "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
       "dev": true
     },
+    "ng2-bs3-modal": {
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/ng2-bs3-modal/-/ng2-bs3-modal-0.13.0.tgz",
+      "integrity": "sha512-rCxLpyTFXGpQOQCm32N4xGTN2roBsmIyUNQw6dFd/2yjVK+t7zmsFSO5IIuHioXAzTVGr4/LHFTOiz0JvJGnbg=="
+    },
     "no-case": {
       "version": "2.3.2",
       "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
diff --git a/knox-homepage-ui/package.json b/knox-homepage-ui/package.json
index d282245..71e4e96 100644
--- a/knox-homepage-ui/package.json
+++ b/knox-homepage-ui/package.json
@@ -20,11 +20,11 @@
     "@angular/platform-browser": "^5.2.0",
     "@angular/platform-browser-dynamic": "^5.2.0",
     "@angular/router": "^5.2.0",
-    "angular2-datatable": "^0.6.0",
     "bootstrap": "^3.4.1",
     "core-js": "^2.6.11",
     "jquery": "^3.4.1",
     "js-yaml": "^3.13.1",
+    "ng2-bs3-modal": "^0.13.0",
     "popper.js": "^1.16.1",
     "rxjs": "^5.5.2",
     "sweetalert": "^2.1.2",


Mime
View raw message