You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by ve...@apache.org on 2013/11/14 00:58:14 UTC

[1/2] git commit: FALCON-190 Entity list REST API should allow the client to query different fields. Contributed by Haohui Mai

Updated Branches:
  refs/heads/master bf63dbf19 -> 9e376c20e


FALCON-190 Entity list REST API should allow the client to query different fields. Contributed by Haohui Mai


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

Branch: refs/heads/master
Commit: 7de95ad78a0a8b3b2a7e856ba488d2b57a749aed
Parents: bf63dbf
Author: Venkatesh Seetharam <ve...@apache.org>
Authored: Wed Nov 13 15:52:23 2013 -0800
Committer: Venkatesh Seetharam <ve...@apache.org>
Committed: Wed Nov 13 15:52:23 2013 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |  3 ++
 .../falcon/resource/AbstractEntityManager.java  | 26 +++++++---
 .../proxy/SchedulableEntityManagerProxy.java    |  5 +-
 .../resource/SchedulableEntityManager.java      |  5 +-
 .../falcon/resource/EntityManagerJerseyIT.java  | 53 ++++++++++++++------
 5 files changed, 64 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/7de95ad7/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8dfb5b9..226e0f0 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -78,6 +78,9 @@ Trunk (Unreleased)
 
   IMPROVEMENTS
 
+    FALCON-190 Entity list REST API should allow the client to
+    query different fields (Haohui Mai via Venkatesh Seetharam)
+
     FALCON-188 hadoop-2 profile is not carried through to
     oozie package (Haohui Mai via Venkatesh Seetharam)
 

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/7de95ad7/prism/src/main/java/org/apache/falcon/resource/AbstractEntityManager.java
----------------------------------------------------------------------
diff --git a/prism/src/main/java/org/apache/falcon/resource/AbstractEntityManager.java b/prism/src/main/java/org/apache/falcon/resource/AbstractEntityManager.java
index c899407..7ec6cd1 100644
--- a/prism/src/main/java/org/apache/falcon/resource/AbstractEntityManager.java
+++ b/prism/src/main/java/org/apache/falcon/resource/AbstractEntityManager.java
@@ -436,9 +436,17 @@ public abstract class AbstractEntityManager {
      * Returns the list of entities registered of a given type.
      *
      * @param type entity type
+     * @param fieldStr fields that the query is interested in, separated by comma
+     *
+     * @param type entity type
      * @return String
      */
-    public EntityList getDependencies(String type) {
+    public EntityList getEntityList(String type, String fieldStr) {
+        HashSet<String> fields = new HashSet<String>(Arrays.asList(fieldStr.split(",")));
+
+        // Currently only the status of the entity is supported
+        boolean requireStatus = fields.contains("status");
+
         try {
             EntityType entityType = EntityType.valueOf(type.toUpperCase());
             final String entityTypeString = type.toLowerCase();
@@ -456,14 +464,16 @@ public abstract class AbstractEntityManager {
                 EntityList.EntityElement elem = new EntityList.EntityElement();
                 elem.name = e.getName();
                 elem.type = entityTypeString;
-                String statusString;
-                try {
-                    EntityStatus status = getStatus(e, entityType);
-                    statusString = status.name();
-                } catch (FalconException e1) {
-                    statusString = "UNKNOWN";
+                if (requireStatus) {
+                    String statusString;
+                    try {
+                        EntityStatus status = getStatus(e, entityType);
+                        statusString = status.name();
+                    } catch (FalconException e1) {
+                        statusString = "UNKNOWN";
+                    }
+                    elem.status = statusString;
                 }
-                elem.status = statusString;
                 elements[i++] = elem;
             }
             return new EntityList(elements);

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/7de95ad7/prism/src/main/java/org/apache/falcon/resource/proxy/SchedulableEntityManagerProxy.java
----------------------------------------------------------------------
diff --git a/prism/src/main/java/org/apache/falcon/resource/proxy/SchedulableEntityManagerProxy.java b/prism/src/main/java/org/apache/falcon/resource/proxy/SchedulableEntityManagerProxy.java
index 0b6b34a..8ba2a97 100644
--- a/prism/src/main/java/org/apache/falcon/resource/proxy/SchedulableEntityManagerProxy.java
+++ b/prism/src/main/java/org/apache/falcon/resource/proxy/SchedulableEntityManagerProxy.java
@@ -283,8 +283,9 @@ public class SchedulableEntityManagerProxy extends AbstractSchedulableEntityMana
     @Path("list/{type}")
     @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
     @Override
-    public EntityList getDependencies(@PathParam("type") String type) {
-        return super.getDependencies(type);
+    public EntityList getEntityList(@PathParam("type") String type,
+                                    @DefaultValue("") @QueryParam("fields") String fields) {
+        return super.getEntityList(type, fields);
     }
 
     @GET

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/7de95ad7/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java b/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
index b17dcc8..3c9078d 100644
--- a/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
+++ b/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
@@ -58,8 +58,9 @@ public class SchedulableEntityManager extends AbstractSchedulableEntityManager {
     @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
     @Monitored(event = "dependencies")
     @Override
-    public EntityList getDependencies(@Dimension("type") @PathParam("type") String type) {
-        return super.getDependencies(type);
+    public EntityList getEntityList(@Dimension("type") @PathParam("type") String type,
+                                    @DefaultValue("") @QueryParam("fields") String fields) {
+        return super.getEntityList(type, fields);
     }
 
     @GET

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/7de95ad7/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java b/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
index 767ff4b..cb2fcbb 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
@@ -79,7 +79,7 @@ public class EntityManagerJerseyIT {
     public void testLibExtensions() throws Exception {
         TestContext context = newContext();
         Map<String, String> overlay = context.getUniqueOverlay();
-        ClientResponse response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        ClientResponse response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
         FileSystem fs = context.getCluster().getFileSystem();
         assertLibs(fs, new Path("/project/falcon/working/libext/FEED/retention"));
@@ -296,7 +296,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.submitToFalcon(TestContext.FEED_TEMPLATE1, overlay, EntityType.FEED);
@@ -319,10 +319,10 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
     }
 
@@ -382,7 +382,7 @@ public class EntityManagerJerseyIT {
         Map<String, String> overlay = context.getUniqueOverlay();
 
         InputStream stream = context.getServletInputStream(
-                context.overlayParametersOverTemplate(context.CLUSTER_TEMPLATE, overlay));
+                context.overlayParametersOverTemplate(TestContext.CLUSTER_TEMPLATE, overlay));
 
         clientRepsonse = context.service.path("api/entities/validate/cluster")
                 .accept(MediaType.TEXT_XML).type(MediaType.TEXT_XML)
@@ -397,7 +397,7 @@ public class EntityManagerJerseyIT {
         ClientResponse clientRepsonse;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        clientRepsonse = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay,
+        clientRepsonse = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay,
                 EntityType.CLUSTER);
         context.assertSuccessful(clientRepsonse);
 
@@ -435,7 +435,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.submitToFalcon(TestContext.FEED_TEMPLATE1, overlay, EntityType.FEED);
@@ -454,7 +454,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.submitToFalcon(TestContext.FEED_TEMPLATE1, overlay, EntityType.FEED);
@@ -509,7 +509,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.submitToFalcon(TestContext.FEED_TEMPLATE1, overlay, EntityType.FEED);
@@ -580,7 +580,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.submitToFalcon(TestContext.FEED_TEMPLATE1, overlay, EntityType.FEED);
@@ -599,7 +599,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response;
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.submitToFalcon(TestContext.FEED_TEMPLATE1, overlay, EntityType.FEED);
@@ -650,7 +650,7 @@ public class EntityManagerJerseyIT {
     }
 
     @Test
-    public void testGetDependencies() throws Exception {
+    public void testGetEntityList() throws Exception {
         TestContext context = newContext();
         ClientResponse response;
         response = context.service
@@ -660,14 +660,35 @@ public class EntityManagerJerseyIT {
         Assert.assertEquals(response.getStatus(), 200);
 
         Map<String, String> overlay = context.getUniqueOverlay();
-
-        response = context.submitToFalcon(context.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
+        overlay.put("cluster", "WTF-" + overlay.get("cluster"));
+        response = context.submitToFalcon(TestContext.CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         context.assertSuccessful(response);
 
         response = context.service
                 .path("api/entities/list/cluster/")
-                .header("Remote-User", TestContext.REMOTE_USER).type(MediaType.TEXT_XML)
-                .accept(MediaType.TEXT_XML).get(ClientResponse.class);
+                .header("Remote-User", TestContext.REMOTE_USER)
+                .type(MediaType.TEXT_XML)
+                .accept(MediaType.TEXT_XML)
+                .get(ClientResponse.class);
         Assert.assertEquals(response.getStatus(), 200);
+        EntityList result = response.getEntity(EntityList.class);
+        Assert.assertNotNull(result);
+        for (EntityList.EntityElement entityElement : result.getElements()) {
+            Assert.assertNull(entityElement.status); // status is null
+        }
+
+        response = context.service
+                .path("api/entities/list/cluster/")
+                .queryParam("fields", "status")
+                .header("Remote-User", TestContext.REMOTE_USER)
+                .type(MediaType.APPLICATION_JSON)
+                .accept(MediaType.APPLICATION_JSON)
+                .get(ClientResponse.class);
+        Assert.assertEquals(response.getStatus(), 200);
+        result = response.getEntity(EntityList.class);
+        Assert.assertNotNull(result);
+        for (EntityList.EntityElement entityElement : result.getElements()) {
+            Assert.assertNotNull(entityElement.status); // status is null
+        }
     }
 }


[2/2] git commit: Dashboard related changes: FALCON-164 Provide Falcon Web UI. Contributed by Haohui Mai FALCON-178 Implement client-side pagination. Contributed by Haohui Mai FALCON-175 Visualize dependency information. Contributed by Haohui Mai FALCON-

Posted by ve...@apache.org.
Dashboard related changes:
FALCON-164 Provide Falcon Web UI. Contributed by Haohui Mai
FALCON-178 Implement client-side pagination. Contributed by Haohui Mai
FALCON-175 Visualize dependency information. Contributed by Haohui Mai
FALCON-193 Update the documentation for dashboard. Contributed by Haohui Mai


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

Branch: refs/heads/master
Commit: 9e376c20e3d9fa449c0ea10310d9fb396cf62223
Parents: 7de95ad
Author: Venkatesh Seetharam <ve...@apache.org>
Authored: Wed Nov 13 15:57:48 2013 -0800
Committer: Venkatesh Seetharam <ve...@apache.org>
Committed: Wed Nov 13 15:57:48 2013 -0800

----------------------------------------------------------------------
 CHANGES.txt                                    |  14 +-
 docs/src/site/twiki/InstallationSteps.twiki    |   4 +
 docs/src/site/twiki/restapi/EntityList.twiki   |  27 +-
 docs/src/site/twiki/restapi/ResourceList.twiki |   2 +-
 html5-ui/css/falcon.css                        | 138 +++++++++++
 html5-ui/entity.html                           | 110 ++++++++
 html5-ui/img/falcon-114.png                    | Bin 0 -> 17181 bytes
 html5-ui/img/falcon-144.png                    | Bin 0 -> 23857 bytes
 html5-ui/img/falcon-57.png                     | Bin 0 -> 8036 bytes
 html5-ui/img/falcon-64.png                     | Bin 0 -> 8020 bytes
 html5-ui/img/falcon-72.png                     | Bin 0 -> 9276 bytes
 html5-ui/img/falcon.png                        | Bin 0 -> 12349 bytes
 html5-ui/img/falcon.xcf                        | Bin 0 -> 42007 bytes
 html5-ui/img/favicon.png                       | Bin 0 -> 8020 bytes
 html5-ui/index.html                            |  74 ++++++
 html5-ui/js/falcon-entity.js                   | 262 ++++++++++++++++++++
 html5-ui/js/falcon-index.js                    | 107 ++++++++
 html5-ui/js/falcon.js                          | 139 +++++++++++
 pom.xml                                        |   1 +
 prism/pom.xml                                  |   7 +-
 webapp/pom.xml                                 |  15 +-
 21 files changed, 890 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 226e0f0..182e504 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -5,7 +5,19 @@ Trunk (Unreleased)
   INCOMPATIBLE CHANGES
 
   NEW FEATURES
-  
+
+    FALCON-193 Update the documentation to reflect the current
+    work of dashboard (Haohui Mai via Venkatesh Seetharam)
+
+    FALCON-175 Visualize dependency information
+    (Haohui Mai via Venkatesh Seetharam)
+
+    FALCON-178 Implement client-side pagination
+    (Haohui Mai via Venkatesh Seetharam)
+
+    FALCON-164 Provide Falcon Web UI
+    (Haohui Mai via Venkatesh Seetharam)
+
     FALCON-85 Hive (HCatalog) integration. (Venkatesh Seetharam
     via Srikanth Sundarrajan)
 

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/docs/src/site/twiki/InstallationSteps.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/InstallationSteps.twiki b/docs/src/site/twiki/InstallationSteps.twiki
index 223242b..e396747 100644
--- a/docs/src/site/twiki/InstallationSteps.twiki
+++ b/docs/src/site/twiki/InstallationSteps.twiki
@@ -202,6 +202,10 @@ bin/falcon help
 (for more details about falcon cli usage)
 </verbatim>
 
+*Dashboard*
+
+Once falcon / prism is started, you can view the status of falcon entities using the Web-based dashboard. The web UI works in both distributed and embedded mode. You can open your browser at the corresponding port to use the web UI.
+
 *Stopping Falcon Server*
 <verbatim>
 bin/falcon-stop

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/docs/src/site/twiki/restapi/EntityList.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/restapi/EntityList.twiki b/docs/src/site/twiki/restapi/EntityList.twiki
index 45416ad..bca84b0 100644
--- a/docs/src/site/twiki/restapi/EntityList.twiki
+++ b/docs/src/site/twiki/restapi/EntityList.twiki
@@ -1,4 +1,4 @@
----++  GET /api/entities/list/:entity-type
+---++  GET /api/entities/list/:entity-type?fields=:fields
    * <a href="#Description">Description</a>
    * <a href="#Parameters">Parameters</a>
    * <a href="#Results">Results</a>
@@ -9,6 +9,8 @@ Get list of the entities.
 
 ---++ Parameters
    * :entity-type can be cluster, feed or process.
+   * :fields (optional) additional fields that the client are interested in, separated by commas.
+     Currently falcon only support status as a valid field.
 
 ---++ Results
 List of the entities.
@@ -35,3 +37,26 @@ Remote-User: rgautam
 }
 </verbatim>
 
+---+++ Rest Call
+<verbatim>
+GET http://localhost:15000/api/entities/list/feed?fields=status
+Remote-User: rgautam
+</verbatim>
+---+++ Result
+<verbatim>
+{
+    "entity": [
+        {
+            "name"  : "SampleOutput",
+            "type"  : "feed",
+            "status": "RUNNING"
+        },
+        {
+            "name": "SampleInput",
+            "type": "feed",
+            "status": "RUNNING"
+        }
+    ]
+}
+</verbatim>
+

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/docs/src/site/twiki/restapi/ResourceList.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/restapi/ResourceList.twiki b/docs/src/site/twiki/restapi/ResourceList.twiki
index f17cb1a..b9ec4b6 100644
--- a/docs/src/site/twiki/restapi/ResourceList.twiki
+++ b/docs/src/site/twiki/restapi/ResourceList.twiki
@@ -23,7 +23,7 @@
 | DELETE      | [[EntityDelete][api/entities/delete/:entity-type/:entity-name]]             | Delete the entity                  |
 | GET         | [[EntityStatus][api/entities/status/:entity-type/:entity-name]]             | Get the status of the entity       |
 | GET         | [[EntityDefinition][api/entities/definition/:entity-type/:entity-name]]     | Get the definition of the entity   |
-| GET         | [[EntityList][api/entities/list/:entity-type]]                              | Get the list of entities           |
+| GET         | [[EntityList][api/entities/list/:entity-type?fields=:fields]]               | Get the list of entities           |
 | GET         | [[EntityDependencies][api/entities/dependencies/:entity-type/:entity-name]] | Get the dependencies of the entity |
 
 ---++ REST Call on Feed and Process Instances

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/css/falcon.css
----------------------------------------------------------------------
diff --git a/html5-ui/css/falcon.css b/html5-ui/css/falcon.css
new file mode 100644
index 0000000..f72b1ad
--- /dev/null
+++ b/html5-ui/css/falcon.css
@@ -0,0 +1,138 @@
+/*
+* 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.
+*/
+
+.falcon-brand {
+  padding-left: 40px;
+  background-image: url('../img/falcon-64.png');
+  background-size: 40px 40px;
+  background-repeat: no-repeat;
+  background-position: left center;
+}
+
+.btn-entity-list {
+  cursor: pointer;
+}
+
+.link-icons:before {
+  position: relative;
+  display: inline-block;
+  font-family: 'Glyphicons Halflings';
+  -webkit-font-smoothing: antialiased;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  padding-right: 0.4em;
+  vertical-align: -20%;
+  font-size: 120%;
+}
+
+.entity-title:before {
+  color: #428bca;
+  vertical-align: -20%;
+}
+
+.entity-link-cluster:before {
+  content: "\2601";
+}
+
+.entity-link-process:before {
+  content: "\e110";
+}
+
+.entity-link-feed:before {
+  content: "\e181";
+}
+
+#entity-paginator {
+  text-align: right;
+}
+
+.instance-icons:before {
+  position: relative;
+  display: inline-block;
+  font-family: 'Glyphicons Halflings';
+  -webkit-font-smoothing: antialiased;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  padding-right: 0.3em;
+  font-size: 100%;
+  vertical-align: top;
+}
+
+.instance-link-SUCCEEDED:before {
+  color: green;
+  content: "\e013";
+}
+
+.instance-link-RUNNING:before {
+  color: green;
+  content: "\e072";
+}
+
+.instance-link-WAITING:before {
+  color: orange;
+  content: "\e023";
+}
+
+.instance-link-FAILED:before {
+  color: red;
+  content: "\e014";
+}
+
+.node-name:before {
+  font-family: 'Glyphicons Halflings';
+  -webkit-font-smoothing: antialiased;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  padding-right: 0.3em;
+  vertical-align: -20%;
+  font-size: 110%;
+  color: #428bca;
+}
+
+.node-name-cluster:before {
+  content: "\2601";
+}
+
+.node-name-process:before {
+  content: "\e110";
+}
+
+.node-name-feed:before {
+  content: "\e181";
+}
+
+.node rect {
+  stroke-width: 0.5px;
+  stroke: #999;
+  fill: #ffffff;
+  fill-opacity: 80%;
+}
+
+.edge path {
+  fill: none;
+  stroke: #333;
+  stroke-width: 1px;
+}
+
+.node-name {
+  vertical-align: middle;
+  margin: 10px;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/entity.html
----------------------------------------------------------------------
diff --git a/html5-ui/entity.html b/html5-ui/entity.html
new file mode 100644
index 0000000..1032187
--- /dev/null
+++ b/html5-ui/entity.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!--
+   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.
+-->
+<meta charset="utf-8" />
+<title>Apache Falcon</title>
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta name="description" content="" />
+<meta name="author" content="" />
+<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+<link href="css/falcon.css" type="text/css" rel="stylesheet" />
+<link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/falcon-144.png" />
+<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/falcon-114.png" />
+<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/falcon-72.png" />
+<link rel="apple-touch-icon-precomposed" href="img/falcon-57.png" />
+<link rel="shortcut icon" href="img/favicon.png" />
+</head>
+<body>
+<div class="navbar navbar-default">
+<div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=
+".navbar-collapse"></button> <a class="navbar-brand falcon-brand">Falcon Server</a></div>
+<div class="navbar-collapse navbar-right collapse">
+<ul class="nav navbar-nav">
+<li><a class="btn-entity-list" href="index.html?type=feed">Data sets</a></li>
+<li><a class="btn-entity-list" href="index.html?type=process">Processes</a></li>
+<li><a class="btn-entity-list" href="index.html?type=cluster">Clusters</a></li>
+</ul>
+</div>
+</div>
+<div class="container">
+
+<h3 class="link-icons entity-title" id="entity-title"></h3>
+<br />
+<div id="entity-info-container">
+<div class="panel panel-default" id="panel-instance" style="display:none">
+<div class="panel-heading">Instances</div>
+<div class="panel-body"></div>
+</div>
+<div class="panel panel-default" id="panel-definition">
+<div class="panel-heading">Definition</div>
+<div class="panel-body"> <textarea class="form-control" id="entity-def-textarea"></textarea></div>
+</div>
+<div class="panel panel-default" id="panel-dependency" style="display:none">
+<div class="panel-heading">
+Dependency
+</div>
+<div class="panel-body">
+<div id="dep-view-list" style="display:none"></div>
+<div id="dep-view-graph" style="display:none"></div>
+</div>
+<div class="panel-footer">
+<div class="btn-group">
+<button class="btn btn-primary" id="btn-dep-list">List view</button>
+<button class="btn btn-default" id="btn-dep-graph">Graph view</button>
+</div>
+</div>
+</div>
+</div>
+<hr />
+<div class="footer">&#169; Apache Falcon, 2013</div>
+</div>
+<!-- /container -->
+<script id="dependency-tmpl" type="text/x-dust-template">
+<table class="table table-bordered">
+  <tbody>
+    {#entity}
+    <tr><td><a class="link-icons entity-link-{type}" href="entity.html?type={type}&id={name}">{name}</a></td></tr>
+    {/entity}
+  </tbody>
+</table>
+</script><script id="instance-tmpl" type="text/x-dust-template">
+<table class="table">
+  <tbody>
+    {#instances}
+    <tr>
+      <td><span class="instance-icons instance-link-{status}"></span> {instance}</td>
+      <td style="width: 6em; text-align: right">
+        {?logFile}<a href="{logFile}" target="_blank">Logs</a>{/logFile}
+        {?details}<a style="cursor: pointer" class="instance-hdfs-log" data-toggle="tooltip" data-title="<div style='word-break:break-all;'>Log available at {details}</div>" data-html="true" data-trigger="click"><span class="glyphicon glyphicon-export"></span></a>{/details}
+      </td>
+    </tr>
+    {/instances}
+  </tbody>
+</table>
+</script><script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript">
+</script><script src="//netdna.bootstrapcdn.com/bootstrap/3.0.1/js/bootstrap.min.js" type="text/javascript">
+</script><script src="//cdnjs.cloudflare.com/ajax/libs/dustjs-linkedin/2.0.0/dust-full.min.js" type="text/javascript">
+</script><script src="http://d3js.org/d3.v3.min.js" charset="utf-8">
+</script><script src="//cpettitt.github.io/project/dagre/latest/dagre.min.js" type="text/javascript">
+</script><script src="js/falcon.js" type="text/javascript">
+</script><script src="js/falcon-entity.js" type="text/javascript">
+</script>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon-114.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon-114.png b/html5-ui/img/falcon-114.png
new file mode 100644
index 0000000..8185dde
Binary files /dev/null and b/html5-ui/img/falcon-114.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon-144.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon-144.png b/html5-ui/img/falcon-144.png
new file mode 100644
index 0000000..0b4cc00
Binary files /dev/null and b/html5-ui/img/falcon-144.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon-57.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon-57.png b/html5-ui/img/falcon-57.png
new file mode 100644
index 0000000..f5643c6
Binary files /dev/null and b/html5-ui/img/falcon-57.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon-64.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon-64.png b/html5-ui/img/falcon-64.png
new file mode 100644
index 0000000..bda8906
Binary files /dev/null and b/html5-ui/img/falcon-64.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon-72.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon-72.png b/html5-ui/img/falcon-72.png
new file mode 100644
index 0000000..4f4bc20
Binary files /dev/null and b/html5-ui/img/falcon-72.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon.png b/html5-ui/img/falcon.png
new file mode 100644
index 0000000..be66974
Binary files /dev/null and b/html5-ui/img/falcon.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/falcon.xcf
----------------------------------------------------------------------
diff --git a/html5-ui/img/falcon.xcf b/html5-ui/img/falcon.xcf
new file mode 100644
index 0000000..4bc14b8
Binary files /dev/null and b/html5-ui/img/falcon.xcf differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/img/favicon.png
----------------------------------------------------------------------
diff --git a/html5-ui/img/favicon.png b/html5-ui/img/favicon.png
new file mode 100644
index 0000000..bda8906
Binary files /dev/null and b/html5-ui/img/favicon.png differ

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/index.html
----------------------------------------------------------------------
diff --git a/html5-ui/index.html b/html5-ui/index.html
new file mode 100644
index 0000000..47f2a3b
--- /dev/null
+++ b/html5-ui/index.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!--
+   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.
+-->
+<meta charset="utf-8" />
+<title>Apache Falcon</title>
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta name="description" content="" />
+<meta name="author" content="" />
+<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+<link href="css/falcon.css" type="text/css" rel="stylesheet" />
+<link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/falcon-144.png" />
+<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/falcon-114.png" />
+<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/falcon-72.png" />
+<link rel="apple-touch-icon-precomposed" href="img/falcon-57.png" />
+<link rel="shortcut icon" href="img/favicon.png" />
+</head>
+<body>
+<div class="navbar navbar-default">
+<div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=
+".navbar-collapse"></button> <a class="navbar-brand falcon-brand">Falcon Server</a></div>
+<div class="navbar-collapse navbar-right collapse">
+<ul class="nav navbar-nav">
+<li><a class="btn-entity-list" data-entity-type="feed" href="index.html?type=feed">Data sets</a></li>
+<li><a class="btn-entity-list" data-entity-type="process" href="index.html?type=process">Processes</a></li>
+<li><a class="btn-entity-list" data-entity-type="cluster" href="index.html?type=cluster">Clusters</a></li>
+</ul>
+</div>
+</div>
+<div class="container">
+<div id="entity-list-container"></div>
+<div id="entity-paginator"></div>
+<hr />
+<div class="footer">&#169; Apache Falcon, 2013</div>
+</div>
+<!-- /container -->
+<script id="entity-list-tmpl" type="text/x-dust-template">
+<table class="table table-striped table-bordered" id="entity-list">
+  <thead>
+    <th>Name</th><th style="width:10em; text-align: center">Status</th>
+  </thead>
+  <tbody>
+    {#entity}
+    <tr>
+      <td><a class="link-icons entity-link-{type}" href="entity.html?type={type}&id={name}">{name}</a></td>
+      <td style="text-align: center">{status}</td>
+    </tr>
+    {/entity}
+  </tbody>
+</table>
+</script><script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript">
+</script><script src="//netdna.bootstrapcdn.com/bootstrap/3.0.1/js/bootstrap.min.js" type="text/javascript">
+</script><script src="//cdnjs.cloudflare.com/ajax/libs/dustjs-linkedin/2.0.0/dust-full.min.js" type="text/javascript">
+</script><script src="js/falcon.js" type="text/javascript">
+</script><script src="js/falcon-index.js" type="text/javascript">
+</script>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/js/falcon-entity.js
----------------------------------------------------------------------
diff --git a/html5-ui/js/falcon-entity.js b/html5-ui/js/falcon-entity.js
new file mode 100644
index 0000000..de2eae5
--- /dev/null
+++ b/html5-ui/js/falcon-entity.js
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+(function(falcon, dust) {
+  var TYPE_MAP = {
+    "feed": "Data set",
+    "process": "Process",
+    "cluster": "Cluster"
+  };
+
+  dust.loadSource(dust.compile($('#dependency-tmpl').html(), 'dependency'));
+  dust.loadSource(dust.compile($('#instance-tmpl').html(), 'instance'));
+
+  var entityType = (/type=(.+?)(&|$)/.exec(location.search)||[,null])[1];
+  var entityId = (/id=(.+?)(&|$)/.exec(location.search)||[,null])[1];
+
+  function url(type) {
+    return 'api/' + type + '/' + entityType + '/' + entityId;
+  }
+
+  $('#breadcrumb-type').text(TYPE_MAP[entityType]);
+  $('#entity-title').addClass('entity-link-' + entityType)
+    .text(entityId + ' ')
+    .append('<span class="label label-success">' + TYPE_MAP[entityType] + '</span>');
+
+  function switchDependencyView(to_shown) {
+    var orig = to_shown === 'list' ? 'graph' : 'list';
+    $('#dep-view-' + orig).hide();
+    $('#btn-dep-' + orig).addClass('btn-default').removeClass('btn-primary');
+    $('#dep-view-' + to_shown).show();
+    $('#btn-dep-' + to_shown).addClass('btn-primary').removeClass('btn-default');
+  }
+
+  function loadInstance(start, end) {
+    falcon.getJson(url('instance/status') + '?start=' + start + '&end=' + end, function (data) {
+      if (data.instances == null)
+        return;
+
+      if (!($.isArray(data.instances)))
+        data.instances = new Array(data.instances);
+
+      dust.render('instance', data, function(err, out) {
+        $('#panel-instance > .panel-body').html(out);
+        $('.instance-hdfs-log').tooltip();
+        $('#panel-instance').show();
+      });
+    });
+  }
+
+  function loadDependency() {
+    falcon.getJson(url('entities/dependencies'), function (data) {
+      if (data.entity == null)
+        return;
+
+      if (!($.isArray(data.entity)))
+        data.entity = new Array(data.entity);
+
+      data.entity.sort(function(l,r) {
+        var a = l.type, b = r.type;
+        return a < b ? -1 : (a > b ? 1 : 0);
+      });
+
+      dust.render('dependency', data, function(err, out) {
+        $('#dep-view-list').html(out);
+        switchDependencyView('list');
+        $('#panel-dependency').show();
+      });
+    });
+  }
+
+  function load() {
+    var isCluster = entityType === 'cluster';
+
+    falcon.getText(url('entities/definition'), function (data) {
+      $('#entity-def-textarea')
+        .attr('rows', data.match(/\n/g).length + 1)
+        .text(data);
+
+      if (!isCluster) {
+        var xml = $.parseXML(data);
+        var e = $(xml).find('validity');
+        if (e != null) {
+          loadInstance(e.attr('start'), e.attr('end'));
+        }
+      }
+    });
+
+    if (!isCluster) {
+      loadDependency();
+    }
+  }
+
+  /**
+   * Plot dependency graph in SVG format
+   **/
+  function plotDependencyGraph(nodes, svg) {
+    var NODE_WIDTH  = 150;
+    var NODE_HEIGHT = 60;
+    var RECT_ROUND  = 5;
+    var SEPARATION  = 40;
+
+    // Function to draw the lines of the edge
+    var LINE_FUNCTION = d3.svg.line()
+      .x(function(d) { return d.x; })
+      .y(function(d) { return d.y; })
+      .interpolate('basis');
+
+    // Mappining from id to a node
+    var node_by_id = {};
+
+    var layout = null;
+
+    /**
+     * Calculate the intersection point between the point p and the edges of the rectangle rect
+     **/
+    function intersectRect(rect, p) {
+      var cx = rect.x, cy = rect.y, dx = p.x - cx, dy = p.y - cy, w = rect.width / 2, h = rect.height / 2;
+
+      if (dx == 0)
+        return { "x": p.x, "y": rect.y + (dy > 0 ? h : -h) };
+
+      var slope = dy / dx;
+
+      var x0 = null, y0 = null;
+      if (Math.abs(slope) < rect.height / rect.width) {
+        // intersect with the left or right edges of the rect
+        x0 = rect.x + (dx > 0 ? w : -w);
+        y0 = cy + slope * (x0 - cx);
+      } else {
+        y0 = rect.y + (dy > 0 ? h : -h);
+        x0 = cx + (y0 - cy) / slope;
+      }
+
+      return { "x": x0, "y": y0 };
+    }
+
+    function drawNode(u, value) {
+      var root = svg.append('g').classed('node', true)
+        .attr('transform', 'translate(' + -value.width/2 + ',' + -value.height/2 + ')');
+      var node = node_by_id[u];
+
+      var rect = root.append('rect')
+        .attr('width', value.width)
+        .attr('height', value.height)
+        .attr('x', value.x)
+        .attr('y', value.y)
+        .attr('rx', RECT_ROUND)
+        .attr('ry', RECT_ROUND);
+
+      var fo = root.append('foreignObject')
+        .attr('x', value.x)
+        .attr('y', value.y)
+        .attr('width', value.width)
+        .attr('height', value.height);
+
+      var txt = fo.append('xhtml:div')
+        .text(node.name)
+        .classed('node-name', true)
+        .classed('node-name-' + node.type, true);
+    }
+
+    function drawEdge(e, u, v, value) {
+      var root = svg.append('g').classed('edge', true);
+
+      root.append('path')
+        .attr('marker-end', 'url(#arrowhead)')
+        .attr('d', function() {
+          var points = value.points;
+
+          var source = layout.node(u);
+          var target = layout.node(v);
+
+          var p0 = points.length === 0 ? target : points[0];
+          var p1 = points.length === 0 ? source : points[points.length - 1];
+
+          points.unshift(intersectRect(source, p0));
+          points.push(intersectRect(target, p1));
+
+          return LINE_FUNCTION(points);
+        });
+    }
+
+    function postRender() {
+      svg
+        .append('svg:defs')
+        .append('svg:marker')
+        .attr('id', 'arrowhead')
+        .attr('viewBox', '0 0 10 10')
+        .attr('refX', 8)
+        .attr('refY', 5)
+        .attr('markerUnits', 'strokewidth')
+        .attr('markerWidth', 8)
+        .attr('markerHeight', 5)
+        .attr('orient', 'auto')
+        .attr('style', 'fill: #333')
+        .append('svg:path')
+        .attr('d', 'M 0 0 L 10 5 L 0 10 z');
+    }
+
+    function plot() {
+      var g = new dagre.Digraph();
+
+      for (var key in nodes) {
+        var n = nodes[key];
+        node_by_id[n.id] = n;
+        g.addNode(n.id, { "width": NODE_WIDTH, "height": NODE_HEIGHT });
+      }
+
+      for (var key in nodes) {
+        var n = nodes[key];
+        for (var i = 0, l = n.dependency.length; i < l; ++i) {
+          var d = n.dependency[i];
+          g.addEdge(null, d, n.id);
+        }
+      }
+
+      layout = dagre.layout()
+        .universalSep(100).rankSep(SEPARATION)
+        .run(g);
+      layout.eachEdge(drawEdge);
+      layout.eachNode(drawNode);
+
+      var bb = layout.graph().bbox;
+
+      $('#entity-dep-graph').attr('width', bb.width);
+      $('#entity-dep-graph').attr('height', bb.height);
+      postRender();
+    }
+    plot();
+  }
+
+
+  function visualizeDependencyGraph() {
+    $('#dep-view-graph')
+      .css('text-align', 'center')
+      .html('<svg id="entity-dep-graph" height="200"><g></g></svg>');
+
+    falcon.loadDependencyGraph(entityType, entityId, function(nodes) {
+      plotDependencyGraph(nodes, d3.select('#entity-dep-graph'));
+      switchDependencyView('graph');
+    });
+  }
+
+  $('#btn-dep-list').click(function() {
+    switchDependencyView('list');
+  });
+  $('#btn-dep-graph').click(visualizeDependencyGraph);
+  load();
+})(falcon, dust);

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/js/falcon-index.js
----------------------------------------------------------------------
diff --git a/html5-ui/js/falcon-index.js b/html5-ui/js/falcon-index.js
new file mode 100644
index 0000000..aa5e7a2
--- /dev/null
+++ b/html5-ui/js/falcon-index.js
@@ -0,0 +1,107 @@
+/*
+* 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.
+*/
+(function (falcon, dust) {
+  var ENTRIES_PER_PAGE = 25;
+
+  var source = $("#entity-list-tmpl").html();
+  dust.loadSource(dust.compile(source, 'entity-list'));
+
+  var entityType = (/type=(.+?)(&|$)/.exec(location.search)||[,'feed'])[1];
+
+  function gotoPage(page) {
+    var start = (page - 1) * ENTRIES_PER_PAGE, end = page * ENTRIES_PER_PAGE;
+
+    var d = falcon.entities.slice(start, end);
+    dust.render('entity-list', {"entity": d}, function(err, out) {
+      var total = Math.ceil(falcon.entities.length / ENTRIES_PER_PAGE);
+      $('#entity-paginator').data('activePage', page);
+      generatePaginator(page, total);
+
+      $('#entity-list-container').html(out);
+    });
+  }
+
+  function generatePaginator(current, total) {
+    var root = $('<ul class="pagination"></ul>'),
+    prev = $('<li><a href="#">&laquo;</a></li>'),
+    next = $('<li><a href="#">&raquo;</a></li>');
+
+    root.append(prev);
+    for (var i = 1; i <= total; ++i) {
+      var l = $('<li><a href="#">' + i + '</a></li>')
+        .attr('data-page', i);
+
+      if (i == current)
+        l.addClass('active');
+
+      root.append(l);
+    }
+
+    root.append(next);
+
+    if (current == 1) {
+      prev.addClass('disabled');
+    } else {
+      prev.attr('data-page', current - 1);
+    }
+
+    if (current == total) {
+      next.addClass('disabled');
+    } else {
+      next.attr('data-page', current + 1);
+    }
+
+    root.children()
+      .click(function() {
+        var n = $(this).attr('data-page');
+        if (n !== undefined)
+          gotoPage(n);
+
+        return false;
+      });
+    $('#entity-paginator').html(root);
+  }
+
+  /**
+   * Gets the latest entities from '/entities/list/process',
+   * 'entities/list/feed', '/entities/list/cluster'
+   **/
+  function refreshEntities(type) {
+    falcon.getJson('api/entities/list/' + type + '?fields=status', function (data) {
+      if (data.entity == null)
+        return;
+
+      if (!($.isArray(data.entity)))
+        data.entity = new Array(data.entity);
+
+      $('#entity-paginator').data('activePage', 1);
+      falcon.entities = data.entity;
+      gotoPage(1);
+    });
+  }
+
+  function initialize() {
+    $('.btn-entity-list').click(function() {
+      $(this).parent().siblings().removeClass('active');
+      $(this).parent().addClass('active');
+      refreshEntities($(this).attr('data-entity-type'));
+    });
+    $('.btn-entity-list[data-entity-type="' + entityType + '"]').click();
+  }
+
+  initialize();
+})(falcon, dust);

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/html5-ui/js/falcon.js
----------------------------------------------------------------------
diff --git a/html5-ui/js/falcon.js b/html5-ui/js/falcon.js
new file mode 100644
index 0000000..14758bc
--- /dev/null
+++ b/html5-ui/js/falcon.js
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+(function(exports) {
+  "use strict";
+
+  var USER_ID = 'admin';
+
+  function onError (msg) {
+    alert(msg);
+  }
+
+  function ajax_impl(options) {
+    $.extend(options, {'headers': { 'Remote-User': USER_ID }});
+    return $.ajax(options);
+  }
+
+  function getJson_impl(url, success) {
+    return ajax_impl({
+      'dataType': 'json',
+      'url': url,
+      'success': success
+    });
+  }
+
+  function getText_impl(url, success) {
+    return ajax_impl({
+      'dataType': 'text',
+      'url': url,
+      'success': success
+    });
+  }
+
+  var falcon = {
+    loadTemplate: function(tmpl_name, url, success) {
+      $.get(url, function (data) {
+        dust.loadSource(dust.compile(data, tmpl_name));
+        success();
+      }).fail(function() { onError('Cannot load the application.'); });
+    },
+
+    ajax: ajax_impl,
+    getJson: getJson_impl,
+    getText: getText_impl,
+
+    /**
+     * Calling the REST API recursively to get the dependency graph
+     **/
+    loadDependencyGraph: function(entity_type, entity_name, done_callback) {
+      var nodes = {};
+      var next_node_id = 0;
+
+      var STATE_UNINITIALIZED = 0;
+      var STATE_REQUEST_SENT = 1;
+
+      var requests_in_fly = 0;
+
+      function key(type, name) {
+        return type + '/' + name;
+      }
+
+      function getOrCreateNode(type, name) {
+        var k = key(type, name);
+        if (nodes[k] !== undefined)
+          return nodes[k];
+
+        var n = {
+          "request_state": STATE_UNINITIALIZED,
+          "id": next_node_id++,
+          "type": type,
+          "name": name,
+          "dependency": []
+        };
+        nodes[k] = n;
+        return n;
+      }
+
+      function loadEntry(node) {
+        var type = node.type, name = node.name, k = key(type, name);
+        getJson_impl(
+          'api/entities/dependencies/' + type + '/' + name,
+          function (data) {
+            if (data.entity == null)
+              return;
+
+            if (!($.isArray(data.entity)))
+              data.entity = new Array(data.entity);
+
+            var l = data.entity.length;
+            for (var i = 0; i < l; ++i) {
+              var e = data.entity[i];
+              node.dependency.push(getOrCreateNode(e.type, e.name).id);
+              enqueue(e.type, e.name);
+            }
+          })
+          .always(function () {
+            --requests_in_fly;
+
+            if (requests_in_fly == 0)
+              done_callback(nodes);
+          });
+      }
+
+      function enqueue(type, name) {
+        // There's no dependency for clusters
+        if (type === 'cluster')
+          return;
+
+        var k = key(type, name);
+
+        if (nodes[k] !== undefined && nodes[k].request_state !== STATE_UNINITIALIZED)
+          return;
+
+        var n = getOrCreateNode(type, name);
+        n.request_state = STATE_REQUEST_SENT;
+
+        ++requests_in_fly;
+        loadEntry(n);
+      }
+
+      enqueue(entity_type, entity_name);
+    }
+  };
+
+  exports.falcon = falcon;
+})(window);

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 091db4d..c05de77 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1018,6 +1018,7 @@
                         <exclude>**/data.txt</exclude>
                         <exclude>**/maven-eclipse.xml</exclude>
                         <exclude>**/.externalToolBuilders/**</exclude>
+                        <exclude>html5-ui/**</exclude>
                     </excludes>
                     <argLine>-Dfalcon.log.dir=target/logs -Dfalcon.embeddedmq.data=target/data</argLine>
                 </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/prism/pom.xml
----------------------------------------------------------------------
diff --git a/prism/pom.xml b/prism/pom.xml
index 2d78ffd..2ca6330 100644
--- a/prism/pom.xml
+++ b/prism/pom.xml
@@ -134,8 +134,13 @@
         <plugins>
             <plugin>
                 <artifactId>maven-war-plugin</artifactId>
-                <version>2.1.1</version>
+                <version>2.4</version>
                 <configuration>
+                    <webResources>
+                        <resource>
+                            <directory>../html5-ui</directory>
+			            </resource>
+                    </webResources>
                     <attachClasses>true</attachClasses>
                 </configuration>
             </plugin>

http://git-wip-us.apache.org/repos/asf/incubator-falcon/blob/9e376c20/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/webapp/pom.xml b/webapp/pom.xml
index 02c0458..e14b261 100644
--- a/webapp/pom.xml
+++ b/webapp/pom.xml
@@ -184,10 +184,13 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-war-plugin</artifactId>
-                <version>2.1.1</version>
+                <version>2.4</version>
                 <configuration>
                     <webResources>
                         <resource>
+                            <directory>../html5-ui</directory>
+                        </resource>
+                        <resource>
                             <directory>src/main/webapp/WEB-INF/embedded</directory>
                             <targetPath>WEB-INF</targetPath>
                         </resource>
@@ -400,14 +403,14 @@
                     <plugin>
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-war-plugin</artifactId>
-                        <version>2.1.1</version>
+                        <version>2.4</version>
                         <configuration>
                             <packagingExcludes>WEB-INF/classes/deploy.properties</packagingExcludes>
                             <webResources>
-                                <resource>
-                                    <directory>src/main/webapp/WEB-INF/distributed</directory>
-                                    <targetPath>WEB-INF</targetPath>
-                                </resource>
+                              <resource>
+                                <directory>src/main/webapp/WEB-INF/distributed</directory>
+                                <targetPath>WEB-INF</targetPath>
+                              </resource>
                             </webResources>
                         </configuration>
                     </plugin>