Repository: incubator-slider
Updated Branches:
  refs/heads/develop ad33f069e -> fad546eab


SLIDER-771 root web UI to link to REST API


Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/d3c08bdb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/d3c08bdb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/d3c08bdb

Branch: refs/heads/develop
Commit: d3c08bdbccc2037bbb4bdb78879a7a37f61cb0ec
Parents: 00542b8
Author: Steve Loughran <[email protected]>
Authored: Tue Feb 3 20:58:27 2015 +0000
Committer: Steve Loughran <[email protected]>
Committed: Tue Feb 3 20:58:27 2015 +0000

----------------------------------------------------------------------
 .../providers/AbstractProviderService.java      |  5 ++
 .../slider/providers/ProviderService.java       |  6 ++
 .../providers/agent/AgentProviderService.java   |  5 ++
 .../slideram/SliderAMProviderService.java       |  5 ++
 .../server/appmaster/web/view/IndexBlock.java   | 82 ++++++++++++++------
 .../server/appmaster/web/view/NavBlock.java     | 35 +++++++--
 .../slider/agent/rest/TestStandaloneREST.groovy |  1 -
 .../agent/standalone/DemoStandaloneAM.groovy    | 71 +++++++++++++++++
 .../model/mock/MockProviderService.groovy       |  5 ++
 9 files changed, 182 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
 
b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
index c628d8a..6856400 100644
--- 
a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
+++ 
b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
@@ -58,6 +58,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -101,6 +102,10 @@ public abstract class AbstractProviderService
     this.amState = amState;
   }
 
+  @Override
+  public String getHumanName() {
+    return getName().toLowerCase(Locale.ENGLISH);
+  }
   
   @Override
   public void bind(StateAccessForProviders stateAccessor,

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/main/java/org/apache/slider/providers/ProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/ProviderService.java 
b/slider-core/src/main/java/org/apache/slider/providers/ProviderService.java
index dd891db..28cef01 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/ProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/ProviderService.java
@@ -156,6 +156,12 @@ public interface ProviderService extends ProviderCore,
    */
   Map<String, String> buildMonitorDetails(ClusterDescription clusterSpec);
 
+  /**
+   * Get a human friendly name for web UIs and messages
+   * @return a name string. Default is simply the service instance name.
+   */
+  String getHumanName();
+
   public void bind(StateAccessForProviders stateAccessor,
       QueueAccess queueAccess,
       List<Container> liveContainers);

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
 
b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
index ad8ef43..69857d2 100644
--- 
a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
+++ 
b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
@@ -196,6 +196,11 @@ public class AgentProviderService extends 
AbstractProviderService implements
   }
 
   @Override
+  public String getHumanName() {
+    return "Slider Agent";
+  }
+
+  @Override
   public List<ProviderRole> getRoles() {
     return AgentRoles.getRoles();
   }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
 
b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
index 408e311..cee7a97 100644
--- 
a/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
+++ 
b/slider-core/src/main/java/org/apache/slider/providers/slideram/SliderAMProviderService.java
@@ -67,6 +67,11 @@ public class SliderAMProviderService extends 
AbstractProviderService implements
   }
 
   @Override
+  public String getHumanName() {
+    return "Slider Application";
+  }
+  
+  @Override
   public Configuration loadProviderConfigurationInformation(File confDir) 
throws
       BadCommandArgumentsException,
       IOException {

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java
index 59a03f9..ef020fd 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java
@@ -24,6 +24,7 @@ import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.UL;
 import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
 import org.apache.slider.api.ClusterDescription;
 import org.apache.slider.api.StatusKeys;
+import org.apache.slider.api.types.ApplicationLivenessInformation;
 import org.apache.slider.common.tools.SliderUtils;
 import org.apache.slider.providers.ProviderService;
 import org.apache.slider.server.appmaster.state.RoleStatus;
@@ -64,26 +65,51 @@ public class IndexBlock extends HtmlBlock {
   @VisibleForTesting
   protected void doIndex(Hamlet html, String providerName) {
     ClusterDescription clusterStatus = appView.getClusterStatus();
+    String name = clusterStatus.name;
+    if (name.startsWith(" ") || name.endsWith(" ")) {
+      name = "'" + name + "'";
+    } 
     DIV<Hamlet> div = html.div("general_info")
                           .h1("index_header",
-                              "Application: '" + clusterStatus.name + "'");
+                              "Application: " + name);
+
+    ApplicationLivenessInformation liveness =
+        appView.getApplicationLivenessInformation();
+    String livestatus =
+        liveness.allRequestsSatisfied
+        ? "all containers allocated"
+        : String.format("Awaiting %d containers", 
liveness.requestsOutstanding);
+    Hamlet.TABLE<DIV<Hamlet>> table1 = div.table();
+    table1.tr()
+          .td("Status")
+          .td(livestatus)
+          ._();
+    table1.tr()
+          .td("Total number of containers")
+          .td(Integer.toString(appView.getNumOwnedContainers()))
+          ._();
+    table1.tr()
+          .td("Create time: ")
+          .td(getInfoAvoidingNulls(StatusKeys.INFO_CREATE_TIME_HUMAN))
+          ._();
+    table1.tr()
+          .td("Running since: ")
+          .td(getInfoAvoidingNulls(StatusKeys.INFO_LIVE_TIME_HUMAN))
+          ._();
+    table1.tr()
+          .td("Time last flexed: ")
+          .td(getInfoAvoidingNulls(StatusKeys.INFO_FLEX_TIME_HUMAN))
+          ._();
+    table1.tr()
+          .td("Application storage path: ")
+          .td(clusterStatus.dataPath)
+          ._();
+    table1.tr()
+          .td("Application configuration path: ")
+          .td(clusterStatus.originConfigurationPath)
+          ._();
+    table1._()._();
 
-    UL<DIV<Hamlet>> ul = div.ul();
-
-    ul.li("Total number of containers for application: " + 
appView.getNumOwnedContainers());
-    ul.li("Application created: " +
-          getInfoAvoidingNulls(StatusKeys.INFO_CREATE_TIME_HUMAN));
-    ul.li("Application last flexed: " + 
getInfoAvoidingNulls(StatusKeys.INFO_FLEX_TIME_HUMAN));
-    ul.li("Application running since: " + 
getInfoAvoidingNulls(StatusKeys.INFO_LIVE_TIME_HUMAN));
-    ul.li("Application HDFS storage path: " + clusterStatus.dataPath);
-    ul.li("Application configuration path: " + 
clusterStatus.originConfigurationPath);
-
-    ul._()._();
-
-    html.div("provider_info").h3(providerName + " specific information");
-    ul = div.ul();
-    addProviderServiceOptions(providerService, ul, clusterStatus);
-    ul._()._();
 
     html.div("container_instances").h3("Component Instances");
 
@@ -102,20 +128,28 @@ public class IndexBlock extends HtmlBlock {
     for (RoleStatus status : roleStatuses) {
       table.tr()
            .td(status.getName())
-           .th(String.format("%d", status.getDesired()))
-           .th(String.format("%d", status.getActual()))
-           .th(String.format("%d", status.getRequested()))
-           .th(String.format("%d", status.getFailed()))
-           .th(String.format("%d", status.getStartFailed()))
+           .td(String.format("%d", status.getDesired()))
+           .td(String.format("%d", status.getActual()))
+           .td(String.format("%d", status.getRequested()))
+           .td(String.format("%d", status.getFailed()))
+           .td(String.format("%d", status.getStartFailed()))
             ._();
     }
 
     table._()._();
+
+    // some spacing
+    html.p()._();
+    html.p()._();
+
+    html.div("provider_info").h3(providerName + " information");
+    UL<DIV<Hamlet>> ul = div.ul();
+    addProviderServiceOptions(providerService, ul, clusterStatus);
+    ul._()._();
   }
 
   private String getProviderName() {
-    String providerServiceName = 
providerService.getName().toLowerCase(Locale.ENGLISH);
-    return providerServiceName;
+    return providerService.getHumanName();
   }
 
   private String getInfoAvoidingNulls(String key) {

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java
index 1bdf1bd..b2327ba 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java
@@ -17,8 +17,10 @@
 package org.apache.slider.server.appmaster.web.view;
 
 import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
-import org.apache.slider.server.appmaster.web.SliderAMWebApp;
-import org.apache.slider.server.appmaster.web.rest.RestPaths;
+import static org.apache.slider.server.appmaster.web.SliderAMWebApp.*;
+import static org.apache.slider.server.appmaster.web.rest.RestPaths.*;
+
+import static org.apache.hadoop.yarn.util.StringHelper.ujoin;
 
 /**
  * 
@@ -32,12 +34,21 @@ public class NavBlock extends HtmlBlock {
         h3("Slider").
         ul().
           li().a(this.prefix(), "Overview")._().
-          li().a(this.prefix() + SliderAMWebApp.CONTAINER_STATS, 
"Statistics")._().
-          li().a(this.prefix() + SliderAMWebApp.CLUSTER_SPEC, 
"Specification")._().
-          li().a(rootPath(RestPaths.SYSTEM_METRICS), "Metrics")._().
-          li().a(rootPath(RestPaths.SYSTEM_METRICS_JSON), "Metrics as 
JSON")._().
-          li().a(rootPath(RestPaths.SYSTEM_HEALTHCHECK), "Health")._().
-          li().a(rootPath(RestPaths.SYSTEM_THREADS), "Threads")._()
+          li().a(relPath(CONTAINER_STATS), "Statistics")._().
+          li().a(relPath(CLUSTER_SPEC), "Specification")._().
+          li().a(relPath(CLUSTER_SPEC), "Specification")._().
+          li().a(rootPath(SYSTEM_METRICS_JSON), "Metrics")._().
+          li().a(rootPath(SYSTEM_HEALTHCHECK), "Health")._().
+          li().a(rootPath(SYSTEM_THREADS), "Threads")._().
+        _()
+    .h3("REST API"). 
+        ul().
+          li().a(apiPath(MODEL_DESIRED), "Specified")._().
+          li().a(apiPath(MODEL_RESOLVED), "Resolved")._().
+          li().a(apiPath(LIVE_RESOURCES), "Resources")._().
+          li().a(apiPath(LIVE_COMPONENTS), "Components")._().
+          li().a(apiPath(LIVE_CONTAINERS), "Containers")._().
+          li().a(apiPath(LIVE_LIVENESS), "Liveness")._()
         ._()
       ._();
   }
@@ -45,4 +56,12 @@ public class NavBlock extends HtmlBlock {
   private String rootPath(String absolutePath) {
     return root_url(absolutePath);
   }
+  
+  private String relPath(String... args) {
+    return ujoin(this.prefix(), args);
+  }
+  private String apiPath(String api) {
+    return root_url(SLIDER_PATH_APPLICATION,  api);
+  }
+  
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
index e4ce295..7306c48 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
@@ -85,7 +85,6 @@ class TestStandaloneREST extends AgentMiniClusterTestBase {
       def metrics = GET(directAM, SYSTEM_METRICS)
       log.info metrics
     }
-
     
     GET(proxyAM)
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/test/groovy/org/apache/slider/agent/standalone/DemoStandaloneAM.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/DemoStandaloneAM.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/DemoStandaloneAM.groovy
new file mode 100644
index 0000000..0b90ffe
--- /dev/null
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/DemoStandaloneAM.groovy
@@ -0,0 +1,71 @@
+/*
+ * 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.slider.agent.standalone
+
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+import org.apache.hadoop.yarn.api.records.ApplicationReport
+import org.apache.slider.agent.AgentMiniClusterTestBase
+import org.apache.slider.client.SliderClient
+import org.apache.slider.core.main.ServiceLauncher
+import org.junit.After
+import org.junit.Test
+
+/**
+ * This is a test with the name "Demo" so it doesn't run.
+ * All it does is start the AM, print the URLs and then
+ * sleep for a while.
+ */
+@CompileStatic
+@Slf4j
+class DemoStandaloneAM extends AgentMiniClusterTestBase {
+
+
+
+  @After
+  void fixclientname() {
+    sliderClientClassName = DEFAULT_SLIDER_CLIENT
+  }
+  
+  @Test(timeout = 600000L)
+  public void testDemoStandaloneAM() throws Throwable {
+
+    describe "create a standalone AM then pause to allow the user " +
+             "to explore the web and YARN UI integration"
+    //launch fake master
+    String clustername = createMiniCluster("", configuration, 1, true)
+
+
+    ServiceLauncher<SliderClient> launcher =
+        createStandaloneAM(clustername, true, false)
+    SliderClient client = launcher.service
+    addToTeardown(client);
+
+    ApplicationReport report = waitForClusterLive(client)
+    URI uri = new URI(report.originalTrackingUrl)
+
+    logReport(report)
+
+    describe "YARN RM proxy: ${report.trackingUrl}"
+    describe "Direct Application ${report.originalTrackingUrl}"
+    
+    sleep(5 * 60 * 1000)
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/d3c08bdb/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
index 7efcd96..e62c24e 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
@@ -53,6 +53,11 @@ import 
org.apache.slider.server.services.yarnregistry.YarnRegistryViewForProvide
 class MockProviderService implements ProviderService {
 
   @Override
+  String getHumanName() {
+    return null
+  }
+
+  @Override
   public String getName() {
     return null;
   }

Reply via email to