CHUKWA-787. Added full screen support, and quick link to Hadoop and HBase UI.  (Eric Yang)
diff --git a/CHANGES.txt b/CHANGES.txt
index cab670f..684b3f5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,8 @@
 
   NEW FEATURES
 
+    CHUKWA-787. Added full screen support, and quick link to Hadoop and HBase UI.  (Eric Yang)
+
     CHUKWA-785. Added banner, pie chart, gauge chart to graph explorer.  (Eric Yang)
 
     CHUKWA-778. Added pie chart, circle chart and timeline javascripts.  (Eric Yang)
diff --git a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
index fec9281..120b731 100644
--- a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
+++ b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
@@ -424,8 +424,8 @@
    * Create a chart in HBase by specifying parameters.
    * @throws URISyntaxException 
    */
-  public static synchronized String createChart(String id, String yunitType, 
-      String title, String[] metrics, String source) throws URISyntaxException {
+  public static synchronized String createChart(String id,
+      String title, String[] metrics, String source, String yunitType) throws URISyntaxException {
     Chart chart = new Chart(id);
     chart.setYUnitType(yunitType);
     chart.setTitle(title);
@@ -445,6 +445,58 @@
   }
 
   /**
+   * Create a chart in HBase by specifying parameters.
+   * @throws URISyntaxException 
+   */
+  public static synchronized String createCircle(String id,
+      String title, String[] metrics, String source, String suffixLabel) throws URISyntaxException {
+    Chart chart = new Chart(id);
+    chart.setSuffixText(suffixLabel);
+    chart.setTitle(title);
+    ArrayList<SeriesMetaData> series = new ArrayList<SeriesMetaData>();
+    for(String metric : metrics) {
+      SeriesMetaData s = new SeriesMetaData();
+      s.setLabel(metric + "/" + source);
+      s.setUrl(new URI("/hicc/v1/metrics/series/" + metric + "/"
+        + source));
+      series.add(s);
+    }
+    chart.setSeries(series);
+    return createChart(chart);
+    
+  }
+
+  /**
+   * Create a tile in HBase by specifying parameters.
+   * @param id
+   * @param title
+   * @param bannerText
+   * @param suffixLabel
+   * @param metrics
+   * @param source
+   * @param icon
+   * @return
+   * @throws URISyntaxException
+   */
+  public static synchronized String createTile(String id, String title, 
+      String bannerText, String suffixLabel, String[] metrics, String source, 
+      String icon) throws URISyntaxException {
+    Chart chart = new Chart(id);
+    chart.setTitle(title);
+    chart.setBannerText(bannerText);
+    chart.setSuffixText(suffixLabel);
+    chart.setIcon(icon);
+    List<SeriesMetaData> smd = new ArrayList<SeriesMetaData>();
+    for (String metric : metrics) {
+      SeriesMetaData series = new SeriesMetaData();
+      series.setUrl(new URI("/hicc/v1/metrics/series/" + metric + "/" + source));
+      smd.add(series);
+    }
+    chart.setSeries(smd);
+    return createChart(chart);
+  }
+
+  /**
    * Create a chart in HBase.
    * 
    * @param chart
@@ -662,6 +714,13 @@
           Result result = it.next();
           for(Cell kv : result.rawCells()) {
             snapshot = new String(CellUtil.cloneValue(kv));
+            if(snapshot.matches("-?\\d+(\\.\\d+)?")) {
+              int endOffset = snapshot.length();
+              if(snapshot.length() - snapshot.indexOf(".") > 2) {
+                endOffset = snapshot.indexOf(".") + 2;
+              }
+              snapshot = snapshot.substring(0, endOffset);
+            }
           }
         }
         data.add(snapshot);
@@ -848,41 +907,67 @@
       String hostname = InetAddress.getLocalHost().getHostName().toLowerCase();
       // Populate example chart widgets
       String[] metrics = { "SystemMetrics.LoadAverage.1" };
-      createChart("1", "", "System Load Average", metrics, hostname);
+      createChart("1", "System Load Average", metrics, hostname, "");
       String[] cpuMetrics = { "SystemMetrics.cpu.combined", "SystemMetrics.cpu.sys", "SystemMetrics.cpu.user" };
-      createChart("2", "percent", "CPU Utilization", cpuMetrics, hostname);
+      createChart("2", "CPU Utilization", cpuMetrics, hostname, "percent");
       String[] memMetrics = { "SystemMetrics.memory.FreePercent", "SystemMetrics.memory.UsedPercent"};
-      createChart("3", "percent", "Memory Utilization", memMetrics, hostname);
+      createChart("3", "Memory Utilization", memMetrics, hostname, "percent");
       String[] diskMetrics = { "SystemMetrics.disk.ReadBytes", "SystemMetrics.disk.WriteBytes" };
-      createChart("4", "bytes-decimal", "Disk Utilization", diskMetrics, hostname);
+      createChart("4", "Disk Utilization", diskMetrics, hostname, "bytes-decimal");
       String[] netMetrics = { "SystemMetrics.network.TxBytes", "SystemMetrics.network.RxBytes" };
-      createChart("5", "bytes", "Network Utilization", netMetrics, hostname);
+      createChart("5", "Network Utilization", netMetrics, hostname, "bytes");
       String[] swapMetrics = { "SystemMetrics.swap.Total", "SystemMetrics.swap.Used", "SystemMetrics.swap.Free" };
-      createChart("6", "bytes-decimal", "Swap Utilization", swapMetrics, hostname);
+      createChart("6", "Swap Utilization", swapMetrics, hostname, "bytes-decimal");
+      
+      // Namenode heap usage
       StringBuilder namenode = new StringBuilder();
       namenode.append(hostname);
       namenode.append(":NameNode");
       String[] namenodeHeap = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("7", "percent", "Namenode Memory", namenodeHeap, namenode.toString());
+      createCircle("7", "Namenode Memory", namenodeHeap, namenode.toString(), "%");
+      
+      // HDFS Usage
       String[] hdfsUsage = { "HadoopMetrics.dfs.FSNamesystem.CapacityUsed", "HadoopMetrics.dfs.FSNamesystem.CapacityTotal" };
-      createChart("8", "percent", "HDFS Usage", hdfsUsage, hostname);
+      createCircle("8", "HDFS Usage", hdfsUsage, hostname, "%");
 
+      // Resource Manager Memory
       StringBuilder rmnode = new StringBuilder();
       rmnode.append(hostname);
       rmnode.append(":ResourceManager");
       String[] rmHeap = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("9", "percent", "Resource Manager Memory", rmHeap, rmnode.toString());
+      createCircle("9", "Resource Manager Memory", rmHeap, rmnode.toString(), "%");
 
+      // Node Managers Health
+      String[] nmh = { "HadoopMetrics.yarn.ClusterMetrics.NumActiveNMs", "HadoopMetrics.yarn.ClusterMetrics.NumLostNMs" };
+      createTile("10", "Node Managers Health", "Node Managers", "Active/Lost", nmh, hostname, "glyphicon-th");
+
+      // High Availability State
+      String[] ha = { "HadoopMetrics.dfs.FSNamesystem.HAState" };
+      createTile("11", "HDFS High Availability State", "HDFS High Availability", "", ha, hostname, "glyphicon-random");
+
+      // HDFS Load
+      String[] hdfsLoad = { "HadoopMetrics.dfs.FSNamesystem.TotalLoad" };
+      createTile("12", "HDFS Load Average", "HDFS Load", "", hdfsLoad, hostname, "glyphicon-signal");
+
+      // Namenode RPC Latency
+      String[] nnLatency = { "HadoopMetrics.rpc.rpc.RpcProcessingTimeAvgTime" };
+      createTile("13", "NameNode Latency", "NameNode RPC Latency", "Milliseconds", nnLatency, hostname, "glyphicon-tasks");
+
+      // Datanode Health
+      String[] dnHealth = { "HadoopMetrics.dfs.FSNamesystem.StaleDataNodes" };
+      createTile("14", "Datanodes Health", "Datanodes", "Dead", dnHealth, hostname, "glyphicon-hdd");
+
+      // HBase Master Memory
       StringBuilder hbaseMaster = new StringBuilder();
       hbaseMaster.append(hostname);
       hbaseMaster.append(":Master");
       String[] hbm = { "HBaseMetrics.jvm.JvmMetrics.MemHeapUsedM", "HBaseMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("10", "percent", "HBase Master Memory", hbm, hbaseMaster.toString());
+      createCircle("15", "HBase Master Memory", hbm, hbaseMaster.toString(), "%");
 
       // Demo metrics
-      String[] trialAbandonRate = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("11", "percent", "Trial Abandon Rate", trialAbandonRate, namenode.toString());
-      createChart("12", "percent", "Unhealthy Clusters", hdfsUsage, hostname);
+//      String[] trialAbandonRate = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
+//      createChart("T1", "Trial Abandon Rate", trialAbandonRate, namenode.toString(), "percent");
+//      createChart("T2", "Unhealthy Clusters", hdfsUsage, hostname, "percent");
       
       // Populate default widgets
       Widget widget = new Widget();
@@ -902,7 +987,7 @@
       widget.setSrc(new URI("/hicc/welcome.html"));
       widget.setCol(1);
       widget.setRow(1);
-      widget.setSize_x(9);
+      widget.setSize_x(10);
       widget.setSize_y(5);
       createWidget(widget);
       dashboard.add(widget);
@@ -992,6 +1077,57 @@
 
       // Populate user dashboards
       dashboard = new Dashboard();
+
+      widget = new Widget();
+      widget.setTitle("Quick Links");
+      widget.setSrc(new URI("/hicc/v1/dashboard/quicklinks"));
+      widget.setCol(1);
+      widget.setRow(1);
+      widget.setSize_x(10);
+      widget.setSize_y(5);
+      createWidget(widget);
+      dashboard.add(widget);
+
+      // Log Search widget
+      widget = new Widget();
+      widget.setTitle("Log Search");
+      widget.setSrc(new URI("/hicc/ajax-solr/chukwa"));
+      widget.setCol(1);
+      widget.setRow(1);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
+      // Applications
+      widget = new Widget();
+      widget.setTitle("YARN Applications");
+      widget.setSrc(new URI("http://localhost:8088/"));
+      widget.setCol(1);
+      widget.setRow(7);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
+      // Hadoop Distributed File System
+      widget = new Widget();
+      widget.setTitle("HDFS");
+      widget.setSrc(new URI("http://localhost:50070/explorer.html#/"));
+      widget.setCol(1);
+      widget.setRow(7);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
+      // HBase Tables
+      widget = new Widget();
+      widget.setTitle("HBase Tables");
+      widget.setSrc(new URI("http://localhost:50654/tablesDetailed.jsp"));
+      widget.setCol(1);
+      widget.setRow(14);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
       widget = new Widget();
       widget.setTitle("Top Applications");
       widget.setSrc(new URI("/hicc/apps/"));
@@ -999,18 +1135,7 @@
       widget.setRow(1);
       widget.setSize_x(2);
       widget.setSize_y(2);
-      dashboard.add(widget);
-
-      // Log Search widget
-      widget = new Widget();
-      widget.setTitle("Log Search");
-      widget.setSrc(new URI("/hicc/ajax-solr/chukwa"));
-      widget.setCol(3);
-      widget.setRow(1);
-      widget.setSize_x(6);
-      widget.setSize_y(6);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Top Users");
@@ -1020,116 +1145,116 @@
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-      dashboard.add(widget);
       updateDashboard("user", "", dashboard);
 
       // Populate system dashboards
       dashboard = new Dashboard();
       widget = new Widget();
-      widget.setTitle("Services Running");
-      widget.setSrc(new URI("/hicc/services/services.html"));
+      widget.setTitle("HDFS High Availability State");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/11"));
       widget.setCol(1);
       widget.setRow(1);
       widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
+
+      widget = new Widget();
+      widget.setTitle("HDFS Load");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/12"));
+      widget.setCol(3);
+      widget.setRow(1);
+      widget.setSize_x(2);
+      widget.setSize_y(1);
+      createWidget(widget);
+      dashboard.add(widget);
+
+      widget = new Widget();
+      widget.setTitle("HDFS Namenode Latency");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/13"));
+      widget.setCol(5);
+      widget.setRow(1);
+      widget.setSize_x(2);
+      widget.setSize_y(1);
+      createWidget(widget);
+      dashboard.add(widget);
+
+      widget = new Widget();
+      widget.setTitle("Datanodes Health");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/14"));
+      widget.setCol(7);
+      widget.setRow(1);
+      widget.setSize_x(2);
+      widget.setSize_y(1);
+      createWidget(widget);
+      dashboard.add(widget);
       
       widget = new Widget();
-      widget.setTitle("Applications Running");
-      widget.setSrc(new URI("/hicc/home/apps.html"));
-      widget.setCol(3);
+      widget.setTitle("Node Managers Health");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/10"));
+      widget.setCol(9);
       widget.setRow(1);
       widget.setSize_x(2);
       widget.setSize_y(1);
+      createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("HDFS Usage");
       widget.setSrc(new URI("/hicc/v1/circles/draw/8"));
-      widget.setCol(5);
-      widget.setRow(1);
-      widget.setSize_x(1);
-      widget.setSize_y(1);
+      widget.setCol(1);
+      widget.setRow(2);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Namenode Memory");
       widget.setSrc(new URI("/hicc/v1/circles/draw/7"));
-      widget.setCol(6);
-      widget.setRow(1);
-      widget.setSize_x(1);
-      widget.setSize_y(1);
+      widget.setCol(3);
+      widget.setRow(2);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Resource Manager Memory");
       widget.setSrc(new URI("/hicc/v1/circles/draw/9"));
-      widget.setCol(7);
-      widget.setRow(1);
-      widget.setSize_x(1);
-      widget.setSize_y(1);
+      widget.setCol(5);
+      widget.setRow(2);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("HBase Master Memory");
-      widget.setSrc(new URI("/hicc/v1/circles/draw/10"));
-      widget.setCol(8);
-      widget.setRow(1);
-      widget.setSize_x(1);
-      widget.setSize_y(1);
+      widget.setSrc(new URI("/hicc/v1/circles/draw/15"));
+      widget.setCol(7);
+      widget.setRow(2);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("System Load Average");
       widget.setSrc(new URI("/hicc/v1/chart/draw/1"));
-      widget.setCol(1);
+      widget.setCol(9);
       widget.setRow(2);
-      widget.setSize_x(3);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("Disk Utilization");
-      widget.setSrc(new URI("/hicc/v1/chart/draw/4"));
-      widget.setCol(4);
-      widget.setRow(2);
-      widget.setSize_x(3);
-      widget.setSize_y(1);
-      createWidget(widget);
-      dashboard.add(widget);
-
-      widget = new Widget();
-      widget.setTitle("Timeline");
-      widget.setSrc(new URI("/hicc/timeline/"));
-      widget.setCol(7);
-      widget.setRow(2);
-      widget.setSize_x(4);
-      widget.setSize_y(6);
-      createWidget(widget);
-      dashboard.add(widget);
-
-      widget = new Widget();
       widget.setTitle("CPU Utilization");
       widget.setSrc(new URI("/hicc/v1/chart/draw/2"));
-      widget.setCol(1);
+      widget.setCol(9);
       widget.setRow(3);
-      widget.setSize_x(3);
-      widget.setSize_y(1);
-      createWidget(widget);
-      dashboard.add(widget);
-
-      widget = new Widget();
-      widget.setTitle("Network Utilization");
-      widget.setSrc(new URI("/hicc/v1/chart/draw/5"));
-      widget.setCol(4);
-      widget.setRow(3);
-      widget.setSize_x(3);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
@@ -1137,9 +1262,9 @@
       widget = new Widget();
       widget.setTitle("Memory Utilization");
       widget.setSrc(new URI("/hicc/v1/chart/draw/3"));
-      widget.setCol(1);
+      widget.setCol(9);
       widget.setRow(4);
-      widget.setSize_x(3);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
@@ -1147,13 +1272,33 @@
       widget = new Widget();
       widget.setTitle("Swap Utilization");
       widget.setSrc(new URI("/hicc/v1/chart/draw/6"));
-      widget.setCol(4);
-      widget.setRow(4);
-      widget.setSize_x(3);
+      widget.setCol(9);
+      widget.setRow(5);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
 
+      widget = new Widget();
+      widget.setTitle("Disk Utilization");
+      widget.setSrc(new URI("/hicc/v1/chart/draw/4"));
+      widget.setCol(1);
+      widget.setRow(4);
+      widget.setSize_x(4);
+      widget.setSize_y(2);
+      createWidget(widget);
+      dashboard.add(widget);
+
+      widget = new Widget();
+      widget.setTitle("Network Utilization");
+      widget.setSrc(new URI("/hicc/v1/chart/draw/5"));
+      widget.setCol(5);
+      widget.setRow(4);
+      widget.setSize_x(4);
+      widget.setSize_y(2);
+      createWidget(widget);
+      dashboard.add(widget);
+
       // CPU heatmap
       widget = new Widget();
       widget.setTitle("CPU Heatmap");
@@ -1163,52 +1308,73 @@
       widget.setSize_x(6);
       widget.setSize_y(5);
       createWidget(widget);
-      dashboard.add(widget);
 
+      // HDFS Namenode
       widget = new Widget();
-      widget.setTitle("Alerts");
-      widget.setSrc(new URI("/hicc/alerts/"));
+      widget.setTitle("HDFS UI");
+      widget.setSrc(new URI("http://localhost:50070/"));
       widget.setCol(1);
-      widget.setRow(5);
+      widget.setRow(11);
       widget.setSize_x(6);
-      widget.setSize_y(5);
+      widget.setSize_y(6);
       createWidget(widget);
 
+      // HBase Master
       widget = new Widget();
-      widget.setTitle("Log Errors");
-      widget.setSrc(new URI("/hicc/logs/"));
+      widget.setTitle("HBase Master UI");
+      widget.setSrc(new URI("http://localhost:16010/"));
       widget.setCol(1);
-      widget.setRow(5);
+      widget.setRow(18);
       widget.setSize_x(6);
-      widget.setSize_y(5);
+      widget.setSize_y(6);
       createWidget(widget);
 
-      widget = new Widget();
-      widget.setTitle("Web Stats");
-      widget.setSrc(new URI("https://birepo-internal.svl.ibm.com/awstats/awstats.pl?config=ibm-open-platform&framename=mainright&month=08&year=2015#month"));
-      widget.setCol(1);
-      widget.setRow(5);
-      widget.setSize_x(6);
-      widget.setSize_y(5);
-      createWidget(widget);
+//    widget = new Widget();
+//    widget.setTitle("Services Running");
+//    widget.setSrc(new URI("/hicc/services/services.html"));
+//    widget.setCol(1);
+//    widget.setRow(1);
+//    widget.setSize_x(2);
+//    widget.setSize_y(1);
+//    createWidget(widget);
+//    dashboard.add(widget);
+//    
+//    widget = new Widget();
+//    widget.setTitle("Applications Running");
+//    widget.setSrc(new URI("/hicc/home/apps.html"));
+//    widget.setCol(3);
+//    widget.setRow(1);
+//    widget.setSize_x(2);
+//    widget.setSize_y(1);
+//    dashboard.add(widget);
 
-      widget = new Widget();
-      widget.setTitle("Sessions");
-      widget.setSrc(new URI("https://birepo-internal.svl.ibm.com/awstats/awstats.pl?config=ibm-open-platform&framename=mainright&month=08&year=2015#sessions"));
-      widget.setCol(1);
-      widget.setRow(5);
-      widget.setSize_x(6);
-      widget.setSize_y(5);
-      createWidget(widget);
+//    widget = new Widget();
+//    widget.setTitle("Timeline");
+//    widget.setSrc(new URI("/hicc/timeline/"));
+//    widget.setCol(7);
+//    widget.setRow(2);
+//    widget.setSize_x(4);
+//    widget.setSize_y(6);
+//    createWidget(widget);
+//    dashboard.add(widget);
 
-      widget = new Widget();
-      widget.setTitle("Domains");
-      widget.setSrc(new URI("https://birepo-internal.svl.ibm.com/awstats/awstats.pl?config=ibm-open-platform&framename=mainright&month=08&year=2015#domains"));
-      widget.setCol(1);
-      widget.setRow(5);
-      widget.setSize_x(6);
-      widget.setSize_y(5);
-      createWidget(widget);
+//      widget = new Widget();
+//      widget.setTitle("Alerts");
+//      widget.setSrc(new URI("/hicc/alerts/"));
+//      widget.setCol(1);
+//      widget.setRow(5);
+//      widget.setSize_x(6);
+//      widget.setSize_y(5);
+//      createWidget(widget);
+//
+//      widget = new Widget();
+//      widget.setTitle("Log Errors");
+//      widget.setSrc(new URI("/hicc/logs/"));
+//      widget.setCol(1);
+//      widget.setRow(5);
+//      widget.setSize_x(6);
+//      widget.setSize_y(5);
+//      createWidget(widget);
 
       updateDashboard("system", "", dashboard);
       
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
index 987e405..16133f4 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
@@ -17,6 +17,9 @@
  */
 package org.apache.hadoop.chukwa.hicc.rest;
 
+import java.io.StringWriter;
+import java.util.Set;
+
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -24,6 +27,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.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -31,7 +35,15 @@
 
 import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore;
 import org.apache.hadoop.chukwa.hicc.bean.Dashboard;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.log4j.Logger;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
 
 import com.google.gson.Gson;
 
@@ -41,6 +53,9 @@
 
   @Context
   private ServletContext context;
+  @Context
+  VelocityEngine velocity;
+
   
   @GET
   @Path("load/{id}")
@@ -69,4 +84,57 @@
   public String whoami(@Context HttpServletRequest request) {
     return request.getRemoteUser();
   }
+  
+  @GET
+  @Path("quicklinks")
+  @Produces(MediaType.TEXT_HTML)
+  public String quicklinks() {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    Configuration hconf = HBaseConfiguration.create();
+    Configuration hadoop = new Configuration();
+    String nn = "";
+    String rm = "";
+    String hm = "";
+    Set<String> sourceNames = ChukwaHBaseStore.getSourceNames("");
+    for (String source : sourceNames) {
+      String[] sourceParts = source.split(":");
+      if(sourceParts.length<2) {
+        continue;
+      }
+      if(sourceParts[1].equals("NameNode")) {
+        String[] parts = hadoop.get(DFSConfigKeys.DFS_NAMENODE_HTTP_ADDRESS_KEY).split(":");
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(sourceParts[0]);
+        buffer.append(":");
+        buffer.append(parts[1]);
+        nn = buffer.toString();
+      } else if(sourceParts[1].equals("ResourceManager")) {
+        String[] parts = hadoop.get(YarnConfiguration.RM_WEBAPP_ADDRESS).split(":");
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(sourceParts[0]);
+        buffer.append(":");
+        buffer.append(parts[1]);
+        rm = buffer.toString();
+      } else if(sourceParts[1].equals("Master")) {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(sourceParts[0]);
+        buffer.append(":");
+        buffer.append(hconf.getInt("hbase.master.info.port", HConstants.DEFAULT_MASTER_INFOPORT));
+        hm = buffer.toString();
+      }
+    }
+    try {
+      context.put("nn", nn);
+      context.put("rm", rm);
+      context.put("hm", hm);
+      Template template = velocity.getTemplate("quick-links.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
 }
diff --git a/src/main/web/hicc/WEB-INF/vm/quick-links.vm b/src/main/web/hicc/WEB-INF/vm/quick-links.vm
new file mode 100644
index 0000000..fd6bf9b
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/quick-links.vm
@@ -0,0 +1,63 @@
+<!--
+   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.
+-->
+<!DOCTYPE html>
+<html lang="en" class="no-js">
+  <head>
+    <link href="/hicc/css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
+    <link href="/hicc/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+    <script src="/hicc/js/jquery.js" type="text/javascript"></script>
+    <script src="/hicc/js/bootstrap.min.js" type="text/javascript"></script>
+    <style>
+      html, body, .row, .container {
+        height: 100%;
+        min-height: 100%;
+      }
+      .menu {
+        float:left;
+        height: 95%;
+      }
+      .main {
+        float:left;
+        height: 95%;
+      }
+      iframe {
+        border: 0px none transparent;
+        width: 100%;
+        height: 100%;
+      }
+      .container {
+        width: 100%;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="container">
+      <div class="row">
+        <div class="menu col-md-2 col-lg-2">
+          <h1>Quick Links</h1>
+          <p><a href="http://$nn/explorer.html#/" target="link_target">Browse File System</a></p>
+          <p><a href="http://$hm/tablesDetailed.jsp" target="link_target">Browse HBase Tables</a></p>
+          <p><a href="http://$rm/" target="link_target">Browse Hadoop Applications</a></p>
+          <p><a href="/hicc/ajax-solr/chukwa/" target="link_target">Search Log Files</a></p>
+        </div>
+        <div class="main col-md-10 col-lg-10">
+          <iframe id="link_target" src="/hicc/ajax-solr/chukwa/" width="100%" height="100%"></iframe>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/src/main/web/hicc/home/css/component.css b/src/main/web/hicc/home/css/component.css
index 9b4bcec..1d4d53e 100755
--- a/src/main/web/hicc/home/css/component.css
+++ b/src/main/web/hicc/home/css/component.css
@@ -243,10 +243,10 @@
 		user-select: none;
 }
 
-.gn-menu-main > li:nth-last-child(2) {
+.gn-menu-main > li:nth-last-child(3) {
 		padding-right: 10px;
                 position: absolute;
-		right: 82px;
+		right: 164px;
 		overflow: hidden;
 		float: left;
 		border-left: none;
@@ -254,7 +254,7 @@
 		white-space: nowrap;
 }
 
-.gn-menu-main > li:last-child {
+.gn-menu-main > li:nth-last-child(-n+2) {
 		width: 82px;
 		float: right;
 		border-right: none;
@@ -457,6 +457,12 @@
 		content: "\e017";
 }
 
+.gn-icon-fullscreen::before {
+		font-family: 'Glyphicons Halflings';
+		font-size: 18px;
+		content: "\e140";
+}
+
 .gn-icon-home::before {
 		font-family: 'Glyphicons Halflings';
 		font-size: 18px;
diff --git a/src/main/web/hicc/home/index.html b/src/main/web/hicc/home/index.html
index b7ed0a1..828c291 100755
--- a/src/main/web/hicc/home/index.html
+++ b/src/main/web/hicc/home/index.html
@@ -72,6 +72,7 @@
         </li>
         <li><span id="username"></span></li>
         <li><a class="gn-icon-poweroff" onclick="logout()"><span> </span></a></li>
+        <li><a class="gn-icon-fullscreen" onclick="toggleFullScreen()"><span> </span></a></li>
       </ul>
     </div><!-- /container -->
     <div class="gridster">
@@ -111,6 +112,32 @@
   };
 };
 
+function toggleFullScreen() {
+  var element = document.documentElement;
+  if(document.fullscreenElement ||
+	document.webkitFullscreenElement ||
+	document.mozFullScreenElement ||
+	document.msFullscreenElement) {
+    if(document.exitFullscreen) {
+      document.exitFullscreen();
+    } else if(document.mozCancelFullScreen) {
+      document.mozCancelFullScreen();
+    } else if(document.webkitExitFullscreen) {
+      document.webkitExitFullscreen();
+    }
+  } else {
+    if(element.requestFullscreen) {
+      element.requestFullscreen();
+    } else if(element.mozRequestFullScreen) {
+      element.mozRequestFullScreen();
+    } else if(element.webkitRequestFullscreen) {
+      element.webkitRequestFullscreen();
+    } else if(element.msRequestFullscreen) {
+      element.msRequestFullscreen();
+    }
+  }
+}
+
 function toggleGlass() {
   $('#glass').toggle();
 }