You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2017/09/06 17:45:28 UTC

[8/8] nifi-registry git commit: [NIFIREG-13] Initial implementation of the registry UI/UX. This closes #8

[NIFIREG-13] Initial implementation of the registry UI/UX. This closes #8


Project: http://git-wip-us.apache.org/repos/asf/nifi-registry/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi-registry/commit/7fa56bea
Tree: http://git-wip-us.apache.org/repos/asf/nifi-registry/tree/7fa56bea
Diff: http://git-wip-us.apache.org/repos/asf/nifi-registry/diff/7fa56bea

Branch: refs/heads/master
Commit: 7fa56bea9ff73f096480bfb6d9b5ab85a09c0dcf
Parents: a1629c8
Author: Scott Aslan <sc...@gmail.com>
Authored: Tue Sep 5 17:02:14 2017 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Wed Sep 6 13:45:00 2017 -0400

----------------------------------------------------------------------
 .travis.yml                                     |   21 +
 nifi-registry-jetty/pom.xml                     |   25 +-
 .../apache/nifi/registry/jetty/JettyServer.java |   23 +-
 .../org/apache/nifi-registry/web/webdefault.xml |  556 ++++
 nifi-registry-web-api/pom.xml                   |   10 +-
 nifi-registry-web-ui/pom.xml                    |  467 ++-
 .../src/main/frontend/Gruntfile.js              |   91 +
 .../src/main/frontend/karma-test-shim.js        |  113 +
 .../src/main/frontend/karma.conf.ci.js          |   39 +
 .../src/main/frontend/karma.conf.js             |  140 +
 .../src/main/frontend/package.json              |   65 +
 .../src/main/frontend/protractor.config.js      |  201 ++
 .../src/main/locale/messages.es.xlf             |   46 +
 .../src/main/platform/core/README.md            |   33 +
 .../core/common/styles/_basicElements.scss      |  130 +
 .../core/common/styles/_buttonToggles.scss      |   98 +
 .../platform/core/common/styles/_buttons.scss   |  198 ++
 .../core/common/styles/_checkboxes.scss         |   85 +
 .../platform/core/common/styles/_chips.scss     |   67 +
 .../core/common/styles/_expansionPanels.scss    |   59 +
 .../core/common/styles/_globalVars.scss         |   80 +
 .../core/common/styles/_helperClasses.scss      |   72 +
 .../platform/core/common/styles/_inputs.scss    |  124 +
 .../platform/core/common/styles/_links.scss     |   33 +
 .../platform/core/common/styles/_menus.scss     |  120 +
 .../platform/core/common/styles/_modals.scss    |   23 +
 .../platform/core/common/styles/_panels.scss    |   54 +
 .../platform/core/common/styles/_radios.scss    |   56 +
 .../platform/core/common/styles/_sideNav.scss   |   20 +
 .../platform/core/common/styles/_tables.scss    |  113 +
 .../main/platform/core/common/styles/_tabs.scss |   41 +
 .../platform/core/common/styles/_tooltips.scss  |   24 +
 .../core/common/styles/fluid-design-system.scss |   55 +
 .../core/dialogs/_fds-dialog-component.scss     |   21 +
 .../confirm-dialog.component.html               |   45 +
 .../confirm-dialog/confirm-dialog.component.js  |   64 +
 .../core/dialogs/fds-dialog.component.html      |   29 +
 .../core/dialogs/fds-dialog.component.js        |   82 +
 .../platform/core/dialogs/fds-dialogs.module.js |   87 +
 .../core/dialogs/services/dialog.service.js     |  130 +
 .../platform/core/fluid-design-system.module.js |   99 +
 .../resources/filters/registry-min.properties   |   19 +
 .../main/resources/filters/registry.properties  |   23 +
 .../src/main/webapp/WEB-INF/pages/index.jsp     |   25 +-
 .../src/main/webapp/WEB-INF/web.xml             |   29 +-
 .../nf-registry-general-administration.html     |   30 +
 .../nf-registry-general-administration.js       |   61 +
 .../nf-registry-administration.html             |   39 +
 .../nf-registry-administration.js               |   84 +
 .../nf-registry-administration.spec.js          |  152 +
 .../users/add/nf-registry-add-user.html         |   28 +
 .../users/add/nf-registry-add-user.js           |   66 +
 .../users/details/nf-registry-user-details.html |   28 +
 .../users/details/nf-registry-user-details.js   |   66 +
 .../users/nf-registry-users-administration.html |  122 +
 .../users/nf-registry-users-administration.js   |  128 +
 .../nf-registry-user-permissions.html           |   28 +
 .../permissions/nf-registry-user-permissions.js |   66 +
 .../nf-registry-bucket-permissions.html         |   28 +
 .../nf-registry-bucket-permissions.js           |   77 +
 .../nf-registry-workflow-administration.html    |  170 +
 .../nf-registry-workflow-administration.js      |  121 +
 .../nf-registry-explorer-grid-list-viewer.html  |   18 +
 .../nf-registry-explorer-grid-list-viewer.js    |   43 +
 .../nf-registry-droplet-grid-list-viewer.html   |   17 +
 .../nf-registry-droplet-grid-list-viewer.js     |   75 +
 .../nf-registry-bucket-grid-list-viewer.html    |   18 +
 .../nf-registry-bucket-grid-list-viewer.js      |   76 +
 .../registry/nf-registry-grid-list-viewer.html  |  186 ++
 .../registry/nf-registry-grid-list-viewer.js    |  106 +
 .../explorer/nf-registry-explorer.html          |   18 +
 .../components/explorer/nf-registry-explorer.js |   61 +
 .../fluid-design-system/fds-demo.html           | 3060 ++++++++++++++++++
 .../components/fluid-design-system/fds-demo.js  | 1029 ++++++
 .../nf-registry-page-not-found.js               |   36 +
 .../src/main/webapp/css/main.css                |   22 -
 .../src/main/webapp/images/registry-favicon.png |  Bin 0 -> 388 bytes
 .../webapp/images/registry-logo-web-app.svg     |   17 +
 .../src/main/webapp/nf-registry-bootstrap.js    |   54 +
 .../src/main/webapp/nf-registry.animations.js   |  119 +
 .../src/main/webapp/nf-registry.e2e-spec.js     |   30 +
 .../src/main/webapp/nf-registry.html            |   88 +
 .../src/main/webapp/nf-registry.js              |   59 +
 .../src/main/webapp/nf-registry.module.js       |   60 +
 .../src/main/webapp/nf-registry.routes.js       |  104 +
 .../src/main/webapp/nf-registry.spec.js         |   63 +
 .../main/webapp/services/nf-registry.service.js |  981 ++++++
 .../src/main/webapp/systemjs-angular-loader.js  |   66 +
 .../src/main/webapp/systemjs.builder.config.js  |  137 +
 .../src/main/webapp/systemjs.config.extras.js   |   27 +
 .../src/main/webapp/systemjs.spec.config.js     |   76 +
 .../src/main/webapp/theming/_helperClasses.scss |   63 +
 .../main/webapp/theming/_structureElements.scss |   82 +
 .../administration/_structureElements.scss      |   22 +
 .../general/_structureElements.scss             |   25 +
 .../users/_structureElements.scss               |   61 +
 .../workflow/_structureElements.scss            |   61 +
 .../explorer/grid-list/_structureElements.scss  |   44 +
 .../fluid-design-system/_structureElements.scss |   25 +
 .../src/main/webapp/theming/nf-registry.scss    |   30 +
 pom.xml                                         |  141 +-
 101 files changed, 12282 insertions(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..4bef783
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,21 @@
+# 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.
+
+# before_install
+#   1. Configures pre-installed Chrome on Travis CI for karma testing
+before_install:
+  - export CHROME_BIN=chromium-browser
+  - export DISPLAY=:99.0
+  - sh -e /etc/init.d/xvfb start
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-jetty/pom.xml b/nifi-registry-jetty/pom.xml
index 3c75832..38e6442 100644
--- a/nifi-registry-jetty/pom.xml
+++ b/nifi-registry-jetty/pom.xml
@@ -13,7 +13,8 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.nifi.registry</groupId>
@@ -50,28 +51,22 @@
             <artifactId>jetty-servlets</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-jsp</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>javax.servlet.jsp</groupId>
-            <artifactId>javax.servlet.jsp-api</artifactId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-annotations</artifactId>
         </dependency>
         <dependency>
-            <groupId>javax.el</groupId>
-            <artifactId>javax.el-api</artifactId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <scope>compile</scope>
         </dependency>
         <dependency>
-            <groupId>javax.servlet.jsp.jstl</groupId>
-            <artifactId>javax.servlet.jsp.jstl-api</artifactId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <scope>compile</scope>
         </dependency>
     </dependencies>
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
----------------------------------------------------------------------
diff --git a/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java b/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
index 474f907..9f71e5f 100644
--- a/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
+++ b/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
@@ -20,6 +20,7 @@ import org.apache.nifi.registry.security.AuthorizationProvider;
 import org.apache.nifi.registry.security.AuthorizedUserFilter;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.registry.properties.NiFiRegistryProperties;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.HttpConfiguration;
@@ -32,6 +33,9 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.WebAppClassLoader;
 import org.eclipse.jetty.webapp.WebAppContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,6 +44,7 @@ import javax.servlet.DispatcherType;
 import javax.servlet.Filter;
 import java.io.File;
 import java.io.FileFilter;
+import java.io.IOException;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
@@ -56,7 +61,7 @@ import java.util.Set;
 public class JettyServer {
 
     private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
-
+    private static final String WEB_DEFAULTS_XML = "org/apache/nifi-registry/web/webdefault.xml";
     private static final int HEADER_BUFFER_SIZE = 16 * 1024; // 16kb
 
     private static final FileFilter WAR_FILTER = new FileFilter() {
@@ -79,6 +84,11 @@ public class JettyServer {
 
         this.properties = properties;
         this.server = new Server(threadPool);
+
+        // enable the annotation based configuration to ensure the jsp container is initialized properly
+        final Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
+        classlist.addBefore(JettyWebXmlConfiguration.class.getName(), AnnotationConfiguration.class.getName());
+
         configureConnectors();
         loadWars();
     }
@@ -223,6 +233,7 @@ public class JettyServer {
         List<String> serverClasses = new ArrayList<>(Arrays.asList(webappContext.getServerClasses()));
         serverClasses.remove("org.slf4j.");
         webappContext.setServerClasses(serverClasses.toArray(new String[0]));
+        webappContext.setDefaultsDescriptor(WEB_DEFAULTS_XML);
 
         // get the temp directory for this webapp
         final File webWorkingDirectory = properties.getWebWorkingDirectory();
@@ -245,11 +256,11 @@ public class JettyServer {
         // configure the max form size (3x the default)
         webappContext.setMaxFormContentSize(600000);
 
-//        try {
-//            webappContext.setClassLoader(new WebAppClassLoader(ClassLoader.getSystemClassLoader(), webappContext));
-//        } catch (final IOException ioe) {
-//            throw new RuntimeException(ioe);
-//        }
+        try {
+            webappContext.setClassLoader(new WebAppClassLoader(ClassLoader.getSystemClassLoader(), webappContext));
+        } catch (final IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
         logger.info("Loading WAR: " + warFile.getAbsolutePath() + " with context path set to " + contextPath);
         return webappContext;
     }

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-jetty/src/main/resources/org/apache/nifi-registry/web/webdefault.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-jetty/src/main/resources/org/apache/nifi-registry/web/webdefault.xml b/nifi-registry-jetty/src/main/resources/org/apache/nifi-registry/web/webdefault.xml
new file mode 100644
index 0000000..814dbd8
--- /dev/null
+++ b/nifi-registry-jetty/src/main/resources/org/apache/nifi-registry/web/webdefault.xml
@@ -0,0 +1,556 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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.
+-->
+<web-app 
+    xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+    metadata-complete="false"
+    version="3.1"> 
+
+    <!-- ===================================================================== -->
+    <!-- This file contains the default descriptor for web applications.       -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    <!-- The intent of this descriptor is to include jetty specific or common  -->
+    <!-- configuration for all webapps.   If a context has a webdefault.xml    -->
+    <!-- descriptor, it is applied before the contexts own web.xml file        -->
+    <!--                                                                       -->
+    <!-- A context may be assigned a default descriptor by:                    -->
+    <!--  + Calling WebApplicationContext.setDefaultsDescriptor                -->
+    <!--  + Passed an arg to addWebApplications                                -->
+    <!--                                                                       -->
+    <!-- This file is used both as the resource within the jetty.jar (which is -->
+    <!-- used as the default if no explicit defaults descriptor is set) and it -->
+    <!-- is copied to the etc directory of the Jetty distro and explicitly     -->
+    <!-- by the jetty.xml file.                                                -->
+    <!--                                                                       -->
+    <!-- ===================================================================== -->
+
+    <description>
+        Default web.xml file.  
+        This file is applied to a Web application before it's own WEB_INF/web.xml file
+    </description>
+
+    <!-- ==================================================================== -->
+    <!-- Removes static references to beans from javax.el.BeanELResolver to   -->
+    <!-- ensure webapp classloader can be released on undeploy                -->
+    <!-- ==================================================================== -->
+    <listener>
+        <listener-class>org.eclipse.jetty.servlet.listener.ELContextCleaner</listener-class>
+    </listener>
+  
+    <!-- ==================================================================== -->
+    <!-- Removes static cache of Methods from java.beans.Introspector to      -->
+    <!-- ensure webapp classloader can be released on undeploy                -->
+    <!-- ==================================================================== -->  
+    <listener>
+        <listener-class>org.eclipse.jetty.servlet.listener.IntrospectorCleaner</listener-class>
+    </listener>
+  
+
+    <!-- ==================================================================== -->
+    <!-- Context params to control Session Cookies                            -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <!--
+      UNCOMMENT TO ACTIVATE 
+      <context-param> 
+        <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name> 
+        <param-value>127.0.0.1</param-value> 
+      </context-param> 
+      <context-param>
+        <param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
+        <param-value>/</param-value>
+      </context-param>
+      <context-param>
+        <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
+        <param-value>-1</param-value>
+      </context-param>
+    -->
+
+    <!-- ==================================================================== -->
+    <!-- The default servlet.                                                 -->
+    <!-- This servlet, normally mapped to /, provides the handling for static -->
+    <!-- content, OPTIONS and TRACE methods for the context.                  -->
+    <!-- The following initParameters are supported:                          -->
+    <!--  
+    *  acceptRanges      If true, range requests and responses are
+    *                    supported
+    *
+    *  dirAllowed        If true, directory listings are returned if no
+    *                    welcome file is found. Else 403 Forbidden.
+    *
+    *  welcomeServlets   If true, attempt to dispatch to welcome files
+    *                    that are servlets, but only after no matching static
+    *                    resources could be found. If false, then a welcome
+    *                    file must exist on disk. If "exact", then exact
+    *                    servlet matches are supported without an existing file.
+    *                    Default is true.
+    *
+    *                    This must be false if you want directory listings,
+    *                    but have index.jsp in your welcome file list.
+    *
+    *  redirectWelcome   If true, welcome files are redirected rather than
+    *                    forwarded to.
+    *
+    *  gzip              If set to true, then static content will be served as
+    *                    gzip content encoded if a matching resource is
+    *                    found ending with ".gz"
+    *
+    *  resourceBase      Set to replace the context resource base
+    *
+    *  resourceCache     If set, this is a context attribute name, which the servlet
+    *                    will use to look for a shared ResourceCache instance.
+    *
+    *  relativeResourceBase
+    *                    Set with a pathname relative to the base of the
+    *                    servlet context root. Useful for only serving static content out
+    *                    of only specific subdirectories.
+    *
+    *  pathInfoOnly      If true, only the path info will be applied to the resourceBase
+    *
+    *  stylesheet        Set with the location of an optional stylesheet that will be used
+    *                    to decorate the directory listing html.
+    *
+    *  aliases           If True, aliases of resources are allowed (eg. symbolic
+    *                    links and caps variations). May bypass security constraints.
+    *                    
+    *  etags             If True, weak etags will be generated and handled.
+    *
+    *  maxCacheSize      The maximum total size of the cache or 0 for no cache.
+    *  maxCachedFileSize The maximum size of a file to cache
+    *  maxCachedFiles    The maximum number of files to cache
+    *
+    *  useFileMappedBuffer
+    *                    If set to true, it will use mapped file buffer to serve static content
+    *                    when using NIO connector. Setting this value to false means that
+    *                    a direct buffer will be used instead of a mapped file buffer.
+    *                    By default, this is set to true.
+    *
+    *  cacheControl      If set, all static content will have this value set as the cache-control
+    *                    header.
+    *
+    -->
+ 
+ 
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <servlet>
+        <servlet-name>default</servlet-name>
+        <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
+        <init-param>
+            <param-name>aliases</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>acceptRanges</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>dirAllowed</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>welcomeServlets</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>redirectWelcome</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>maxCacheSize</param-name>
+            <param-value>256000000</param-value>
+        </init-param>
+        <init-param>
+            <param-name>maxCachedFileSize</param-name>
+            <param-value>200000000</param-value>
+        </init-param>
+        <init-param>
+            <param-name>maxCachedFiles</param-name>
+            <param-value>2048</param-value>
+        </init-param>
+        <init-param>
+            <param-name>gzip</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>etags</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>useFileMappedBuffer</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <!--
+        <init-param>
+          <param-name>resourceCache</param-name>
+          <param-value>resourceCache</param-value>
+        </init-param>
+        -->
+        <!--
+        <init-param>
+          <param-name>cacheControl</param-name>
+          <param-value>max-age=3600,public</param-value>
+        </init-param>
+        -->
+        <load-on-startup>0</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>default</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+
+
+    <!-- ==================================================================== -->
+    <!-- JSP Servlet                                                          -->
+    <!-- This is the jasper JSP servlet from the jakarta project              -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <!-- The JSP page compiler and execution servlet, which is the mechanism  -->
+    <!-- used by Glassfish to support JSP pages.  Traditionally, this servlet -->
+    <!-- is mapped to URL patterh "*.jsp".  This servlet supports the         -->
+    <!-- following initialization parameters (default values are in square    -->
+    <!-- brackets):                                                           -->
+    <!--                                                                      -->
+    <!--   checkInterval       If development is false and reloading is true, -->
+    <!--                       background compiles are enabled. checkInterval -->
+    <!--                       is the time in seconds between checks to see   -->
+    <!--                       if a JSP page needs to be recompiled. [300]    -->
+    <!--                                                                      -->
+    <!--   compiler            Which compiler Ant should use to compile JSP   -->
+    <!--                       pages.  See the Ant documenation for more      -->
+    <!--                       information. [javac]                           -->
+    <!--                                                                      -->
+    <!--   classdebuginfo      Should the class file be compiled with         -->
+    <!--                       debugging information?  [true]                 -->
+    <!--                                                                      -->
+    <!--   classpath           What class path should I use while compiling   -->
+    <!--                       generated servlets?  [Created dynamically      -->
+    <!--                       based on the current web application]          -->
+    <!--                       Set to ? to make the container explicitly set  -->
+    <!--                       this parameter.                                -->
+    <!--                                                                      -->
+    <!--   development         Is Jasper used in development mode (will check -->
+    <!--                       for JSP modification on every access)?  [true] -->
+    <!--                                                                      -->
+    <!--   enablePooling       Determines whether tag handler pooling is      -->
+    <!--                       enabled  [true]                                -->
+    <!--                                                                      -->
+    <!--   fork                Tell Ant to fork compiles of JSP pages so that -->
+    <!--                       a separate JVM is used for JSP page compiles   -->
+    <!--                       from the one Tomcat is running in. [true]      -->
+    <!--                                                                      -->
+    <!--   ieClassId           The class-id value to be sent to Internet      -->
+    <!--                       Explorer when using <jsp:plugin> tags.         -->
+    <!--                       [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93]   -->
+    <!--                                                                      -->
+    <!--   javaEncoding        Java file encoding to use for generating java  -->
+    <!--                       source files. [UTF-8]                          -->
+    <!--                                                                      -->
+    <!--   keepgenerated       Should we keep the generated Java source code  -->
+    <!--                       for each page instead of deleting it? [true]   -->
+    <!--                                                                      -->
+    <!--   logVerbosityLevel   The level of detailed messages to be produced  -->
+    <!--                       by this servlet.  Increasing levels cause the  -->
+    <!--                       generation of more messages.  Valid values are -->
+    <!--                       FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
+    <!--                       [WARNING]                                      -->
+    <!--                                                                      -->
+    <!--   mappedfile          Should we generate static content with one     -->
+    <!--                       print statement per input line, to ease        -->
+    <!--                       debugging?  [false]                            -->
+    <!--                                                                      -->
+    <!--                                                                      -->
+    <!--   reloading           Should Jasper check for modified JSPs?  [true] -->
+    <!--                                                                      -->
+    <!--   suppressSmap        Should the generation of SMAP info for JSR45   -->
+    <!--                       debugging be suppressed?  [false]              -->
+    <!--                                                                      -->
+    <!--   dumpSmap            Should the SMAP info for JSR45 debugging be    -->
+    <!--                       dumped to a file? [false]                      -->
+    <!--                       False if suppressSmap is true                  -->
+    <!--                                                                      -->
+    <!--   scratchdir          What scratch directory should we use when      -->
+    <!--                       compiling JSP pages?  [default work directory  -->
+    <!--                       for the current web application]               -->
+    <!--                                                                      -->
+    <!--   tagpoolMaxSize      The maximum tag handler pool size  [5]         -->
+    <!--                                                                      -->
+    <!--   xpoweredBy          Determines whether X-Powered-By response       -->
+    <!--                       header is added by generated servlet  [false]  -->
+    <!--                                                                      -->
+    <!-- If you wish to use Jikes to compile JSP pages:                       -->
+    <!--   Set the init parameter "compiler" to "jikes".  Define              -->
+    <!--   the property "-Dbuild.compiler.emacs=true" when starting Jetty     -->
+    <!--   to cause Jikes to emit error messages in a format compatible with  -->
+    <!--   Jasper.                                                            -->
+    <!--   If you get an error reporting that jikes can't use UTF-8 encoding, -->
+    <!--   try setting the init parameter "javaEncoding" to "ISO-8859-1".     -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <servlet id="jsp">
+        <servlet-name>jsp</servlet-name>
+        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+        <init-param>
+            <param-name>logVerbosityLevel</param-name>
+            <param-value>DEBUG</param-value>
+        </init-param>
+        <init-param>
+            <param-name>fork</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>keepgenerated</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>development</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>xpoweredBy</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>compilerTargetVM</param-name>
+            <param-value>1.7</param-value>
+        </init-param>
+        <init-param>
+            <param-name>compilerSourceVM</param-name>
+            <param-value>1.7</param-value>
+        </init-param>
+        <!--  
+        <init-param>
+            <param-name>classpath</param-name>
+            <param-value>?</param-value>
+        </init-param>
+        -->
+        <load-on-startup>0</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>jsp</servlet-name>
+        <url-pattern>*.jsp</url-pattern>
+        <url-pattern>*.jspf</url-pattern>
+        <url-pattern>*.jspx</url-pattern>
+        <url-pattern>*.xsp</url-pattern>
+        <url-pattern>*.JSP</url-pattern>
+        <url-pattern>*.JSPF</url-pattern>
+        <url-pattern>*.JSPX</url-pattern>
+        <url-pattern>*.XSP</url-pattern>
+    </servlet-mapping>
+
+
+    <!-- ==================================================================== -->
+    <session-config>
+        <session-timeout>30</session-timeout>
+    </session-config>
+
+    <!-- ==================================================================== -->
+    <!-- Default MIME mappings                                                -->
+    <!-- The default MIME mappings are provided by the mime.properties        -->
+    <!-- resource in the org.eclipse.jetty.server.jar file.  Additional or modified  -->
+    <!-- mappings may be specified here                                       -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <!-- UNCOMMENT TO ACTIVATE
+    <mime-mapping>
+      <extension>mysuffix</extension>
+      <mime-type>mymime/type</mime-type>
+    </mime-mapping>
+    -->
+
+    <!-- ==================================================================== -->
+    <welcome-file-list>
+        <welcome-file>index.html</welcome-file>
+        <welcome-file>index.htm</welcome-file>
+        <welcome-file>index.jsp</welcome-file>
+    </welcome-file-list>
+
+    <!-- ==================================================================== -->
+    <locale-encoding-mapping-list>
+        <locale-encoding-mapping>
+            <locale>ar</locale>
+            <encoding>ISO-8859-6</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>be</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>bg</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ca</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>cs</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>da</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>de</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>el</locale>
+            <encoding>ISO-8859-7</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>en</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>es</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>et</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>fi</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>fr</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>hr</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>hu</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>is</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>it</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>iw</locale>
+            <encoding>ISO-8859-8</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ja</locale>
+            <encoding>Shift_JIS</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ko</locale>
+            <encoding>EUC-KR</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>lt</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>lv</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>mk</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>nl</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>no</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>pl</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>pt</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ro</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ru</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sh</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sk</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sl</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sq</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sr</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sv</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>tr</locale>
+            <encoding>ISO-8859-9</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>uk</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>zh</locale>
+            <encoding>GB2312</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>zh_TW</locale>
+            <encoding>Big5</encoding>
+        </locale-encoding-mapping>
+    </locale-encoding-mapping-list>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Disable TRACE</web-resource-name>
+            <url-pattern>/</url-pattern>
+            <http-method>TRACE</http-method>
+        </web-resource-collection>
+        <auth-constraint/>
+    </security-constraint>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Enable everything but TRACE</web-resource-name>
+            <url-pattern>/</url-pattern>
+            <http-method-omission>TRACE</http-method-omission>
+        </web-resource-collection>
+    </security-constraint>
+
+</web-app>
+

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-web-api/pom.xml b/nifi-registry-web-api/pom.xml
index 74c6ba3..94478eb 100644
--- a/nifi-registry-web-api/pom.xml
+++ b/nifi-registry-web-api/pom.xml
@@ -14,7 +14,8 @@
   limitations under the License.
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.nifi.registry</groupId>
@@ -57,7 +58,8 @@
                                         <title>NiFi Registry REST API</title>
                                         <version>${project.version}</version>
                                         <description>
-                                            The Rest Api provides an interface to a registry with operations for saving, versioning, reading NiFi flows
+                                            The Rest Api provides an interface to a registry with operations for saving,
+                                            versioning, reading NiFi flows
                                             and components.
                                         </description>
                                         <contact>
@@ -71,7 +73,9 @@
                                         </license>
                                     </info>
                                     <templatePath>classpath:/templates/index.html.hbs</templatePath>
-                                    <outputPath>${project.build.directory}/${project.artifactId}-${project.version}/docs/rest-api/index.html</outputPath>
+                                    <outputPath>
+                                        ${project.build.directory}/${project.artifactId}-${project.version}/docs/rest-api/index.html
+                                    </outputPath>
                                     <swaggerDirectory>${project.build.directory}/swagger-ui</swaggerDirectory>
                                 </apiSource>
                             </apiSources>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-ui/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/pom.xml b/nifi-registry-web-ui/pom.xml
index 270af29..7240345 100644
--- a/nifi-registry-web-ui/pom.xml
+++ b/nifi-registry-web-ui/pom.xml
@@ -14,7 +14,8 @@
   limitations under the License.
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.nifi.registry</groupId>
@@ -25,26 +26,446 @@
     <artifactId>nifi-registry-web-ui</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <packaging>war</packaging>
-    <dependencies>
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>javax.servlet.jsp</groupId>
-            <artifactId>javax.servlet.jsp-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>javax.el</groupId>
-            <artifactId>javax.el-api</artifactId>
-            <scope>provided</scope>            
-        </dependency>
-        <dependency>
-            <groupId>javax.servlet.jsp.jstl</groupId>
-            <artifactId>javax.servlet.jsp.jstl-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
+    <properties>
+        <skipTests>true</skipTests>
+        <staging.dir>${project.build.directory}/tmp</staging.dir>
+        <registry.filter>registry-min.properties</registry.filter>
+        <frontend.source>${basedir}/src/main</frontend.source>
+        <frontend.dependency.configs>${basedir}/src/main/frontend</frontend.dependency.configs>
+        <frontend.working.dir>${project.build.directory}/frontend-working-directory</frontend.working.dir>
+        <frontend.assets>${project.build.directory}/${project.build.finalName}/node_modules</frontend.assets>
+    </properties>
+    <build>
+        <!--
+            These filters are used to populate the includes (css and js)
+            for each of the available pages. The property is the name of
+            the file which contains the properties that define which
+            css and js files get included. When running with minify and
+            compression (default) the filter properties will be overridden
+            in the profile. The JSPs that contain the HEAD portion of the
+            pages will not be pre-compiled and will instead be filtered
+            when the war is built.
+        -->
+        <filters>
+            <filter>src/main/resources/filters/${registry.filter}</filter>
+        </filters>
+        <plugins>
+            <!--
+                Precompile jsp's and add entries into the web.xml - the web.xml
+                is automatically places in ${project.build.directory}. Do not
+                precompile index.jsp, etc.
+                These jsp's need to have the artifacts version filtered in to
+                eliminate browser caching issues and set up the proper includes.
+                Since the webResource filter occurs after the precompilation we
+                must exclude them here.
+            -->
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-jspc-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>jspc</goal>
+                        </goals>
+                        <configuration>
+                            <keepSources>true</keepSources>
+                            <useProvidedScope>true</useProvidedScope>
+                            <excludes>
+                                **/index.jsp
+                            </excludes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <!--
+                        Filter the web.xml that was generated from jspc to specify the
+                        NiFi Registry base directory. The plugin configuration is
+                        specified here while the execution's are defined below in the
+                        profiles to bind to the appropriate phase.
+                    -->
+                    <execution>
+                        <id>copy-web-xml</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${staging.dir}/WEB-INF</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.build.directory}</directory>
+                                    <filtering>true</filtering>
+                                    <includes>
+                                        <include>web.xml</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Copy build and test configs into frontend working directory.
+                    -->
+                    <execution>
+                        <id>copy-client-side-build-and-test-configs</id>
+                        <phase>initialize</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${frontend.working.dir}</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.dependency.configs}</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <include>*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Copy src into frontend working directory.
+                    -->
+                    <execution>
+                        <id>copy-source</id>
+                        <phase>initialize</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${frontend.working.dir}</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.source}</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <include>locale/**/*</include>
+                                        <include>webapp/**/*</include>
+                                        <include>platform/**/*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Simulate an npm installed FDS.
+                    -->
+                    <execution>
+                        <id>copy-fluid-design-system</id>
+                        <phase>process-sources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${frontend.working.dir}/node_modules/@fluid-design-system/dist
+                            </outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.working.dir}</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <include>platform/**/*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Stage client side node_modules dependencies for inclusion in .war.
+                    -->
+                    <execution>
+                        <id>copy-client-side-deps</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${frontend.assets}</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.working.dir}/node_modules</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <!-- roboto -->
+                                        <include>roboto-fontface/fonts/Roboto/Roboto-Regular.ttf</include>
+                                        <include>roboto-fontface/fonts/Roboto/Roboto-Medium.ttf</include>
+                                        <include>roboto-fontface/fonts/Roboto/Roboto-Light.ttf</include>
+                                        <include>roboto-fontface/fonts/Roboto/Roboto-Bold.ttf</include>
+                                        <include>roboto-fontface/LICENSE*</include>
+                                        <!-- covalent -->
+                                        <include>@covalent/core/common/platform.css</include>
+                                        <include>@covalent/core/common/styles/font/MaterialIcons-Regular.woff2</include>
+                                        <include>@covalent/core/common/styles/font/MaterialIcons-Regular.ttf</include>
+                                        <include>@covalent/core/README.md</include>
+                                        <!-- FDS -->
+                                        <include>
+                                            @fluid-design-system/dist/platform/core/common/styles/css/*
+                                        </include>
+                                        <include>@fluid-design-system/dist/platform/core/dialogs/**/*</include>
+                                        <include>@fluid-design-system/dist/platform/core/LICENSE.md</include>
+                                        <!-- font-awesome -->
+                                        <include>font-awesome/css/font-awesome.css</include>
+                                        <include>font-awesome/fonts/fontawesome-webfont.woff2</include>
+                                        <include>font-awesome/fonts/fontawesome-webfont.ttf</include>
+                                        <include>font-awesome/README.md</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Stage client side styles.
+                    -->
+                    <execution>
+                        <id>copy-webapp-client-side-styles</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/${project.build.finalName}/css</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.working.dir}/webapp/css</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <include>*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!--
+                Tell the war plugin where to find the filtered web.xml and
+                filter the head portion of the pages. The correct includes and
+                project version is filtered into these jsp's as a browser cache
+                buster.
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <configuration>
+                    <webXml>${staging.dir}/WEB-INF/web.xml</webXml>
+                    <webResources>
+                        <resource>
+                            <directory>src/main/webapp/WEB-INF/pages</directory>
+                            <targetPath>WEB-INF/pages</targetPath>
+                            <includes>
+                                <include>index.jsp</include>
+                            </includes>
+                            <filtering>true</filtering>
+                        </resource>
+                    </webResources>
+                </configuration>
+            </plugin>
+            <!--
+                Skip tests by default
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.12.4</version>
+                <configuration>
+                    <skipTests>${skipTests}</skipTests>
+                </configuration>
+            </plugin>
+            <!--
+                Speed up build time by excluding node, npm, and any node_modules from `mvn clean` since the front-end-maven plugin uses these
+                directories as cache.
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-clean-plugin</artifactId>
+                <version>3.0.0</version>
+                <configuration>
+                    <excludeDefaultDirectories>true</excludeDefaultDirectories>
+                    <filesets>
+                        <fileset>
+                            <directory>${project.build.directory}</directory>
+                            <includes>
+                                <include>**</include>
+                            </includes>
+                            <excludes>
+                                <exclude>frontend-working-directory/node/**/*</exclude>
+                                <exclude>frontend-working-directory/node_modules/**/*</exclude>
+                            </excludes>
+                        </fileset>
+                    </filesets>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+                <version>1.5</version>
+                <configuration>
+                    <installDirectory>${frontend.working.dir}</installDirectory>
+                </configuration>
+                <executions>
+                    <!--
+                        Install node and npm.
+                    -->
+                    <execution>
+                        <id>install-node-and-npm</id>
+                        <goals>
+                            <goal>install-node-and-npm</goal>
+                        </goals>
+                        <phase>initialize</phase>
+                        <configuration>
+                            <nodeVersion>v6.11.1</nodeVersion>
+                            <npmVersion>3.10.10</npmVersion>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Install node_modules (build, test, AND client side dependencies).
+                    -->
+                    <execution>
+                        <id>npm-install</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>initialize</phase>
+                        <configuration>
+                            <arguments>--silent --cache-min Infinity install</arguments>
+                            <workingDirectory>${frontend.working.dir}</workingDirectory>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Compile FDS SASS into css and gzip compress it.
+                    -->
+                    <execution>
+                        <id>grunt-compile-fds-sass</id>
+                        <goals>
+                            <goal>grunt</goal>
+                        </goals>
+                        <phase>generate-sources</phase>
+                        <configuration>
+                            <arguments>compile-fds-styles</arguments>
+                            <workingDirectory>${frontend.working.dir}</workingDirectory>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Selenium, Karma/Jasmine JS unit tests.
+                    -->
+                    <execution>
+                        <id>javascript-tests</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>test</phase>
+                        <configuration>
+                            <arguments>run test:ci</arguments>
+                            <workingDirectory>${frontend.working.dir}</workingDirectory>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Compile nifi registry web ui SASS into css and gzip compress it.
+                    -->
+                    <execution>
+                        <id>grunt-compile-web-ui-sass</id>
+                        <goals>
+                            <goal>grunt</goal>
+                        </goals>
+                        <phase>generate-resources</phase>
+                        <configuration>
+                            <arguments>compile-web-ui-styles</arguments>
+                            <workingDirectory>${frontend.working.dir}</workingDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+                <version>1.5</version>
+                <executions>
+                    <!--
+                        Bundle, minify, and gzip compress all the javascript.
+                    -->
+                    <execution>
+                        <id>grunt-package-web-ui</id>
+                        <goals>
+                            <goal>grunt</goal>
+                        </goals>
+                        <phase>generate-resources</phase>
+                        <configuration>
+                            <arguments>bundle-web-ui</arguments>
+                            <workingDirectory>${frontend.working.dir}</workingDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <!--
+                        Stage the final bundle of JS to be included in the .war
+                    -->
+                    <execution>
+                        <id>copy-web-ui-bundle</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/${project.build.finalName}
+                            </outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.working.dir}/webapp</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <include>nf-registry.bundle.*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!--
+                        Stage the localization files to be included in the .war
+                    -->
+                    <execution>
+                        <id>copy-localization</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/${project.build.finalName}
+                            </outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${frontend.working.dir}/locale</directory>
+                                    <filtering>false</filtering>
+                                    <includes>
+                                        <include>*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes combine.children="append">
+                        <exclude>nbactions.xml</exclude>
+                        <exclude>src/main/frontend/package.json</exclude>
+                        <exclude>src/main/platform/core/package.json</exclude>
+                        <exclude>src/main/platform/core/README.md</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-ui/src/main/frontend/Gruntfile.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/Gruntfile.js b/nifi-registry-web-ui/src/main/frontend/Gruntfile.js
new file mode 100644
index 0000000..5ec5c61
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/frontend/Gruntfile.js
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+module.exports = function (grunt) {
+    // load all grunt tasks matching the ['grunt-*', '@*/grunt-*'] patterns
+    require('load-grunt-tasks')(grunt);
+
+    grunt.initConfig({
+        sass: {
+            options: {
+                outputStyle: 'compressed',
+                sourceMap: true
+            },
+            minifyFds: {
+                files: [{
+                    './platform/core/common/styles/css/fluid-design-system.min.css': ['./platform/core/common/styles/fluid-design-system.scss']
+                }]
+            },
+            minifyWebUi: {
+                files: [{
+                    './webapp/css/nf-registry.min.css': ['./webapp/theming/nf-registry.scss']
+                }]
+            }
+        },
+        systemjs: {
+            options: {
+                sfx: true,
+                minify: true, // Comment out this line when developing
+                sourceMaps: true,
+                build: {
+                    lowResSourceMaps: true
+                }
+            },
+            bundleWebUi: {
+                options: {
+                    configFile: "./webapp/systemjs.builder.config.js"
+                },
+                files: [{
+                    "src": "./webapp/nf-registry-bootstrap.js",
+                    "dest": "./webapp/nf-registry.bundle.min.js"
+                }]
+            }
+        },
+        compress: {
+            options: {
+                mode: 'gzip'
+            },
+            webUi: {
+                files: [{
+                    expand: true,
+                    src: ['./webapp/nf-registry.bundle.min.js'],
+                    dest: './',
+                    ext: '.bundle.min.js.gz'
+                }]
+            },
+            webUiStyles: {
+                files: [{
+                    expand: true,
+                    src: ['./webapp/css/nf-registry.min.css'],
+                    dest: './',
+                    ext: '.min.css.gz'
+                }]
+            },
+            fdsStyles: {
+                files: [{
+                    expand: true,
+                    src: ['./platform/core/common/styles/css/fluid-design-system.min.css'],
+                    dest: './',
+                    ext: '.min.css.gz'
+                }]
+            }
+        }
+    });
+    grunt.registerTask('compile-fds-styles', ['sass:minifyFds', 'compress:fdsStyles']);
+    grunt.registerTask('compile-web-ui-styles', ['sass:minifyWebUi', 'compress:webUiStyles']);
+    grunt.registerTask('bundle-web-ui', ['systemjs:bundleWebUi', 'compress:webUi']);
+};

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-ui/src/main/frontend/karma-test-shim.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/karma-test-shim.js b/nifi-registry-web-ui/src/main/frontend/karma-test-shim.js
new file mode 100644
index 0000000..d0a524d
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/frontend/karma-test-shim.js
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+// /*global jasmine, __karma__, window*/
+Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
+
+// Uncomment to get full stacktrace output. Sometimes helpful, usually not.
+// Error.stackTraceLimit = Infinity; //
+
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
+
+// builtPaths: root paths for output ("built") files
+// get from karma.config.js, then prefix with '/base/'
+var builtPaths = (__karma__.config.builtPaths)
+    .map(function (p) {
+        return '/base/' + p;
+    });
+
+__karma__.loaded = function () {
+};
+
+function isJsFile(path) {
+    return path.slice(-3) == '.js';
+}
+
+function isSpecFile(path) {
+    return /\.spec\.(.*\.)?js$/.test(path);
+}
+
+// Is a "built" file if is JavaScript file in one of the "built" folders
+function isBuiltFile(path) {
+    return isJsFile(path) &&
+        builtPaths.reduce(function (keep, bp) {
+            return keep || (path.substr(0, bp.length) === bp);
+        }, false);
+}
+
+var allSpecFiles = Object.keys(window.__karma__.files)
+    .filter(isSpecFile)
+    .filter(isBuiltFile);
+
+System.config({
+    // Base URL for System.js calls. 'base/' is where Karma serves files from.
+    baseURL: 'base',
+
+    // Map the angular testing umd bundles
+    map: {
+        '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
+        '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
+        '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
+        '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
+        '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
+        '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
+        '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
+        '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js'
+    }
+});
+
+System.import('webapp/systemjs.spec.config.js')
+    .then(importSystemJsExtras)
+    .then(initTestBed)
+    .then(initTesting);
+
+/** Optional SystemJS configuration extras. Keep going w/o it */
+function importSystemJsExtras() {
+    return System.import('webapp/systemjs.config.extras.js')
+        .catch(function (reason) {
+            console.log(
+                'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.'
+            );
+            console.log(reason);
+        });
+}
+
+function initTestBed() {
+    return Promise.all([
+        System.import('@angular/core/testing'),
+        System.import('@angular/platform-browser-dynamic/testing')
+    ])
+
+        .then(function (providers) {
+            var coreTesting = providers[0];
+            var browserTesting = providers[1];
+
+            coreTesting.TestBed.initTestEnvironment(
+                browserTesting.BrowserDynamicTestingModule,
+                browserTesting.platformBrowserDynamicTesting());
+        })
+}
+
+// Import all spec files and start karma
+function initTesting() {
+    return Promise.all(
+        allSpecFiles.map(function (moduleName) {
+            return System.import(moduleName);
+        })
+    )
+        .then(__karma__.start, __karma__.error);
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-ui/src/main/frontend/karma.conf.ci.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/karma.conf.ci.js b/nifi-registry-web-ui/src/main/frontend/karma.conf.ci.js
new file mode 100644
index 0000000..c03db0d
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/frontend/karma.conf.ci.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+var baseConfig = require('./karma.conf.js');
+
+module.exports = function (config) {
+    // Load base config
+    baseConfig(config);
+
+    if (process.env.TRAVIS) {
+        config.set({
+            browsers: ['Chrome_travis_ci']
+        });
+    }
+
+    // Override base config
+    config.set({
+        singleRun: true,
+        autoWatch: false,
+        reporters: ['progress', 'spec', 'coverage'],
+        specReporter: {
+            failFast: true
+        }
+    });
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-ui/src/main/frontend/karma.conf.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/karma.conf.js b/nifi-registry-web-ui/src/main/frontend/karma.conf.js
new file mode 100644
index 0000000..f3946b7
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/frontend/karma.conf.js
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+module.exports = function (config) {
+
+    var appBase = 'webapp/';       // app JS and map files
+
+    config.set({
+        basePath: '',
+        frameworks: ['jasmine'],
+
+        plugins: [
+            require('karma-jasmine'),
+            require('karma-chrome-launcher'),
+            require('karma-jasmine-html-reporter'),
+            require('karma-spec-reporter'),
+            require('karma-coverage')
+        ],
+
+        client: {
+            builtPaths: [appBase], // add more spec base paths as needed
+            clearContext: false // leave Jasmine Spec Runner output visible in browser
+        },
+
+        files: [
+            // System.js for module loading
+            'node_modules/systemjs/dist/system.src.js',
+
+            // Polyfills
+            'node_modules/core-js/client/shim.js',
+
+            // zone.js
+            'node_modules/zone.js/dist/zone.js',
+            'node_modules/zone.js/dist/long-stack-trace-zone.js',
+            'node_modules/zone.js/dist/proxy.js',
+            'node_modules/zone.js/dist/sync-test.js',
+            'node_modules/zone.js/dist/jasmine-patch.js',
+            'node_modules/zone.js/dist/async-test.js',
+            'node_modules/zone.js/dist/fake-async-test.js',
+            'node_modules/hammerjs/hammer.js',
+
+            // RxJs
+            {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
+            {pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false},
+
+            // Paths loaded via module imports:
+            {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
+            {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false},
+            {pattern: 'node_modules/@covalent/**/*.js', included: false, watched: false},
+            {pattern: 'node_modules/@covalent/**/*.js.map', included: false, watched: false},
+            {pattern: 'node_modules/@fluid-design-system/**/*.js', included: false, watched: false},
+            {pattern: 'node_modules/jquery/**/*.js', included: false, watched: false},
+            {pattern: 'node_modules/roboto-fontface/**/*.ttf', included: false, watched: false},
+            {pattern: 'node_modules/systemjs-plugin-text/text.js', included: false, watched: false},
+
+            {pattern: appBase + 'systemjs.spec.config.js', included: false, watched: false},
+            'karma-test-shim.js', // optionally extend SystemJS mapping e.g., with barrels
+
+            // Include the Fluid Design System (which includes the Teradata Covalent and
+            // Angular Material themes) in the test suite.
+            {
+                pattern: 'node_modules/@fluid-design-system/dist/platform/core/common/styles/css/fluid-design-system.min.css',
+                included: true,
+                watched: true,
+                served: true
+            },
+            {
+                pattern: 'node_modules/@fluid-design-system/dist/platform/core/common/styles/css/fluid-design-system.min.css.map',
+                included: false,
+                watched: false
+            },
+
+            // Include the Nifi Registry styles (currently built based off of the
+            // @fluid-design-system/dist/platform/core/common/styles/_globalVars.scss)
+            {
+                pattern: 'webapp/css/nf-registry.min.css',
+                included: true,
+                watched: true
+            },
+            {
+                pattern: 'webapp/css/nf-registry.min.css.map',
+                included: false,
+                watched: false
+            },
+
+            // Asset (HTML) paths loaded via Angular's component compiler
+            // (these paths need to be rewritten, see proxies section)
+            // {pattern: appBase + '**/*.html', included: false, watched: true},
+
+            // Images
+            {pattern: '**/*.svg', watched: false, included: false, served: true},
+
+            // Paths for debugging with source maps in dev tools
+            {pattern: appBase + '**/*.js', included: false, watched: false}
+        ],
+
+        // Proxied base paths for loading assets
+        proxies: {
+            // required for modules fetched by SystemJS
+            '/base/nifi-registry/node_modules/': '/base/node_modules/',
+            '/base/systemjs-angular-loader.js': '/base/webapp/systemjs-angular-loader.js',
+            '/base/nifi-registry/': '/base/webapp/',
+            '/nifi-registry/images/': '/base/webapp/images/'
+        },
+
+        exclude: [],
+        preprocessors: {
+            'webapp/**/!(*spec|*mock).js': 'coverage',
+            'platform/**/!(*spec|*mock).js': 'coverage'
+        },
+        reporters: ['progress', 'kjhtml', 'spec', 'coverage'],
+        coverageReporter: {
+            type: 'html',
+            dir: 'coverage/'
+        },
+        specReporter: {
+            failFast: false
+        },
+        port: 9876,
+        colors: true,
+        logLevel: config.LOG_INFO,
+        autoWatch: true,
+        browsers: ['Chrome'],
+        singleRun: false
+    })
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7fa56bea/nifi-registry-web-ui/src/main/frontend/package.json
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/package.json b/nifi-registry-web-ui/src/main/frontend/package.json
new file mode 100644
index 0000000..7317475
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/frontend/package.json
@@ -0,0 +1,65 @@
+{
+  "name": "nifi-registry",
+  "version": "0.0.1",
+  "description": "",
+  "scripts": {
+    "protractor": "protractor protractor.config.js",
+    "test:dev": "./node_modules/protractor/bin/webdriver-manager update --gecko false && karma start karma.conf.js",
+    "test:ci": "./node_modules/protractor/bin/webdriver-manager update --gecko false && karma start karma.conf.ci.js",
+    "test:once": "karma start karma.conf.js --single-run"
+  },
+  "keywords": [],
+  "author": "",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/apache/nifi-registry"
+  },
+  "dependencies": {
+    "@covalent/core": "1.0.0-beta.6",
+    "angular2-moment": "1.6.0",
+    "font-awesome": "4.7.0",
+    "moment": "2.18.1",
+    "roboto-fontface": "0.7.0"
+  },
+  "devDependencies": {
+    "@angular/animations": "4.2.0",
+    "@angular/cdk": "2.0.0-beta.8",
+    "@angular/common": "4.2.0",
+    "@angular/compiler": "4.2.0",
+    "@angular/core": "4.2.0",
+    "@angular/flex-layout": "2.0.0-beta.8",
+    "@angular/forms": "4.2.0",
+    "@angular/http": "4.2.0",
+    "@angular/material": "2.0.0-beta.6",
+    "@angular/platform-browser": "4.2.0",
+    "@angular/platform-browser-dynamic": "4.2.0",
+    "@angular/router": "4.2.0",
+    "canonical-path": "0.0.2",
+    "grunt": "0.4.5",
+    "grunt-cli": "1.2.0",
+    "grunt-contrib-compress": "1.4.3",
+    "grunt-sass": "2.0.0",
+    "grunt-systemjs-builder": "1.0.0",
+    "hammerjs": "2.0.8",
+    "jasmine-core": "2.4.1",
+    "jquery": "3.2.1",
+    "karma": "1.7.0",
+    "karma-chrome-launcher": "2.0.0",
+    "karma-cli": "1.0.1",
+    "karma-coverage": "1.1.1",
+    "karma-jasmine": "1.0.2",
+    "karma-jasmine-html-reporter": "0.2.2",
+    "karma-spec-reporter": "0.0.31",
+    "load-grunt-tasks": "3.5.2",
+    "lodash": "4.16.2",
+    "material-design-icons": "3.0.1",
+    "protractor": "4.0.14",
+    "reset-css": "2.2.0",
+    "rxjs": "5.4.3",
+    "systemjs": "0.20.17",
+    "systemjs-plugin-text": "0.0.11",
+    "zone.js": "0.8.4"
+  },
+  "bundleDependencies": [],
+  "private": true
+}