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 2016/04/04 18:28:37 UTC

[01/18] nifi git commit: Updating versions to 1.0.0-SNAPSHOT.

Repository: nifi
Updated Branches:
  refs/heads/master 16108467c -> 9f7dba491


http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/pom.xml
index 0258db3..6b99d56 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/pom.xml
@@ -19,12 +19,12 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-hbase_1_1_2-client-service-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-api/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-api/pom.xml
index 5044db8..99a2cf7 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-api/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-api/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
   
     <artifactId>nifi-http-context-map-api</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map-nar/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map-nar/pom.xml
index dea4ce2..84a4ddb 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-http-context-map-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 	
     <artifactId>nifi-http-context-map-nar</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map/pom.xml
index fd3f258..6a1481b 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/nifi-http-context-map/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-http-context-map-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-http-context-map</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/pom.xml
index 0d3e752..c79952d 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-http-context-map-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-http-context-map-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-load-distribution-service-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-load-distribution-service-api/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-load-distribution-service-api/pom.xml
index d217981..91e7eab 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-load-distribution-service-api/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-load-distribution-service-api/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-load-distribution-service-api</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-nar/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-nar/pom.xml
index ee92a0a..91347c4 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-ssl-context-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ssl-context-service-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/pom.xml
index a20e6b2..2c8b85f 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/nifi-ssl-context-service/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-ssl-context-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ssl-context-service</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/pom.xml
index 9c2b09c..307cca1 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ssl-context-bundle</artifactId>
     <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/pom.xml
index 6ce4b02..4c862f7 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-ssl-context-service-api/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ssl-context-service-api</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
index 944db38..7d0ca2d 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-standard-services-api-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/pom.xml b/nifi-nar-bundles/nifi-standard-services/pom.xml
index 27d664c..e11ad3d 100644
--- a/nifi-nar-bundles/nifi-standard-services/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-standard-services</artifactId>
     <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
index 93b0301..fbde46c 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-update-attribute-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-update-attribute-model</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-nar/pom.xml b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-nar/pom.xml
index ec34d03..258f42d 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-update-attribute-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-update-attribute-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/pom.xml b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/pom.xml
index ed454a7..7192509 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/pom.xml
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-processor/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-update-attribute-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-update-attribute-processor</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml
index 4a515fc..4363a1f 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-update-attribute-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-update-attribute-ui</artifactId>
     <packaging>war</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-update-attribute-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/pom.xml b/nifi-nar-bundles/nifi-update-attribute-bundle/pom.xml
index 3f77f2d..f3299d6 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-update-attribute-bundle</artifactId>
     <packaging>pom</packaging>
@@ -34,18 +34,18 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-update-attribute-model</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-update-attribute-processor</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-update-attribute-ui</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/pom.xml b/nifi-nar-bundles/pom.xml
index 914e213..7ed2da8 100644
--- a/nifi-nar-bundles/pom.xml
+++ b/nifi-nar-bundles/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-nar-bundles</artifactId>
@@ -65,81 +65,81 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-distributed-cache-client-service</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-distributed-cache-client-service-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ssl-context-service-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-load-distribution-service-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
              <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-http-context-map-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-distributed-cache-protocol</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-distributed-cache-server</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ssl-context-service</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-http-context-map</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-volatile-provenance-repository</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>test</scope>
             </dependency>
             <!-- The following dependencies are marked provided because they must be provided by the container.  Nars can assume they are there-->
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-runtime</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-nar-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-properties</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>provided</scope>
             </dependency>
         </dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e9a46da..dc764b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@ language governing permissions and limitations under the License. -->
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <description>Apache NiFi is an easy to use, powerful, and reliable system to process and distribute data.</description>
     <modules>
@@ -788,67 +788,67 @@ language governing permissions and limitations under the License. -->
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-site-to-site-client</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-expression-language</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-custom-ui-utilities</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ui-extension</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-flowfile-packager</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-socket-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-data-provenance-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-runtime</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-bootstrap</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-resources</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <classifier>resources</classifier>
                 <scope>runtime</scope>
                 <type>zip</type>
@@ -856,7 +856,7 @@ language governing permissions and limitations under the License. -->
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-docs</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <classifier>resources</classifier>
                 <scope>runtime</scope>
                 <type>zip</type>
@@ -864,304 +864,304 @@ language governing permissions and limitations under the License. -->
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-framework-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-provenance-repository-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-standard-services-api-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ssl-context-service-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-distributed-cache-services-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-standard-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-jetty-bundle</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-update-attribute-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hadoop-libraries-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hadoop-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-html-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-kite-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-mongodb-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-solr-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-kafka-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-http-context-map-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-social-media-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hl7-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-language-translation-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-geo-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-aws-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-flume-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-dbcp-service-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ambari-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-avro-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-image-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-couchbase-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-riemann-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-amqp-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-jms-cf-service-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-jms-processors-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-spring-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hbase_1_1_2-client-service-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hbase-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-azure-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ldap-iaa-providers-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-kerberos-iaa-providers-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-scripting-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-elasticsearch-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
 		<type>nar</type>
 	    </dependency>
 	    <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-splunk-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-cassandra-nar</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <type>nar</type>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-properties</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-security-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-logging-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-nar-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-processor-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hadoop-utils</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-mock</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-write-ahead-log</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-dbcp-service</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-dbcp-service-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hbase-client-service-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>com.jayway.jsonpath</groupId>


[16/18] nifi git commit: NIFI-483: Use ZooKeeper's Leader Election to determine Primary Node. This closes #301

Posted by mc...@apache.org.
NIFI-483: Use ZooKeeper's Leader Election to determine Primary Node. This closes #301

Signed-off-by: Matt Gilman <ma...@gmail.com>


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

Branch: refs/heads/master
Commit: 1ac05266a5cbab0c05551fc40201376cca13b540
Parents: 0d3bd2c
Author: Mark Payne <ma...@hotmail.com>
Authored: Wed Mar 23 13:16:13 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Apr 4 11:47:08 2016 -0400

----------------------------------------------------------------------
 nifi-assembly/pom.xml                           |   6 +
 .../org/apache/nifi/util/NiFiProperties.java    |   9 +
 .../protocol/ClusterManagerProtocolSender.java  |   9 -
 .../impl/ClusterManagerProtocolSenderImpl.java  |  27 --
 .../ClusterManagerProtocolSenderListener.java   |   7 -
 .../protocol/jaxb/message/ObjectFactory.java    |   5 -
 .../message/PrimaryRoleAssignmentMessage.java   |  55 ----
 .../protocol/message/ProtocolMessage.java       |   1 -
 .../nifi/cluster/manager/ClusterManager.java    |  18 --
 .../cluster/manager/impl/WebClusterManager.java | 199 +------------
 .../nifi-framework/nifi-framework-core/pom.xml  |   9 +
 .../apache/nifi/controller/FlowController.java  | 103 ++++---
 .../nifi/controller/StandardFlowService.java    |  40 ---
 .../election/CuratorLeaderElectionManager.java  | 285 +++++++++++++++++++
 .../leader/election/LeaderElectionManager.java  |  71 +++++
 .../LeaderElectionStateChangeListener.java      |  35 +++
 .../src/main/resources/conf/nifi.properties     |   6 +
 .../nifi/web/StandardNiFiServiceFacade.java     |   6 -
 pom.xml                                         |  13 +
 19 files changed, 495 insertions(+), 409 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index 0422b8e..09a8d50 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -456,6 +456,12 @@ language governing permissions and limitations under the License. -->
         <nifi.cluster.manager.protocol.threads>10</nifi.cluster.manager.protocol.threads>
         <nifi.cluster.manager.safemode.duration>0 sec</nifi.cluster.manager.safemode.duration>
 
+        <!--  nifi.properties: zookeeper properties -->
+        <nifi.zookeeper.connect.string></nifi.zookeeper.connect.string>
+        <nifi.zookeeper.connect.timeout>3 secs</nifi.zookeeper.connect.timeout>
+        <nifi.zookeeper.session.timeout>3 secs</nifi.zookeeper.session.timeout>
+        <nifi.zookeeper.root.node>/nifi</nifi.zookeeper.root.node>
+
         <!-- nifi.properties: kerberos properties -->
         <nifi.kerberos.krb5.file> </nifi.kerberos.krb5.file>
         <nifi.kerberos.service.principal />

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
index 8c98c0b..517b19a 100644
--- a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
+++ b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
@@ -174,6 +174,12 @@ public class NiFiProperties extends Properties {
     public static final String CLUSTER_NODE_UNICAST_MANAGER_ADDRESS = "nifi.cluster.node.unicast.manager.address";
     public static final String CLUSTER_NODE_UNICAST_MANAGER_PROTOCOL_PORT = "nifi.cluster.node.unicast.manager.protocol.port";
 
+    // zookeeper properties
+    public static final String ZOOKEEPER_CONNECT_STRING = "nifi.zookeeper.connect.string";
+    public static final String ZOOKEEPER_CONNECT_TIMEOUT = "nifi.zookeeper.connect.timeout";
+    public static final String ZOOKEEPER_SESSION_TIMEOUT = "nifi.zookeeper.session.timeout";
+    public static final String ZOOKEEPER_ROOT_NODE = "nifi.zookeeper.root.node";
+
     // cluster manager properties
     public static final String CLUSTER_IS_MANAGER = "nifi.cluster.is.manager";
     public static final String CLUSTER_MANAGER_ADDRESS = "nifi.cluster.manager.address";
@@ -226,6 +232,9 @@ public class NiFiProperties extends Properties {
     public static final String DEFAULT_PERSISTENT_STATE_DIRECTORY = "./conf/state";
     public static final String DEFAULT_COMPONENT_STATUS_SNAPSHOT_FREQUENCY = "5 mins";
     public static final String DEFAULT_BORED_YIELD_DURATION = "10 millis";
+    public static final String DEFAULT_ZOOKEEPER_CONNECT_TIMEOUT = "3 secs";
+    public static final String DEFAULT_ZOOKEEPER_SESSION_TIMEOUT = "3 secs";
+    public static final String DEFAULT_ZOOKEEPER_ROOT_NODE = "/nifi";
 
     // cluster common defaults
     public static final String DEFAULT_CLUSTER_PROTOCOL_HEARTBEAT_INTERVAL = "5 sec";

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterManagerProtocolSender.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterManagerProtocolSender.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterManagerProtocolSender.java
index 10653ff..bdefbbf 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterManagerProtocolSender.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterManagerProtocolSender.java
@@ -19,7 +19,6 @@ package org.apache.nifi.cluster.protocol;
 import org.apache.nifi.cluster.protocol.message.DisconnectMessage;
 import org.apache.nifi.cluster.protocol.message.FlowRequestMessage;
 import org.apache.nifi.cluster.protocol.message.FlowResponseMessage;
-import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionRequestMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionResponseMessage;
 import org.apache.nifi.reporting.BulletinRepository;
@@ -57,14 +56,6 @@ public interface ClusterManagerProtocolSender {
     void disconnect(DisconnectMessage msg) throws ProtocolException;
 
     /**
-     * Sends an "assign primary role" message to a node.
-     *
-     * @param msg a message
-     * @throws ProtocolException if communication failed
-     */
-    void assignPrimaryRole(PrimaryRoleAssignmentMessage msg) throws ProtocolException;
-
-    /**
      * Sets the {@link BulletinRepository} that can be used to report bulletins
      *
      * @param bulletinRepository repo

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderImpl.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderImpl.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderImpl.java
index 636a6d3..fb9292e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderImpl.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderImpl.java
@@ -31,7 +31,6 @@ import org.apache.nifi.cluster.protocol.ProtocolMessageUnmarshaller;
 import org.apache.nifi.cluster.protocol.message.DisconnectMessage;
 import org.apache.nifi.cluster.protocol.message.FlowRequestMessage;
 import org.apache.nifi.cluster.protocol.message.FlowResponseMessage;
-import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage.MessageType;
 import org.apache.nifi.cluster.protocol.message.ReconnectionRequestMessage;
@@ -56,7 +55,6 @@ public class ClusterManagerProtocolSenderImpl implements ClusterManagerProtocolS
     private final ProtocolContext<ProtocolMessage> protocolContext;
     private final SocketConfiguration socketConfiguration;
     private int handshakeTimeoutSeconds;
-    private volatile BulletinRepository bulletinRepository;
 
     public ClusterManagerProtocolSenderImpl(final SocketConfiguration socketConfiguration, final ProtocolContext<ProtocolMessage> protocolContext) {
         if (socketConfiguration == null) {
@@ -71,7 +69,6 @@ public class ClusterManagerProtocolSenderImpl implements ClusterManagerProtocolS
 
     @Override
     public void setBulletinRepository(final BulletinRepository bulletinRepository) {
-        this.bulletinRepository = bulletinRepository;
     }
 
     /**
@@ -183,30 +180,6 @@ public class ClusterManagerProtocolSenderImpl implements ClusterManagerProtocolS
         }
     }
 
-    /**
-     * Assigns the primary role to a node.
-     *
-     * @param msg a message
-     *
-     * @throws ProtocolException if the message failed to be sent
-     */
-    @Override
-    public void assignPrimaryRole(final PrimaryRoleAssignmentMessage msg) throws ProtocolException {
-        Socket socket = null;
-        try {
-            socket = createSocket(msg.getNodeId(), true);
-
-            try {
-                // marshal message to output stream
-                final ProtocolMessageMarshaller<ProtocolMessage> marshaller = protocolContext.createMarshaller();
-                marshaller.marshal(msg, socket.getOutputStream());
-            } catch (final IOException ioe) {
-                throw new ProtocolException("Failed marshalling '" + msg.getType() + "' protocol message due to: " + ioe, ioe);
-            }
-        } finally {
-            SocketUtils.closeQuietly(socket);
-        }
-    }
 
     private void setConnectionHandshakeTimeoutOnSocket(final Socket socket) throws SocketException {
         // update socket timeout, if handshake timeout was set; otherwise use socket's current timeout

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderListener.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderListener.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderListener.java
index 8eb83a4..54d33a8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderListener.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/ClusterManagerProtocolSenderListener.java
@@ -26,7 +26,6 @@ import org.apache.nifi.cluster.protocol.ProtocolListener;
 import org.apache.nifi.cluster.protocol.message.DisconnectMessage;
 import org.apache.nifi.cluster.protocol.message.FlowRequestMessage;
 import org.apache.nifi.cluster.protocol.message.FlowResponseMessage;
-import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionRequestMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionResponseMessage;
 import org.apache.nifi.reporting.BulletinRepository;
@@ -108,10 +107,4 @@ public class ClusterManagerProtocolSenderListener implements ClusterManagerProto
     public void disconnect(DisconnectMessage msg) throws ProtocolException {
         sender.disconnect(msg);
     }
-
-    @Override
-    public void assignPrimaryRole(PrimaryRoleAssignmentMessage msg) throws ProtocolException {
-        sender.assignPrimaryRole(msg);
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
index 516b67e..25041ce 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
@@ -27,7 +27,6 @@ import org.apache.nifi.cluster.protocol.message.FlowResponseMessage;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
 import org.apache.nifi.cluster.protocol.message.MulticastProtocolMessage;
 import org.apache.nifi.cluster.protocol.message.PingMessage;
-import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionFailureMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionRequestMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionResponseMessage;
@@ -92,8 +91,4 @@ public class ObjectFactory {
     public ControllerStartupFailureMessage createControllerStartupFailureMessage() {
         return new ControllerStartupFailureMessage();
     }
-
-    public PrimaryRoleAssignmentMessage createPrimaryRoleAssignmentMessage() {
-        return new PrimaryRoleAssignmentMessage();
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/PrimaryRoleAssignmentMessage.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/PrimaryRoleAssignmentMessage.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/PrimaryRoleAssignmentMessage.java
deleted file mode 100644
index 4b7563a..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/PrimaryRoleAssignmentMessage.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.cluster.protocol.message;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.cluster.protocol.NodeIdentifier;
-import org.apache.nifi.cluster.protocol.jaxb.message.NodeIdentifierAdapter;
-
-/**
- */
-@XmlRootElement(name = "primaryRoleAssignmentMessage")
-public class PrimaryRoleAssignmentMessage extends ProtocolMessage {
-
-    private NodeIdentifier nodeId;
-
-    private boolean primary;
-
-    @XmlJavaTypeAdapter(NodeIdentifierAdapter.class)
-    public NodeIdentifier getNodeId() {
-        return nodeId;
-    }
-
-    public void setNodeId(NodeIdentifier nodeId) {
-        this.nodeId = nodeId;
-    }
-
-    public boolean isPrimary() {
-        return primary;
-    }
-
-    public void setPrimary(boolean primary) {
-        this.primary = primary;
-    }
-
-    @Override
-    public MessageType getType() {
-        return MessageType.PRIMARY_ROLE;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
index f01efd8..5953e09 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
@@ -31,7 +31,6 @@ public abstract class ProtocolMessage {
         FLOW_RESPONSE,
         HEARTBEAT,
         PING,
-        PRIMARY_ROLE,
         RECONNECTION_REQUEST,
         RECONNECTION_RESPONSE,
         SERVICE_BROADCAST,

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
index 51de54b..27ada88 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
@@ -23,9 +23,7 @@ import org.apache.nifi.cluster.event.Event;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeDeletionException;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeDisconnectionException;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeReconnectionException;
-import org.apache.nifi.cluster.manager.exception.IneligiblePrimaryNodeException;
 import org.apache.nifi.cluster.manager.exception.NodeDisconnectionException;
-import org.apache.nifi.cluster.manager.exception.PrimaryRoleAssignmentException;
 import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.node.Node;
 import org.apache.nifi.cluster.node.Node.Status;
@@ -142,22 +140,6 @@ public interface ClusterManager extends NodeInformant {
     List<Event> getNodeEvents(final String nodeId);
 
     /**
-     * Revokes the primary role from the current primary node and assigns the primary role to given given node ID.
-     *
-     * If role revocation fails, then the current primary node is set to disconnected while retaining the primary role and no role assignment is performed.
-     *
-     * If role assignment fails, then the given node is set to disconnected and is given the primary role.
-     *
-     * @param nodeId the node identifier
-     * @param userDn the Distinguished Name of the user requesting that the Primary Node be assigned
-     *
-     * @throws UnknownNodeException if the node with the given identifier does not exist
-     * @throws IneligiblePrimaryNodeException if the node with the given identifier is not eligible to be the primary node
-     * @throws PrimaryRoleAssignmentException if the cluster was unable to change the primary role to the requested node
-     */
-    void setPrimaryNode(String nodeId, String userDn) throws UnknownNodeException, IneligiblePrimaryNodeException, PrimaryRoleAssignmentException;
-
-    /**
      * @return the primary node of the cluster or null if no primary node exists
      */
     Node getPrimaryNode();

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
index 303e98e..6f1bc2c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
@@ -93,12 +93,10 @@ import org.apache.nifi.cluster.manager.exception.IllegalClusterStateException;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeDeletionException;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeDisconnectionException;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeReconnectionException;
-import org.apache.nifi.cluster.manager.exception.IneligiblePrimaryNodeException;
 import org.apache.nifi.cluster.manager.exception.NoConnectedNodesException;
 import org.apache.nifi.cluster.manager.exception.NoResponseFromNodesException;
 import org.apache.nifi.cluster.manager.exception.NodeDisconnectionException;
 import org.apache.nifi.cluster.manager.exception.NodeReconnectionException;
-import org.apache.nifi.cluster.manager.exception.PrimaryRoleAssignmentException;
 import org.apache.nifi.cluster.manager.exception.SafeModeMutableRequestException;
 import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.exception.UriConstructionException;
@@ -118,7 +116,6 @@ import org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage;
 import org.apache.nifi.cluster.protocol.message.ControllerStartupFailureMessage;
 import org.apache.nifi.cluster.protocol.message.DisconnectMessage;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
-import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage.MessageType;
 import org.apache.nifi.cluster.protocol.message.ReconnectionFailureMessage;
@@ -551,9 +548,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
                     servicesBroadcaster.start();
                 }
 
-                // start in safe mode
-                executeSafeModeTask();
-
                 // Load and start running Reporting Tasks
                 final byte[] serializedReportingTasks = clusterDataFlow.getReportingTasks();
                 if (serializedReportingTasks != null && serializedReportingTasks.length > 0) {
@@ -1312,88 +1306,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         }
     }
 
-    /**
-     * Messages the node to have the primary role. If the messaging fails, then the node is marked as disconnected.
-     *
-     * @param nodeId the node ID to assign primary role
-     *
-     * @return true if primary role assigned; false otherwise
-     */
-    private boolean assignPrimaryRole(final NodeIdentifier nodeId) {
-        writeLock.lock();
-        try {
-            // create primary role message
-            final PrimaryRoleAssignmentMessage msg = new PrimaryRoleAssignmentMessage();
-            msg.setNodeId(nodeId);
-            msg.setPrimary(true);
-            logger.info("Attempting to assign primary role to node: " + nodeId);
-
-            // message
-            senderListener.assignPrimaryRole(msg);
-
-            logger.info("Assigned primary role to node: " + nodeId);
-            addBulletin(nodeId, Severity.INFO, "Node assigned primary role");
-
-            // true indicates primary role assigned
-            return true;
-
-        } catch (final ProtocolException ex) {
-
-            logger.warn("Failed attempt to assign primary role to node " + nodeId + " due to " + ex);
-            addBulletin(nodeId, Severity.ERROR, "Failed to assign primary role to node due to: " + ex);
-
-            // mark node as disconnected and log/record the event
-            final Node node = getRawNode(nodeId.getId());
-            node.setStatus(Status.DISCONNECTED);
-            addEvent(node.getNodeId(), "Disconnected because of failed attempt to assign primary role.");
-
-            addBulletin(nodeId, Severity.WARNING, "Node disconnected because of failed attempt to assign primary role");
-
-            // false indicates primary role failed to be assigned
-            return false;
-        } finally {
-            writeLock.unlock("assignPrimaryRole");
-        }
-    }
-
-    /**
-     * Messages the node with the given node ID to no longer have the primary role. If the messaging fails, then the node is marked as disconnected.
-     *
-     * @return true if the primary role was revoked from the node; false otherwise
-     */
-    private boolean revokePrimaryRole(final NodeIdentifier nodeId) {
-        writeLock.lock();
-        try {
-            // create primary role message
-            final PrimaryRoleAssignmentMessage msg = new PrimaryRoleAssignmentMessage();
-            msg.setNodeId(nodeId);
-            msg.setPrimary(false);
-            logger.info("Attempting to revoke primary role from node: " + nodeId);
-
-            // send message
-            senderListener.assignPrimaryRole(msg);
-
-            logger.info("Revoked primary role from node: " + nodeId);
-            addBulletin(nodeId, Severity.INFO, "Primary Role revoked from node");
-
-            // true indicates primary role was revoked
-            return true;
-        } catch (final ProtocolException ex) {
-
-            logger.warn("Failed attempt to revoke primary role from node " + nodeId + " due to " + ex);
-
-            // mark node as disconnected and log/record the event
-            final Node node = getRawNode(nodeId.getId());
-            node.setStatus(Status.DISCONNECTED);
-            addEvent(node.getNodeId(), "Disconnected because of failed attempt to revoke primary role.");
-            addBulletin(node, Severity.ERROR, "Node disconnected because of failed attempt to revoke primary role");
-
-            // false indicates primary role failed to be revoked
-            return false;
-        } finally {
-            writeLock.unlock("revokePrimaryRole");
-        }
-    }
 
     private NodeIdentifier addRequestorDn(final NodeIdentifier nodeId, final String dn) {
         return new NodeIdentifier(nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort(),
@@ -1778,12 +1690,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
                     // get a raw reference to the node (if it doesn't exist, node will be null)
                     node = getRawNode(resolvedNodeIdentifier.getId());
 
-                    // if the node thinks it has the primary role, but the manager has assigned the role to a different node, then revoke the role
-                    if (mostRecentHeartbeat.isPrimary() && !isPrimaryNode(resolvedNodeIdentifier)) {
-                        addEvent(resolvedNodeIdentifier, "Heartbeat indicates node is running as primary node.  Revoking primary role because primary role is assigned to a different node.");
-                        revokePrimaryRole(resolvedNodeIdentifier);
-                    }
-
                     final boolean heartbeatIndicatesNotYetConnected = !mostRecentHeartbeat.isConnected();
 
                     if (isBlockedByFirewall(resolvedNodeIdentifier.getSocketAddress())) {
@@ -1871,6 +1777,10 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
 
                         // record heartbeat
                         node.setHeartbeat(mostRecentHeartbeat);
+
+                        if (mostRecentHeartbeat.isPrimary()) {
+                            setPrimaryNodeId(node.getNodeId());
+                        }
                     }
                 } catch (final Exception e) {
                     logger.error("Failed to process heartbeat from {}:{} due to {}",
@@ -1984,47 +1894,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         }
     }
 
-    @Override
-    public void setPrimaryNode(final String nodeId, final String userDn) throws UnknownNodeException, IneligiblePrimaryNodeException, PrimaryRoleAssignmentException {
-        writeLock.lock();
-        try {
-
-            final Node node = getNode(nodeId);
-            if (node == null) {
-                throw new UnknownNodeException("Node does not exist.");
-            } else if (Status.CONNECTED != node.getStatus()) {
-                throw new IneligiblePrimaryNodeException("Node must be connected before it can be assigned as the primary node.");
-            }
-
-            // revoke primary role
-            final Node primaryNode;
-            if ((primaryNode = getPrimaryNode()) != null) {
-                if (primaryNode.getStatus() == Status.DISCONNECTED) {
-                    throw new PrimaryRoleAssignmentException("A disconnected, primary node exists.  Delete the node before assigning the primary role to a different node.");
-                } else if (revokePrimaryRole(primaryNode.getNodeId())) {
-                    addEvent(primaryNode.getNodeId(), "Role revoked from this node as part of primary role reassignment.");
-                } else {
-                    throw new PrimaryRoleAssignmentException(
-                            "Failed to revoke primary role from node. Primary node is now disconnected. Delete the node before assigning the primary role to a different node.");
-                }
-            }
-
-            // change the primary node ID to the given node
-            setPrimaryNodeId(node.getNodeId());
-
-            // assign primary role
-            if (assignPrimaryRole(node.getNodeId())) {
-                addEvent(node.getNodeId(), "Role assigned to this node as part of primary role reassignment. Action performed by " + userDn);
-                addBulletin(node, Severity.INFO, "Primary Role assigned to node by " + userDn);
-            } else {
-                throw new PrimaryRoleAssignmentException(
-                        "Cluster manager assigned primary role to node, but the node failed to accept the assignment.  Cluster manager disconnected node.");
-            }
-        } finally {
-            writeLock.unlock("setPrimaryNode");
-        }
-    }
-
     private int getClusterProtocolHeartbeatSeconds() {
         return (int) FormatUtils.getTimeDuration(properties.getClusterProtocolHeartbeatInterval(), TimeUnit.SECONDS);
     }
@@ -4508,66 +4377,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         }
     }
 
-    private void executeSafeModeTask() {
-
-        new Thread(new Runnable() {
-
-            private final long threadStartTime = System.currentTimeMillis();
-
-            @Override
-            public void run() {
-                logger.info("Entering safe mode...");
-                final int safeModeSeconds = (int) FormatUtils.getTimeDuration(properties.getClusterManagerSafeModeDuration(), TimeUnit.SECONDS);
-                final long timeToElect = safeModeSeconds <= 0 ? Long.MAX_VALUE : threadStartTime + TimeUnit.MILLISECONDS.convert(safeModeSeconds, TimeUnit.SECONDS);
-                boolean exitSafeMode = false;
-                while (isRunning()) {
-
-                    writeLock.lock();
-                    try {
-
-                        final long currentTime = System.currentTimeMillis();
-                        if (timeToElect < currentTime) {
-                            final Set<NodeIdentifier> connectedNodeIds = getNodeIds(Status.CONNECTED);
-                            if (!connectedNodeIds.isEmpty()) {
-                                // get first connected node ID
-                                final NodeIdentifier connectedNodeId = connectedNodeIds.iterator().next();
-                                if (assignPrimaryRole(connectedNodeId)) {
-                                    try {
-                                        setPrimaryNodeId(connectedNodeId);
-                                        exitSafeMode = true;
-                                    } catch (final DaoException de) {
-                                        final String message = String.format("Failed to persist primary node ID '%s' in cluster dataflow.", connectedNodeId);
-                                        logger.warn(message);
-                                        addBulletin(connectedNodeId, Severity.WARNING, message);
-                                        revokePrimaryRole(connectedNodeId);
-                                    }
-                                }
-                            }
-                        }
-
-                        if (!isInSafeMode()) {
-                            // a primary node has been selected outside of this thread
-                            exitSafeMode = true;
-                            logger.info("Exiting safe mode because " + primaryNodeId + " has been assigned the primary role.");
-                            break;
-                        }
-                    } finally {
-                        writeLock.unlock("executeSafeModeTask");
-                    }
-
-                    if (!exitSafeMode) {
-                        // sleep for a bit
-                        try {
-                            Thread.sleep(1000);
-                        } catch (final InterruptedException ie) {
-                            return;
-                        }
-                    }
-
-                }
-            }
-        }).start();
-    }
 
     /**
      * This timer task simply processes any pending heartbeats. This timer task is not strictly needed, as HeartbeatMonitoringTimerTask will do this. However, this task is scheduled much more

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
index dc5b7d3..ff3ecba 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
@@ -131,6 +131,15 @@
 
         <dependency>
             <groupId>org.apache.curator</groupId>
+            <artifactId>curator-framework</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
             <artifactId>curator-test</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
index 632fa1a..9f14354 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
@@ -83,6 +83,9 @@ import org.apache.nifi.controller.exception.ComponentLifeCycleException;
 import org.apache.nifi.controller.exception.ProcessorInstantiationException;
 import org.apache.nifi.controller.label.Label;
 import org.apache.nifi.controller.label.StandardLabel;
+import org.apache.nifi.controller.leader.election.CuratorLeaderElectionManager;
+import org.apache.nifi.controller.leader.election.LeaderElectionManager;
+import org.apache.nifi.controller.leader.election.LeaderElectionStateChangeListener;
 import org.apache.nifi.controller.queue.FlowFileQueue;
 import org.apache.nifi.controller.queue.QueueSize;
 import org.apache.nifi.controller.reporting.ReportingTaskInstantiationException;
@@ -231,6 +234,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
 
     public static final String ROOT_GROUP_ID_ALIAS = "root";
     public static final String DEFAULT_ROOT_GROUP_NAME = "NiFi Flow";
+    public static final String PRIMARY_NODE_ROLE_NAME = "primary-node";
 
     private final AtomicInteger maxTimerDrivenThreads;
     private final AtomicInteger maxEventDrivenThreads;
@@ -277,6 +281,8 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
     private ProcessGroup rootGroup;
     private final List<Connectable> startConnectablesAfterInitialization;
     private final List<RemoteGroupPort> startRemoteGroupPortsAfterInitialization;
+    private final LeaderElectionManager leaderElectionManager;
+
 
     /**
      * true if controller is configured to operate in a clustered environment
@@ -329,12 +335,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
 
     // guarded by rwLock
     /**
-     * true if controller is the primary of the cluster
-     */
-    private boolean primary;
-
-    // guarded by rwLock
-    /**
      * true if connected to a cluster
      */
     private boolean connected;
@@ -527,6 +527,11 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
         }, snapshotMillis, snapshotMillis, TimeUnit.MILLISECONDS);
 
         heartbeatBeanRef.set(new HeartbeatBean(rootGroup, false, false));
+        if (configuredForClustering) {
+            leaderElectionManager = new CuratorLeaderElectionManager(4);
+        } else {
+            leaderElectionManager = null;
+        }
     }
 
     private static FlowFileRepository createFlowFileRepository(final NiFiProperties properties, final ResourceClaimManager contentClaimManager) {
@@ -1159,6 +1164,10 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
                 throw new IllegalStateException("Controller already stopped or still stopping...");
             }
 
+            if (leaderElectionManager != null) {
+                leaderElectionManager.stop();
+            }
+
             if (kill) {
                 this.timerDrivenEngineRef.get().shutdownNow();
                 this.eventDrivenEngineRef.get().shutdownNow();
@@ -1365,7 +1374,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             }
 
             // update the heartbeat bean
-            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, primary, connected));
+            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, isPrimary(), connected));
         } finally {
             writeLock.unlock();
         }
@@ -3119,6 +3128,19 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             // update the bulletin repository
             if (isChanging) {
                 if (clustered) {
+                    leaderElectionManager.register(PRIMARY_NODE_ROLE_NAME, new LeaderElectionStateChangeListener() {
+                        @Override
+                        public void onLeaderElection() {
+                            setPrimary(true);
+                        }
+
+                        @Override
+                        public void onLeaderRelinquish() {
+                            setPrimary(false);
+                        }
+                    });
+
+                    leaderElectionManager.start();
                     stateManagerProvider.enableClusterProvider();
 
                     if (zooKeeperStateServer != null) {
@@ -3157,6 +3179,8 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
                         LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1L));
                     }
                 } else {
+                    leaderElectionManager.unregister(PRIMARY_NODE_ROLE_NAME);
+
                     if (zooKeeperStateServer != null) {
                         zooKeeperStateServer.shutdown();
                     }
@@ -3170,7 +3194,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             }
 
             // update the heartbeat bean
-            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, primary, connected));
+            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, isPrimary(), connected));
         } finally {
             writeLock.unlock();
         }
@@ -3180,51 +3204,38 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
      * @return true if this instance is the primary node in the cluster; false otherwise
      */
     public boolean isPrimary() {
-        rwLock.readLock().lock();
-        try {
-            return primary;
-        } finally {
-            rwLock.readLock().unlock();
-        }
+        return leaderElectionManager != null && leaderElectionManager.isLeader(PRIMARY_NODE_ROLE_NAME);
     }
 
     public void setPrimary(final boolean primary) {
-        rwLock.writeLock().lock();
-        try {
-            // no update, so return
-            if (this.primary == primary) {
-                return;
-            }
-
-            LOG.info("Setting primary flag from '" + this.primary + "' to '" + primary + "'");
-
-            final PrimaryNodeState nodeState = primary ? PrimaryNodeState.ELECTED_PRIMARY_NODE : PrimaryNodeState.PRIMARY_NODE_REVOKED;
-            final ProcessGroup rootGroup = getGroup(getRootGroupId());
-            for (final ProcessorNode procNode : rootGroup.findAllProcessors()) {
-                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
-                    ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnPrimaryNodeStateChange.class, procNode.getProcessor(), nodeState);
-                }
+        final PrimaryNodeState nodeState = primary ? PrimaryNodeState.ELECTED_PRIMARY_NODE : PrimaryNodeState.PRIMARY_NODE_REVOKED;
+        final ProcessGroup rootGroup = getGroup(getRootGroupId());
+        for (final ProcessorNode procNode : rootGroup.findAllProcessors()) {
+            try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnPrimaryNodeStateChange.class, procNode.getProcessor(), nodeState);
             }
-            for (final ControllerServiceNode serviceNode : getAllControllerServices()) {
-                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
-                    ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnPrimaryNodeStateChange.class, serviceNode.getControllerServiceImplementation(), nodeState);
-                }
+        }
+        for (final ControllerServiceNode serviceNode : getAllControllerServices()) {
+            try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnPrimaryNodeStateChange.class, serviceNode.getControllerServiceImplementation(), nodeState);
             }
-            for (final ReportingTaskNode reportingTaskNode : getAllReportingTasks()) {
-                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
-                    ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnPrimaryNodeStateChange.class, reportingTaskNode.getReportingTask(), nodeState);
-                }
+        }
+        for (final ReportingTaskNode reportingTaskNode : getAllReportingTasks()) {
+            try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnPrimaryNodeStateChange.class, reportingTaskNode.getReportingTask(), nodeState);
             }
+        }
 
-            // update primary
-            this.primary = primary;
-            eventDrivenWorkerQueue.setPrimary(primary);
+        // update primary
+        eventDrivenWorkerQueue.setPrimary(primary);
 
-            // update the heartbeat bean
-            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, primary, connected));
-        } finally {
-            rwLock.writeLock().unlock();
-        }
+        // update the heartbeat bean
+        this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, primary, connected));
+
+        // Emit a bulletin detailing the fact that the primary node state has changed
+        final String message = primary ? "This node has been elected Primary Node" : "This node is no longer Primary Node";
+        final Bulletin bulletin = BulletinFactory.createBulletin("Primary Node", Severity.INFO.name(), message);
+        bulletinRepository.addBulletin(bulletin);
     }
 
     static boolean areEqual(final String a, final String b) {
@@ -3603,7 +3614,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             this.connected = connected;
 
             // update the heartbeat bean
-            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, primary, connected));
+            this.heartbeatBeanRef.set(new HeartbeatBean(rootGroup, isPrimary(), connected));
         } finally {
             rwLock.writeLock().unlock();
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowService.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowService.java
index 6250c5a..67d0338 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowService.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowService.java
@@ -55,7 +55,6 @@ import org.apache.nifi.cluster.protocol.message.ControllerStartupFailureMessage;
 import org.apache.nifi.cluster.protocol.message.DisconnectMessage;
 import org.apache.nifi.cluster.protocol.message.FlowRequestMessage;
 import org.apache.nifi.cluster.protocol.message.FlowResponseMessage;
-import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionFailureMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionRequestMessage;
@@ -342,7 +341,6 @@ public class StandardFlowService implements FlowService, ProtocolHandler {
             case RECONNECTION_REQUEST:
             case DISCONNECTION_REQUEST:
             case FLOW_REQUEST:
-            case PRIMARY_ROLE:
                 return true;
             default:
                 return false;
@@ -381,14 +379,6 @@ public class StandardFlowService implements FlowService, ProtocolHandler {
                     }, "Disconnect from Cluster").start();
 
                     return null;
-                case PRIMARY_ROLE:
-                    new Thread(new Runnable() {
-                        @Override
-                        public void run() {
-                            handlePrimaryRoleAssignment((PrimaryRoleAssignmentMessage) request);
-                        }
-                    }, "Set Primary Role Status").start();
-                    return null;
                 default:
                     throw new ProtocolException("Handler cannot handle message type: " + request.getType());
             }
@@ -512,14 +502,6 @@ public class StandardFlowService implements FlowService, ProtocolHandler {
         }
     }
 
-    private void handlePrimaryRoleAssignment(final PrimaryRoleAssignmentMessage msg) {
-        writeLock.lock();
-        try {
-            controller.setPrimary(msg.isPrimary());
-        } finally {
-            writeLock.unlock();
-        }
-    }
 
     private void handleReconnectionRequest(final ReconnectionRequestMessage request) {
         writeLock.lock();
@@ -747,9 +729,6 @@ public class StandardFlowService implements FlowService, ProtocolHandler {
 
             controller.setConnected(true);
 
-            // set primary
-            controller.setPrimary(response.isPrimary());
-
             // start the processors as indicated by the dataflow
             controller.onFlowInitialized(dataFlow.isAutoStartProcessors());
 
@@ -862,7 +841,6 @@ public class StandardFlowService implements FlowService, ProtocolHandler {
     }
 
     private class SaveHolder {
-
         private final Calendar saveTime;
         private final boolean shouldArchive;
 
@@ -871,22 +849,4 @@ public class StandardFlowService implements FlowService, ProtocolHandler {
             shouldArchive = archive;
         }
     }
-
-    public boolean isPrimary() {
-        readLock.lock();
-        try {
-            return controller.isPrimary();
-        } finally {
-            readLock.unlock();
-        }
-    }
-
-    public void setPrimary(boolean primary) {
-        writeLock.lock();
-        try {
-            controller.setPrimary(primary);
-        } finally {
-            writeLock.unlock();
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/CuratorLeaderElectionManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/CuratorLeaderElectionManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/CuratorLeaderElectionManager.java
new file mode 100644
index 0000000..4c0cbd0
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/CuratorLeaderElectionManager.java
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.leader.election;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.recipes.leader.LeaderSelector;
+import org.apache.curator.framework.recipes.leader.LeaderSelectorListener;
+import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
+import org.apache.curator.framework.state.ConnectionState;
+import org.apache.curator.retry.RetryForever;
+import org.apache.nifi.engine.FlowEngine;
+import org.apache.nifi.util.FormatUtils;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.zookeeper.common.PathUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CuratorLeaderElectionManager implements LeaderElectionManager {
+    private static final Logger logger = LoggerFactory.getLogger(CuratorLeaderElectionManager.class);
+
+    private final FlowEngine leaderElectionMonitorEngine;
+    private final int sessionTimeoutMs;
+    private final int connectionTimeoutMs;
+    private final String rootPath;
+    private final String connectString;
+
+    private CuratorFramework curatorClient;
+
+    private volatile boolean stopped = true;
+
+    private final Map<String, LeaderRole> leaderRoles = new HashMap<>();
+    private final Map<String, LeaderElectionStateChangeListener> registeredRoles = new HashMap<>();
+
+    public CuratorLeaderElectionManager(final int threadPoolSize) {
+        leaderElectionMonitorEngine = new FlowEngine(threadPoolSize, "Leader Election Notification", true);
+
+        final NiFiProperties properties = NiFiProperties.getInstance();
+
+        connectString = properties.getProperty(NiFiProperties.ZOOKEEPER_CONNECT_STRING);
+        if (connectString == null || connectString.trim().isEmpty()) {
+            throw new IllegalStateException("The '" + NiFiProperties.ZOOKEEPER_CONNECT_STRING + "' property is not set in nifi.properties");
+        }
+
+        sessionTimeoutMs = getTimePeriod(properties, NiFiProperties.ZOOKEEPER_SESSION_TIMEOUT, NiFiProperties.DEFAULT_ZOOKEEPER_SESSION_TIMEOUT);
+        connectionTimeoutMs = getTimePeriod(properties, NiFiProperties.ZOOKEEPER_CONNECT_TIMEOUT, NiFiProperties.DEFAULT_ZOOKEEPER_CONNECT_TIMEOUT);
+        rootPath = properties.getProperty(NiFiProperties.ZOOKEEPER_ROOT_NODE, NiFiProperties.DEFAULT_ZOOKEEPER_ROOT_NODE);
+
+        try {
+            PathUtils.validatePath(rootPath);
+        } catch (final IllegalArgumentException e) {
+            throw new IllegalStateException("The '" + NiFiProperties.ZOOKEEPER_ROOT_NODE + "' property in nifi.properties is set to an illegal value: " + rootPath);
+        }
+    }
+
+
+    @Override
+    public synchronized void start() {
+        if (!stopped) {
+            return;
+        }
+
+        stopped = false;
+
+        final RetryPolicy retryPolicy = new RetryForever(5000);
+        curatorClient = CuratorFrameworkFactory.newClient(connectString, sessionTimeoutMs, connectionTimeoutMs, retryPolicy);
+        curatorClient.start();
+
+        // Call #register for each already-registered role. This will
+        // cause us to start listening for leader elections for that
+        // role again
+        for (final Map.Entry<String, LeaderElectionStateChangeListener> entry : registeredRoles.entrySet()) {
+            register(entry.getKey(), entry.getValue());
+        }
+
+        logger.info("{} started", this);
+    }
+
+    private int getTimePeriod(final NiFiProperties properties, final String propertyName, final String defaultValue) {
+        final String timeout = properties.getProperty(propertyName, defaultValue);
+        try {
+            return (int) FormatUtils.getTimeDuration(timeout, TimeUnit.MILLISECONDS);
+        } catch (final Exception e) {
+            logger.warn("Value of '" + propertyName + "' property is set to '" + timeout + "', which is not a valid time period. Using default of " + defaultValue);
+            return (int) FormatUtils.getTimeDuration(defaultValue, TimeUnit.MILLISECONDS);
+        }
+    }
+
+
+    @Override
+    public synchronized void register(final String roleName) {
+        register(roleName, null);
+    }
+
+
+    @Override
+    public synchronized void register(final String roleName, final LeaderElectionStateChangeListener listener) {
+        logger.debug("{} Registering new Leader Selector for role {}", this, roleName);
+
+        if (leaderRoles.containsKey(roleName)) {
+            logger.warn("{} Attempted to register Leader Election for role '{}' but this role is already registered", this, roleName);
+            return;
+        }
+
+        final String leaderPath = (rootPath.endsWith("/") ? "" : "/") + "leaders/" + roleName;
+
+        try {
+            PathUtils.validatePath(rootPath);
+        } catch (final IllegalArgumentException e) {
+            throw new IllegalStateException("Cannot register leader election for role '" + roleName + "' because this is not a valid role name");
+        }
+
+        registeredRoles.put(roleName, listener);
+
+        if (!isStopped()) {
+            final ElectionListener electionListener = new ElectionListener(roleName, listener);
+            final LeaderSelector leaderSelector = new LeaderSelector(curatorClient, leaderPath, leaderElectionMonitorEngine, electionListener);
+            leaderSelector.autoRequeue();
+            leaderSelector.start();
+
+            final LeaderRole leaderRole = new LeaderRole(leaderSelector, electionListener);
+
+            leaderRoles.put(roleName, leaderRole);
+        }
+        logger.info("{} Registered new Leader Selector for role {}", this, roleName);
+    }
+
+    @Override
+    public synchronized void unregister(final String roleName) {
+        registeredRoles.remove(roleName);
+
+        final LeaderRole leaderRole = leaderRoles.remove(roleName);
+        final LeaderSelector leaderSelector = leaderRole.getLeaderSelector();
+        if (leaderSelector == null) {
+            logger.warn("Cannot unregister Leader Election Role '{}' becuase that role is not registered", roleName);
+            return;
+        }
+
+        leaderSelector.close();
+    }
+
+    @Override
+    public synchronized void stop() {
+        stopped = true;
+
+        for (final LeaderRole role : leaderRoles.values()) {
+            final LeaderSelector selector = role.getLeaderSelector();
+            selector.close();
+        }
+
+        leaderRoles.clear();
+
+        if (curatorClient != null) {
+            curatorClient.close();
+            curatorClient = null;
+        }
+
+        logger.info("{} stopped and closed", this);
+    }
+
+    @Override
+    public boolean isStopped() {
+        return stopped;
+    }
+
+
+    @Override
+    public String toString() {
+        return "CuratorLeaderElectionManager[stopped=" + isStopped() + "]";
+    }
+
+
+    @Override
+    public synchronized boolean isLeader(final String roleName) {
+        final LeaderRole role = leaderRoles.get(roleName);
+        if (role == null) {
+            return false;
+        }
+
+        return role.isLeader();
+    }
+
+
+    private static class LeaderRole {
+        private final LeaderSelector leaderSelector;
+        private final ElectionListener electionListener;
+
+        public LeaderRole(final LeaderSelector leaderSelector, final ElectionListener electionListener) {
+            this.leaderSelector = leaderSelector;
+            this.electionListener = electionListener;
+        }
+
+        public LeaderSelector getLeaderSelector() {
+            return leaderSelector;
+        }
+
+        public boolean isLeader() {
+            return electionListener.isLeader();
+        }
+    }
+
+
+    private class ElectionListener extends LeaderSelectorListenerAdapter implements LeaderSelectorListener {
+        private final String roleName;
+        private final LeaderElectionStateChangeListener listener;
+
+        private volatile boolean leader;
+
+        public ElectionListener(final String roleName, final LeaderElectionStateChangeListener listener) {
+            this.roleName = roleName;
+            this.listener = listener;
+        }
+
+        public boolean isLeader() {
+            return leader;
+        }
+
+        @Override
+        public void stateChanged(final CuratorFramework client, final ConnectionState newState) {
+            logger.info("{} Connection State changed to {}", this, newState.name());
+            super.stateChanged(client, newState);
+        }
+
+        @Override
+        public void takeLeadership(final CuratorFramework client) throws Exception {
+            leader = true;
+            logger.info("{} This node has been elected Leader for Role '{}'", this, roleName);
+
+            if (listener != null) {
+                leaderElectionMonitorEngine.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        listener.onLeaderElection();
+                    }
+                });
+            }
+
+            // Curator API states that we lose the leadership election when we return from this method,
+            // so we will block as long as we are not interrupted or closed. Then, we will set leader to false.
+            try {
+                while (!isStopped()) {
+                    try {
+                        Thread.sleep(1000L);
+                    } catch (final InterruptedException ie) {
+                        logger.info("{} has been interrupted; no longer leader for role '{}'", this, roleName);
+                        Thread.currentThread().interrupt();
+                        return;
+                    }
+                }
+            } finally {
+                leader = false;
+                logger.info("{} This node is no longer leader for role '{}'", this, roleName);
+
+                if (listener != null) {
+                    leaderElectionMonitorEngine.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            listener.onLeaderRelinquish();
+                        }
+                    });
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionManager.java
new file mode 100644
index 0000000..d16dbdb
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionManager.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.leader.election;
+
+public interface LeaderElectionManager {
+    /**
+     * Starts managing leader elections for all registered roles
+     */
+    void start();
+
+    /**
+     * Adds a new role for which a leader is required
+     *
+     * @param roleName the name of the role
+     */
+    void register(String roleName);
+
+    /**
+     * Adds a new role for which a leader is required
+     *
+     * @param roleName the name of the role
+     * @param listener a listener that will be called when the node gains or relinquishes
+     *            the role of leader
+     */
+    void register(String roleName, LeaderElectionStateChangeListener listener);
+
+    /**
+     * Removes the role with the given name from this manager. If this
+     * node is the elected leader for the given role, this node will relinquish
+     * the leadership role
+     *
+     * @param roleName the name of the role to unregister
+     */
+    void unregister(String roleName);
+
+    /**
+     * Returns a boolean value indicating whether or not this node
+     * is the elected leader for the given role
+     *
+     * @param roleName the name of the role
+     * @return <code>true</code> if the node is the elected leader, <code>false</code> otherwise.
+     */
+    boolean isLeader(String roleName);
+
+    /**
+     * @return <code>true</code> if the manager is stopped, false otherwise.
+     */
+    boolean isStopped();
+
+    /**
+     * Stops managing leader elections and relinquishes the role as leader
+     * for all registered roles. If the LeaderElectionManager is later started
+     * again, all previously registered roles will still be registered.
+     */
+    void stop();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionStateChangeListener.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionStateChangeListener.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionStateChangeListener.java
new file mode 100644
index 0000000..79c7a75
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/leader/election/LeaderElectionStateChangeListener.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.leader.election;
+
+/**
+ * Callback interface that can be used to listen for state changes so that the node
+ * can be notified when it becomes the Elected Leader for a role or is no longer the
+ * Elected Leader
+ */
+public interface LeaderElectionStateChangeListener {
+    /**
+     * This method is invoked whenever this node is elected leader
+     */
+    void onLeaderElection();
+
+    /**
+     * This method is invoked whenever this node no longer is the elected leader.
+     */
+    void onLeaderRelinquish();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
index 24d2295..beb71c1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
@@ -168,6 +168,12 @@ nifi.cluster.node.protocol.threads=${nifi.cluster.node.protocol.threads}
 nifi.cluster.node.unicast.manager.address=${nifi.cluster.node.unicast.manager.address}
 nifi.cluster.node.unicast.manager.protocol.port=${nifi.cluster.node.unicast.manager.protocol.port}
 
+# zookeeper properties, used for cluster management #
+nifi.zookeeper.connect.string=${nifi.zookeeper.connect.string}
+nifi.zookeeper.connect.timeout=${nifi.zookeeper.connect.timeout}
+nifi.zookeeper.session.timeout=${nifi.zookeeper.session.timeout}
+nifi.zookeeper.root.node=${nifi.zookeeper.root.node}
+
 # cluster manager properties (only configure for cluster manager) #
 nifi.cluster.is.manager=${nifi.cluster.is.manager}
 nifi.cluster.manager.address=${nifi.cluster.manager.address}

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index b981bde..4fdda06 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -760,12 +760,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
             clusterManager.requestReconnection(nodeDTO.getNodeId(), userDn);
         } else if (Node.Status.DISCONNECTING.name().equalsIgnoreCase(nodeDTO.getStatus())) {
             clusterManager.requestDisconnection(nodeDTO.getNodeId(), userDn);
-        } else {
-            // handle primary
-            final Boolean primary = nodeDTO.isPrimary();
-            if (primary != null && primary) {
-                clusterManager.setPrimaryNode(nodeDTO.getNodeId(), userDn);
-            }
         }
 
         final String nodeId = nodeDTO.getNodeId();

http://git-wip-us.apache.org/repos/asf/nifi/blob/1ac05266/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index dc764b0..442acdd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -765,6 +765,17 @@ language governing permissions and limitations under the License. -->
                 <artifactId>zookeeper</artifactId>
                 <version>3.4.6</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.curator</groupId>
+                <artifactId>curator-framework</artifactId>
+                <version>2.10.0</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.curator</groupId>
+                <artifactId>curator-recipes</artifactId>
+                <version>2.10.0</version>
+            </dependency>
+
             
             <!-- Test Dependencies for testing interactions with ZooKeeper -->
             <dependency>
@@ -779,6 +790,8 @@ language governing permissions and limitations under the License. -->
                 <version>6.8.8</version>
                 <scope>test</scope>
             </dependency>
+            
+            
             <dependency>            
                 <groupId>org.jsoup</groupId>
                 <artifactId>jsoup</artifactId>


[15/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don't have enough data points, even if all nodes do (which can be the case if the node performing the aggregation has a different value for the 'nifi.components.status.snapshot.frequency' property than the other nodes) - Bug fixes; code cleanup; replicate requests to bulletin board endpoint - Refactored the <Component>StatusDTO objects into <Component>StatusDTO, <Component>StatusSnapshotDTO, Node<Component>StatusSnapshotDTO objects - Introducing endpoints for accessing individual component status. - Wiring up new endpoints and updated core. - Code clean up. - Starting to handling status merging of individual components. - Nodewise breakdown has been added to Processors but the remaining components still need to be updated. - Refactor so that System Diagnostics re
 quests are replicated to nodes instead of the information being pulled from Heartbeats - Replicate request for counters instead of pulling them from heartbeats - Removed the getCounters / setCounters method from HeartbeatPayload - Implementing component specific endpoints. - Removing unused endpoints. - Supporting nodewise breakdown for system diagnostics and counters. - Updating DTOs to use more consistent naming. - Code clean up. - Addressing contrib issues. - Removed ProcessGroupStatus from HeartbeatPayload - Removing nodewise from the system diagnostics endpoint. Had included it for testing that option but did not intend for it to be committed. - Addressing comments in PR #294. - This closes #294

Signed-off-by: Matt Gilman <ma...@gmail.com>


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

Branch: refs/heads/master
Commit: 0d3bd2c401aacc5bcd602afe90883d751ff773f3
Parents: 2de7f3f
Author: Mark Payne <ma...@hotmail.com>
Authored: Thu Mar 3 13:29:34 2016 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Apr 4 11:42:39 2016 -0400

----------------------------------------------------------------------
 .../controller/status/ProcessGroupStatus.java   |   12 -
 .../org/apache/nifi/web/api/dto/CounterDTO.java |   13 +-
 .../apache/nifi/web/api/dto/CountersDTO.java    |   50 +-
 .../nifi/web/api/dto/CountersSnapshotDTO.java   |   73 +
 .../web/api/dto/NodeCountersSnapshotDTO.java    |   78 ++
 .../web/api/dto/NodeSystemDiagnosticsDTO.java   |   59 -
 .../dto/NodeSystemDiagnosticsSnapshotDTO.java   |   77 ++
 .../nifi/web/api/dto/SystemDiagnosticsDTO.java  |  478 +------
 .../api/dto/SystemDiagnosticsSnapshotDTO.java   |  549 ++++++++
 .../dto/status/ClusterConnectionStatusDTO.java  |   94 --
 .../status/ClusterProcessGroupStatusDTO.java    |  102 --
 .../dto/status/ClusterProcessorStatusDTO.java   |  127 --
 .../ClusterRemoteProcessGroupStatusDTO.java     |   94 --
 .../api/dto/status/ClusterStatusHistoryDTO.java |   79 --
 .../web/api/dto/status/ConnectionStatusDTO.java |  180 +--
 .../dto/status/ConnectionStatusSnapshotDTO.java |  279 ++++
 .../web/api/dto/status/ControllerStatusDTO.java |  134 +-
 .../api/dto/status/NodeConnectionStatusDTO.java |   60 -
 .../status/NodeConnectionStatusSnapshotDTO.java |   78 ++
 .../dto/status/NodePortStatusSnapshotDTO.java   |   77 ++
 .../dto/status/NodeProcessGroupStatusDTO.java   |   64 -
 .../NodeProcessGroupStatusSnapshotDTO.java      |   76 +
 .../api/dto/status/NodeProcessorStatusDTO.java  |   60 -
 .../status/NodeProcessorStatusSnapshotDTO.java  |   80 ++
 .../status/NodeRemotePortStatusSnapshotDTO.java |   77 ++
 .../status/NodeRemoteProcessGroupStatusDTO.java |   60 -
 ...NodeRemoteProcessGroupStatusSnapshotDTO.java |   77 ++
 .../api/dto/status/NodeStatusHistoryDTO.java    |   60 -
 .../api/dto/status/NodeStatusSnapshotsDTO.java  |   85 ++
 .../nifi/web/api/dto/status/PortStatusDTO.java  |  115 +-
 .../api/dto/status/PortStatusSnapshotDTO.java   |  194 +++
 .../api/dto/status/ProcessGroupStatusDTO.java   |  326 +----
 .../status/ProcessGroupStatusSnapshotDTO.java   |  532 +++++++
 .../web/api/dto/status/ProcessorStatusDTO.java  |  194 +--
 .../dto/status/ProcessorStatusSnapshotDTO.java  |  301 ++++
 .../web/api/dto/status/RemotePortStatusDTO.java |   12 +-
 .../dto/status/RemoteProcessGroupStatusDTO.java |  143 +-
 .../RemoteProcessGroupStatusSnapshotDTO.java    |  215 +++
 .../nifi/web/api/dto/status/StatusDTO.java      |   45 -
 .../web/api/dto/status/StatusHistoryDTO.java    |   66 +-
 .../api/dto/status/StatusHistoryDetailDTO.java  |   59 -
 .../entity/ClusterConnectionStatusEntity.java   |   43 -
 .../entity/ClusterProcessGroupStatusEntity.java |   43 -
 .../entity/ClusterProcessorStatusEntity.java    |   43 -
 .../ClusterRemoteProcessGroupStatusEntity.java  |   44 -
 .../api/entity/ClusterStatusHistoryEntity.java  |   43 -
 .../web/api/entity/ConnectionStatusEntity.java  |   44 +
 .../api/entity/NodeSystemDiagnosticsEntity.java |   43 -
 .../nifi/web/api/entity/PortStatusEntity.java   |   44 +
 .../web/api/entity/ProcessorStatusEntity.java   |   44 +
 .../entity/RemoteProcessGroupStatusEntity.java  |   44 +
 .../cluster/protocol/NodeProtocolSender.java    |   10 -
 .../protocol/impl/NodeProtocolSenderImpl.java   |    6 -
 .../impl/NodeProtocolSenderListener.java        |    6 -
 .../protocol/jaxb/message/ObjectFactory.java    |    5 -
 .../protocol/message/NodeBulletinsMessage.java  |   42 -
 .../protocol/message/ProtocolMessage.java       |    2 -
 .../nifi/cluster/manager/ClusterManager.java    |   13 -
 .../nifi/cluster/manager/StatusMerger.java      |  646 +++++++++
 .../manager/impl/ClusteredEventAccess.java      |    2 +-
 .../cluster/manager/impl/WebClusterManager.java | 1302 ++++++++++--------
 .../org/apache/nifi/controller/Heartbeater.java |   22 -
 .../service/ControllerServiceNode.java          |   13 +-
 .../apache/nifi/cluster/HeartbeatPayload.java   |   36 +-
 .../nifi/connectable/StandardConnection.java    |    9 +-
 .../apache/nifi/controller/FlowController.java  |  206 +--
 .../nifi/controller/StandardFlowFileQueue.java  |    8 +-
 .../scheduling/StandardProcessScheduler.java    |   11 +-
 .../service/StandardControllerServiceNode.java  |   23 +-
 .../history/ConnectionStatusDescriptor.java     |  110 ++
 .../history/ProcessGroupStatusDescriptor.java   |  143 ++
 .../history/ProcessorStatusDescriptor.java      |  220 +++
 .../RemoteProcessGroupStatusDescriptor.java     |  127 ++
 .../status/history/StatusHistoryUtil.java       |    4 +-
 .../VolatileComponentStatusRepository.java      |  418 +-----
 .../nifi/events/VolatileBulletinRepository.java |   20 -
 .../nifi/cluster/HeartbeatPayloadTest.java      |   56 +-
 .../controller/TestStandardFlowFileQueue.java   |    2 +-
 .../repository/TestStandardProcessSession.java  |    2 +-
 .../TestWriteAheadFlowFileRepository.java       |    2 +-
 .../TestStandardProcessScheduler.java           |    8 +-
 .../TestStandardControllerServiceProvider.java  |    4 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |  157 +--
 .../nifi/web/StandardNiFiServiceFacade.java     |  966 ++-----------
 .../nifi/web/api/ApplicationResource.java       |    2 +
 .../nifi/web/api/BulletinBoardResource.java     |   36 +-
 .../apache/nifi/web/api/ClusterResource.java    |  737 +---------
 .../apache/nifi/web/api/ConnectionResource.java |  112 +-
 .../apache/nifi/web/api/ControllerResource.java |  109 +-
 .../apache/nifi/web/api/InputPortResource.java  |  158 ++-
 .../org/apache/nifi/web/api/NodeResource.java   |  146 +-
 .../apache/nifi/web/api/OutputPortResource.java |  108 ++
 .../nifi/web/api/ProcessGroupResource.java      |  139 +-
 .../apache/nifi/web/api/ProcessorResource.java  |  189 ++-
 .../web/api/RemoteProcessGroupResource.java     |  170 ++-
 .../nifi/web/api/ReportingTaskResource.java     |   38 +-
 .../nifi/web/api/SystemDiagnosticsResource.java |   85 +-
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  346 +++--
 .../nifi/web/controller/ControllerFacade.java   |  120 ++
 .../src/main/resources/nifi-web-api-context.xml |    4 +
 .../cluster-connection-summary-dialog.jsp       |    1 +
 .../cluster-input-port-summary-dialog.jsp       |    1 +
 .../cluster-output-port-summary-dialog.jsp      |    1 +
 .../cluster-processor-summary-dialog.jsp        |    1 +
 ...ster-remote-process-group-summary-dialog.jsp |    1 +
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |   28 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |    3 +-
 .../src/main/webapp/js/nf/canvas/nf-graph.js    |   26 +-
 .../webapp/js/nf/counters/nf-counters-table.js  |    9 +-
 .../src/main/webapp/js/nf/nf-status-history.js  |  412 ++----
 .../webapp/js/nf/summary/nf-cluster-search.js   |   10 +-
 .../webapp/js/nf/summary/nf-summary-table.js    |  434 +++---
 .../src/main/webapp/js/nf/summary/nf-summary.js |    4 +-
 113 files changed, 7297 insertions(+), 6703 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java b/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java
index eb0339f..db16954 100644
--- a/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java
+++ b/nifi-api/src/main/java/org/apache/nifi/controller/status/ProcessGroupStatus.java
@@ -32,7 +32,6 @@ public class ProcessGroupStatus implements Cloneable {
     private Long inputContentSize;
     private Integer outputCount;
     private Long outputContentSize;
-    private long creationTimestamp;
     private Integer activeThreadCount;
     private Integer queuedCount;
     private Long queuedContentSize;
@@ -132,14 +131,6 @@ public class ProcessGroupStatus implements Cloneable {
         this.queuedContentSize = queuedContentSize;
     }
 
-    public long getCreationTimestamp() {
-        return creationTimestamp;
-    }
-
-    public void setCreationTimestamp(final long creationTimestamp) {
-        this.creationTimestamp = creationTimestamp;
-    }
-
     public Integer getActiveThreadCount() {
         return activeThreadCount;
     }
@@ -249,7 +240,6 @@ public class ProcessGroupStatus implements Cloneable {
 
         final ProcessGroupStatus clonedObj = new ProcessGroupStatus();
 
-        clonedObj.creationTimestamp = creationTimestamp;
         clonedObj.id = id;
         clonedObj.name = name;
         clonedObj.outputContentSize = outputContentSize;
@@ -332,8 +322,6 @@ public class ProcessGroupStatus implements Cloneable {
         builder.append(outputCount);
         builder.append(", outputBytes=");
         builder.append(outputContentSize);
-        builder.append(", creationTimestamp=");
-        builder.append(creationTimestamp);
         builder.append(", activeThreadCount=");
         builder.append(activeThreadCount);
         builder.append(", flowFilesTransferred=");

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
index 615ad93..b3315b9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
@@ -17,13 +17,14 @@
 package org.apache.nifi.web.api.dto;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
+
 import javax.xml.bind.annotation.XmlType;
 
 /**
  * Counter value for a specific component in a specific context. A counter is a value that a component can adjust during processing.
  */
 @XmlType(name = "counter")
-public class CounterDTO {
+public class CounterDTO implements Cloneable {
 
     private String id;
     private String context;
@@ -98,4 +99,14 @@ public class CounterDTO {
         this.valueCount = valueCount;
     }
 
+    @Override
+    public CounterDTO clone() {
+        final CounterDTO other = new CounterDTO();
+        other.setId(getId());
+        other.setName(getName());
+        other.setContext(getContext());
+        other.setValue(getValue());
+        other.setValueCount(getValueCount());
+        return other;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
index 0f162c9..e21d331 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
@@ -14,51 +14,37 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
-import java.util.Date;
+import java.util.List;
 
 import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
-/**
- * All the counters in this NiFi instance at a given time.
- */
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
 @XmlType(name = "counters")
 public class CountersDTO {
+    private CountersSnapshotDTO aggregateSnapshot;
+    private List<NodeCountersSnapshotDTO> nodeSnapshots;
 
-    private Date generated;
-    private Collection<CounterDTO> counters;
-
-    /**
-     * @return the collection of counters
-     */
-    @ApiModelProperty(
-            value = "All counters in the NiFi."
-    )
-    public Collection<CounterDTO> getCounters() {
-        return counters;
+    @ApiModelProperty("A Counters snapshot that represents the aggregate values of all nodes in the cluster. If the NiFi instance is "
+        + "a standalone instance, rather than a cluster, this represents the stats of the single instance.")
+    public CountersSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
     }
 
-    public void setCounters(Collection<CounterDTO> counters) {
-        this.counters = counters;
+    public void setAggregateSnapshot(CountersSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
     }
 
-    /**
-     * @return the date/time that this report was generated
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "The timestamp when the report was generated."
-    )
-    public Date getGenerated() {
-        return generated;
+    @ApiModelProperty("A Counters snapshot for each node in the cluster. If the NiFi instance is a standalone instance, rather than "
+        + "a cluster, this may be null.")
+    public List<NodeCountersSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
     }
 
-    public void setGenerated(Date generated) {
-        this.generated = generated;
+    public void setNodeSnapshots(List<NodeCountersSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersSnapshotDTO.java
new file mode 100644
index 0000000..1e1b389
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersSnapshotDTO.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+
+/**
+ * All the counters in this NiFi instance at a given time.
+ */
+@XmlType(name = "countersSnapshot")
+public class CountersSnapshotDTO implements Cloneable {
+
+    private Date generated;
+    private Collection<CounterDTO> counters;
+
+    @ApiModelProperty("All counters in the NiFi.")
+    public Collection<CounterDTO> getCounters() {
+        return counters;
+    }
+
+    public void setCounters(Collection<CounterDTO> counters) {
+        this.counters = counters;
+    }
+
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    @ApiModelProperty("The timestamp when the report was generated.")
+    public Date getGenerated() {
+        return generated;
+    }
+
+    public void setGenerated(Date generated) {
+        this.generated = generated;
+    }
+
+    @Override
+    public CountersSnapshotDTO clone() {
+        final CountersSnapshotDTO other = new CountersSnapshotDTO();
+        other.setGenerated(getGenerated());
+
+        final List<CounterDTO> clonedCounters = new ArrayList<>(getCounters().size());
+        for (final CounterDTO counterDto : getCounters()) {
+            clonedCounters.add(counterDto.clone());
+        }
+
+        other.setCounters(clonedCounters);
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeCountersSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeCountersSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeCountersSnapshotDTO.java
new file mode 100644
index 0000000..b7f19c7
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeCountersSnapshotDTO.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+@XmlType(name = "nodeProcessorStatusSnapshot")
+public class NodeCountersSnapshotDTO implements Cloneable {
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private CountersSnapshotDTO snapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The counters from the node.")
+    public CountersSnapshotDTO getSnapshot() {
+        return snapshot;
+    }
+
+    public void setSnapshot(CountersSnapshotDTO snapshot) {
+        this.snapshot = snapshot;
+    }
+
+    @Override
+    public NodeCountersSnapshotDTO clone() {
+        final NodeCountersSnapshotDTO other = new NodeCountersSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setSnapshot(getSnapshot().clone());
+        return other;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsDTO.java
deleted file mode 100644
index 8f925aa..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsDTO.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-
-/**
- * The system diagnostics for a node with this NiFi cluster.
- */
-@XmlType(name = "nodeSystemDiagnostics")
-public class NodeSystemDiagnosticsDTO {
-
-    private NodeDTO node;
-    private SystemDiagnosticsDTO systemDiagnostics;
-
-    /**
-     * @return the node
-     */
-    @ApiModelProperty(
-            value = "The node."
-    )
-    public NodeDTO getNode() {
-        return node;
-    }
-
-    public void setNode(NodeDTO node) {
-        this.node = node;
-    }
-
-    /**
-     * @return the system diagnostics
-     */
-    @ApiModelProperty(
-            value = "The diagnostics for the system the node is on."
-    )
-    public SystemDiagnosticsDTO getSystemDiagnostics() {
-        return systemDiagnostics;
-    }
-
-    public void setControllerStatus(SystemDiagnosticsDTO systemDiagnostics) {
-        this.systemDiagnostics = systemDiagnostics;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsSnapshotDTO.java
new file mode 100644
index 0000000..f27b05d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/NodeSystemDiagnosticsSnapshotDTO.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+@XmlType(name = "nodeSystemDiagnosticsSnapshot")
+public class NodeSystemDiagnosticsSnapshotDTO implements Cloneable {
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private SystemDiagnosticsSnapshotDTO snapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The System Diagnostics snapshot from the node.")
+    public SystemDiagnosticsSnapshotDTO getSnapshot() {
+        return snapshot;
+    }
+
+    public void setSnapshot(SystemDiagnosticsSnapshotDTO snapshot) {
+        this.snapshot = snapshot;
+    }
+
+    @Override
+    public NodeSystemDiagnosticsSnapshotDTO clone() {
+        final NodeSystemDiagnosticsSnapshotDTO other = new NodeSystemDiagnosticsSnapshotDTO();
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setNodeId(getNodeId());
+        other.setSnapshot(getSnapshot().clone());
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsDTO.java
index d2a9d1a..40a04d4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsDTO.java
@@ -14,478 +14,38 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Date;
-import java.util.Set;
+import java.util.List;
+
 import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
-/**
- * The diagnostics of the system this NiFi is running on.
- */
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
 @XmlType(name = "systemDiagnostics")
 public class SystemDiagnosticsDTO {
+    private SystemDiagnosticsSnapshotDTO aggregateSnapshot;
+    private List<NodeSystemDiagnosticsSnapshotDTO> nodeSnapshots;
 
-    private String totalNonHeap;
-    private String usedNonHeap;
-    private String freeNonHeap;
-    private String maxNonHeap;
-    private String nonHeapUtilization;
-
-    private String totalHeap;
-    private String usedHeap;
-    private String freeHeap;
-    private String maxHeap;
-    private String heapUtilization;
-
-    private Integer availableProcessors;
-    private Double processorLoadAverage;
-
-    private Integer totalThreads;
-    private Integer daemonThreads;
-
-    private StorageUsageDTO flowFileRepositoryStorageUsage;
-    private Set<StorageUsageDTO> contentRepositoryStorageUsage;
-    private Set<GarbageCollectionDTO> garbageCollection;
-
-    private Date statsLastRefreshed;
-
-    /* getters / setters */
-    /**
-     * @return number of available processors, if supported
-     */
-    @ApiModelProperty(
-            value = "Number of available processors if supported by the underlying system."
-    )
-    public Integer getAvailableProcessors() {
-        return availableProcessors;
-    }
-
-    public void setAvailableProcessors(Integer availableProcessors) {
-        this.availableProcessors = availableProcessors;
-    }
-
-    /**
-     * @return number of daemon threads
-     */
-    @ApiModelProperty(
-            value = "Number of daemon threads."
-    )
-    public Integer getDaemonThreads() {
-        return daemonThreads;
-    }
-
-    public void setDaemonThreads(Integer daemonThreads) {
-        this.daemonThreads = daemonThreads;
-    }
-
-    /**
-     * @return amount of free heap
-     */
-    @ApiModelProperty(
-            value = "Amount of free heap."
-    )
-    public String getFreeHeap() {
-        return freeHeap;
-    }
-
-    public void setFreeHeap(String freeHeap) {
-        this.freeHeap = freeHeap;
-    }
-
-    /**
-     * @return amount of free non-heap
-     */
-    @ApiModelProperty(
-            value = "Amount of free non heap."
-    )
-    public String getFreeNonHeap() {
-        return freeNonHeap;
-    }
-
-    public void setFreeNonHeap(String freeNonHeap) {
-        this.freeNonHeap = freeNonHeap;
-    }
-
-    /**
-     * @return max size of the heap
-     */
-    @ApiModelProperty(
-            value = "Maximum size of heap."
-    )
-    public String getMaxHeap() {
-        return maxHeap;
-    }
-
-    public void setMaxHeap(String maxHeap) {
-        this.maxHeap = maxHeap;
-    }
-
-    /**
-     * @return max size of the non-heap
-     */
-    @ApiModelProperty(
-            value = "Maximum size of non heap."
-    )
-    public String getMaxNonHeap() {
-        return maxNonHeap;
-    }
-
-    public void setMaxNonHeap(String maxNonHeap) {
-        this.maxNonHeap = maxNonHeap;
-    }
-
-    /**
-     * @return processor load average, if supported
-     */
-    @ApiModelProperty(
-            value = "The processor load average if supported by the underlying system."
-    )
-    public Double getProcessorLoadAverage() {
-        return processorLoadAverage;
-    }
-
-    public void setProcessorLoadAverage(Double processorLoadAverage) {
-        this.processorLoadAverage = processorLoadAverage;
-    }
-
-    /**
-     * @return total size of the heap
-     */
-    @ApiModelProperty(
-            value = "Total size of heap."
-    )
-    public String getTotalHeap() {
-        return totalHeap;
-    }
-
-    public void setTotalHeap(String totalHeap) {
-        this.totalHeap = totalHeap;
-    }
-
-    /**
-     * @return total size of non-heap
-     */
-    @ApiModelProperty(
-            value = "Total size of non heap."
-    )
-    public String getTotalNonHeap() {
-        return totalNonHeap;
-    }
-
-    public void setTotalNonHeap(String totalNonHeap) {
-        this.totalNonHeap = totalNonHeap;
-    }
-
-    /**
-     * @return total number of threads
-     */
-    @ApiModelProperty(
-            value = "Total number of threads."
-    )
-    public Integer getTotalThreads() {
-        return totalThreads;
-    }
-
-    public void setTotalThreads(Integer totalThreads) {
-        this.totalThreads = totalThreads;
-    }
-
-    /**
-     * @return amount of used heap
-     */
-    @ApiModelProperty(
-            value = "Amount of used heap."
-    )
-    public String getUsedHeap() {
-        return usedHeap;
-    }
-
-    public void setUsedHeap(String usedHeap) {
-        this.usedHeap = usedHeap;
-    }
-
-    /**
-     * @return amount of used non-heap
-     */
-    @ApiModelProperty(
-            value = "Amount of use non heap."
-    )
-    public String getUsedNonHeap() {
-        return usedNonHeap;
-    }
-
-    public void setUsedNonHeap(String usedNonHeap) {
-        this.usedNonHeap = usedNonHeap;
-    }
-
-    /**
-     * @return heap utilization
-     */
-    @ApiModelProperty(
-            value = "Utilization of heap."
-    )
-    public String getHeapUtilization() {
-        return heapUtilization;
-    }
-
-    public void setHeapUtilization(String heapUtilization) {
-        this.heapUtilization = heapUtilization;
-    }
-
-    /**
-     * @return non-heap utilization
-     */
-    @ApiModelProperty(
-            value = "Utilization of non heap."
-    )
-    public String getNonHeapUtilization() {
-        return nonHeapUtilization;
-    }
-
-    public void setNonHeapUtilization(String nonHeapUsage) {
-        this.nonHeapUtilization = nonHeapUsage;
-    }
-
-    /**
-     * @return content repository storage usage
-     */
-    @ApiModelProperty(
-            value = "The content repository storage usage."
-    )
-    public Set<StorageUsageDTO> getContentRepositoryStorageUsage() {
-        return contentRepositoryStorageUsage;
-    }
-
-    public void setContentRepositoryStorageUsage(Set<StorageUsageDTO> contentRepositoryStorageUsage) {
-        this.contentRepositoryStorageUsage = contentRepositoryStorageUsage;
-    }
-
-    /**
-     * @return flowfile repository storage usage
-     */
-    @ApiModelProperty(
-            value = "The flowfile repository storage usage."
-    )
-    public StorageUsageDTO getFlowFileRepositoryStorageUsage() {
-        return flowFileRepositoryStorageUsage;
-    }
-
-    public void setFlowFileRepositoryStorageUsage(StorageUsageDTO flowFileRepositoryStorageUsage) {
-        this.flowFileRepositoryStorageUsage = flowFileRepositoryStorageUsage;
-    }
-
-    /**
-     * @return Garbage collection details
-     */
-    @ApiModelProperty(
-            value = "The garbage collection details."
-    )
-    public Set<GarbageCollectionDTO> getGarbageCollection() {
-        return garbageCollection;
-    }
-
-    public void setGarbageCollection(Set<GarbageCollectionDTO> garbageCollection) {
-        this.garbageCollection = garbageCollection;
-    }
 
-    /**
-     * @return When these diagnostics were generated
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "When the diagnostics were generated."
-    )
-    public Date getStatsLastRefreshed() {
-        return statsLastRefreshed;
+    @ApiModelProperty("A systems diagnostic snapshot that represents the aggregate values of all nodes in the cluster. If the NiFi instance is "
+        + "a standalone instance, rather than a cluster, this represents the stats of the single instance.")
+    public SystemDiagnosticsSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
     }
 
-    public void setStatsLastRefreshed(Date statsLastRefreshed) {
-        this.statsLastRefreshed = statsLastRefreshed;
+    public void setAggregateSnapshot(SystemDiagnosticsSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
     }
 
-    /**
-     * Details of storage usage.
-     */
-    @XmlType(name = "storageUsage")
-    public static class StorageUsageDTO {
-
-        private String identifier;
-        private String freeSpace;
-        private String totalSpace;
-        private String usedSpace;
-        private Long freeSpaceBytes;
-        private Long totalSpaceBytes;
-        private Long usedSpaceBytes;
-        private String utilization;
-
-        /**
-         * @return identifier for this storage location
-         */
-        @ApiModelProperty(
-                value = "The identifier of this storage location. The identifier will correspond to the identifier keyed in the storage configuration."
-        )
-        public String getIdentifier() {
-            return identifier;
-        }
-
-        public void setIdentifier(String identifier) {
-            this.identifier = identifier;
-        }
-
-        /**
-         * @return amount of free space
-         */
-        @ApiModelProperty(
-                value = "Amount of free space."
-        )
-        public String getFreeSpace() {
-            return freeSpace;
-        }
-
-        public void setFreeSpace(String freeSpace) {
-            this.freeSpace = freeSpace;
-        }
-
-        /**
-         * @return freeSpace amount of total space
-         */
-        @ApiModelProperty(
-                value = "Amount of total space."
-        )
-        public String getTotalSpace() {
-            return totalSpace;
-        }
-
-        public void setTotalSpace(String totalSpace) {
-            this.totalSpace = totalSpace;
-        }
-
-        /**
-         * @return amount of used space
-         */
-        @ApiModelProperty(
-                value = "Amount of used space."
-        )
-        public String getUsedSpace() {
-            return usedSpace;
-        }
-
-        public void setUsedSpace(String usedSpace) {
-            this.usedSpace = usedSpace;
-        }
-
-        /**
-         * @return utilization of this storage location
-         */
-        @ApiModelProperty(
-                value = "Utilization of this storage location."
-        )
-        public String getUtilization() {
-            return utilization;
-        }
-
-        public void setUtilization(String utilization) {
-            this.utilization = utilization;
-        }
-
-        /**
-         * @return number of bytes of free space
-         */
-        @ApiModelProperty(
-                value = "The number of bytes of free space."
-        )
-        public Long getFreeSpaceBytes() {
-            return freeSpaceBytes;
-        }
-
-        public void setFreeSpaceBytes(Long freeSpaceBytes) {
-            this.freeSpaceBytes = freeSpaceBytes;
-        }
-
-        /**
-         * @return number of bytes of total space
-         */
-        @ApiModelProperty(
-                value = "The number of bytes of total space."
-        )
-        public Long getTotalSpaceBytes() {
-            return totalSpaceBytes;
-        }
-
-        public void setTotalSpaceBytes(Long totalSpaceBytes) {
-            this.totalSpaceBytes = totalSpaceBytes;
-        }
-
-        /**
-         * @return number of bytes of used space
-         */
-        @ApiModelProperty(
-                value = "The number of bytes of used space."
-        )
-        public Long getUsedSpaceBytes() {
-            return usedSpaceBytes;
-        }
-
-        public void setUsedSpaceBytes(Long usedSpaceBytes) {
-            this.usedSpaceBytes = usedSpaceBytes;
-        }
+    @ApiModelProperty("A systems diagnostics snapshot for each node in the cluster. If the NiFi instance is a standalone instance, rather than "
+        + "a cluster, this may be null.")
+    public List<NodeSystemDiagnosticsSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
     }
 
-    /**
-     * Details for garbage collection.
-     */
-    @XmlType(name = "garbageCollection")
-    public static class GarbageCollectionDTO {
-
-        private String name;
-        private long collectionCount;
-        private String collectionTime;
-
-        /**
-         * @return name of the garbage collector
-         */
-        @ApiModelProperty(
-                value = "The name of the garbage collector."
-        )
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        @ApiModelProperty(
-                value = "The number of times garbage collection has run."
-        )
-        public long getCollectionCount() {
-            return collectionCount;
-        }
-
-        /**
-         * @param collectionCount number of times garbage collection has run
-         */
-        public void setCollectionCount(long collectionCount) {
-            this.collectionCount = collectionCount;
-        }
-
-        /**
-         * @return total amount of time spent garbage collecting
-         */
-        @ApiModelProperty(
-                value = "The total amount of time spent garbage collecting."
-        )
-        public String getCollectionTime() {
-            return collectionTime;
-        }
-
-        public void setCollectionTime(String collectionTime) {
-            this.collectionTime = collectionTime;
-        }
-
+    public void setNodeSnapshots(List<NodeSystemDiagnosticsSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsSnapshotDTO.java
new file mode 100644
index 0000000..7305837
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SystemDiagnosticsSnapshotDTO.java
@@ -0,0 +1,549 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+/**
+ * The diagnostics of the system this NiFi is running on.
+ */
+@XmlType(name = "systemDiagnosticsSnapshot")
+public class SystemDiagnosticsSnapshotDTO implements Cloneable {
+
+    private String totalNonHeap;
+    private Long totalNonHeapBytes;
+    private String usedNonHeap;
+    private Long usedNonHeapBytes;
+    private String freeNonHeap;
+    private Long freeNonHeapBytes;
+    private String maxNonHeap;
+    private Long maxNonHeapBytes;
+    private String nonHeapUtilization;
+
+    private String totalHeap;
+    private Long totalHeapBytes;
+    private String usedHeap;
+    private Long usedHeapBytes;
+    private String freeHeap;
+    private Long freeHeapBytes;
+    private String maxHeap;
+    private Long maxHeapBytes;
+    private String heapUtilization;
+
+    private Integer availableProcessors;
+    private Double processorLoadAverage;
+
+    private Integer totalThreads;
+    private Integer daemonThreads;
+
+    private StorageUsageDTO flowFileRepositoryStorageUsage;
+    private Set<StorageUsageDTO> contentRepositoryStorageUsage;
+    private Set<GarbageCollectionDTO> garbageCollection;
+
+    private Date statsLastRefreshed;
+
+
+    @ApiModelProperty("Number of available processors if supported by the underlying system.")
+    public Integer getAvailableProcessors() {
+        return availableProcessors;
+    }
+
+    public void setAvailableProcessors(Integer availableProcessors) {
+        this.availableProcessors = availableProcessors;
+    }
+
+    @ApiModelProperty("Number of daemon threads.")
+    public Integer getDaemonThreads() {
+        return daemonThreads;
+    }
+
+    public void setDaemonThreads(Integer daemonThreads) {
+        this.daemonThreads = daemonThreads;
+    }
+
+    @ApiModelProperty("Amount of free heap.")
+    public String getFreeHeap() {
+        return freeHeap;
+    }
+
+    public void setFreeHeap(String freeHeap) {
+        this.freeHeap = freeHeap;
+    }
+
+    @ApiModelProperty("Amount of free non heap.")
+    public String getFreeNonHeap() {
+        return freeNonHeap;
+    }
+
+    public void setFreeNonHeap(String freeNonHeap) {
+        this.freeNonHeap = freeNonHeap;
+    }
+
+    @ApiModelProperty("Maximum size of heap.")
+    public String getMaxHeap() {
+        return maxHeap;
+    }
+
+    public void setMaxHeap(String maxHeap) {
+        this.maxHeap = maxHeap;
+    }
+
+    @ApiModelProperty("Maximum size of non heap.")
+    public String getMaxNonHeap() {
+        return maxNonHeap;
+    }
+
+    public void setMaxNonHeap(String maxNonHeap) {
+        this.maxNonHeap = maxNonHeap;
+    }
+
+    @ApiModelProperty("The processor load average if supported by the underlying system.")
+    public Double getProcessorLoadAverage() {
+        return processorLoadAverage;
+    }
+
+    public void setProcessorLoadAverage(Double processorLoadAverage) {
+        this.processorLoadAverage = processorLoadAverage;
+    }
+
+    @ApiModelProperty("Total size of heap.")
+    public String getTotalHeap() {
+        return totalHeap;
+    }
+
+    public void setTotalHeap(String totalHeap) {
+        this.totalHeap = totalHeap;
+    }
+
+    @ApiModelProperty("Total size of non heap.")
+    public String getTotalNonHeap() {
+        return totalNonHeap;
+    }
+
+    public void setTotalNonHeap(String totalNonHeap) {
+        this.totalNonHeap = totalNonHeap;
+    }
+
+    @ApiModelProperty("Total number of threads.")
+    public Integer getTotalThreads() {
+        return totalThreads;
+    }
+
+    public void setTotalThreads(Integer totalThreads) {
+        this.totalThreads = totalThreads;
+    }
+
+    @ApiModelProperty("Amount of used heap.")
+    public String getUsedHeap() {
+        return usedHeap;
+    }
+
+    public void setUsedHeap(String usedHeap) {
+        this.usedHeap = usedHeap;
+    }
+
+    @ApiModelProperty("Amount of use non heap.")
+    public String getUsedNonHeap() {
+        return usedNonHeap;
+    }
+
+    public void setUsedNonHeap(String usedNonHeap) {
+        this.usedNonHeap = usedNonHeap;
+    }
+
+    @ApiModelProperty("Utilization of heap.")
+    public String getHeapUtilization() {
+        return heapUtilization;
+    }
+
+    public void setHeapUtilization(String heapUtilization) {
+        this.heapUtilization = heapUtilization;
+    }
+
+    @ApiModelProperty("Utilization of non heap.")
+    public String getNonHeapUtilization() {
+        return nonHeapUtilization;
+    }
+
+    public void setNonHeapUtilization(String nonHeapUsage) {
+        this.nonHeapUtilization = nonHeapUsage;
+    }
+
+    @ApiModelProperty("The content repository storage usage.")
+    public Set<StorageUsageDTO> getContentRepositoryStorageUsage() {
+        return contentRepositoryStorageUsage;
+    }
+
+    public void setContentRepositoryStorageUsage(Set<StorageUsageDTO> contentRepositoryStorageUsage) {
+        this.contentRepositoryStorageUsage = contentRepositoryStorageUsage;
+    }
+
+    @ApiModelProperty("The flowfile repository storage usage.")
+    public StorageUsageDTO getFlowFileRepositoryStorageUsage() {
+        return flowFileRepositoryStorageUsage;
+    }
+
+    public void setFlowFileRepositoryStorageUsage(StorageUsageDTO flowFileRepositoryStorageUsage) {
+        this.flowFileRepositoryStorageUsage = flowFileRepositoryStorageUsage;
+    }
+
+    @ApiModelProperty("The garbage collection details.")
+    public Set<GarbageCollectionDTO> getGarbageCollection() {
+        return garbageCollection;
+    }
+
+    public void setGarbageCollection(Set<GarbageCollectionDTO> garbageCollection) {
+        this.garbageCollection = garbageCollection;
+    }
+
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    @ApiModelProperty("When the diagnostics were generated.")
+    public Date getStatsLastRefreshed() {
+        return statsLastRefreshed;
+    }
+
+    public void setStatsLastRefreshed(Date statsLastRefreshed) {
+        this.statsLastRefreshed = statsLastRefreshed;
+    }
+
+
+    @ApiModelProperty("Total number of bytes allocated to the JVM not used for heap")
+    public Long getTotalNonHeapBytes() {
+        return totalNonHeapBytes;
+    }
+
+    public void setTotalNonHeapBytes(Long totalNonHeapBytes) {
+        this.totalNonHeapBytes = totalNonHeapBytes;
+    }
+
+    @ApiModelProperty("Total number of bytes used by the JVM not in the heap space")
+    public Long getUsedNonHeapBytes() {
+        return usedNonHeapBytes;
+    }
+
+    public void setUsedNonHeapBytes(Long usedNonHeapBytes) {
+        this.usedNonHeapBytes = usedNonHeapBytes;
+    }
+
+    @ApiModelProperty("Total number of free non-heap bytes available to the JVM")
+    public Long getFreeNonHeapBytes() {
+        return freeNonHeapBytes;
+    }
+
+    public void setFreeNonHeapBytes(Long freeNonHeapBytes) {
+        this.freeNonHeapBytes = freeNonHeapBytes;
+    }
+
+    @ApiModelProperty("The maximum number of bytes that the JVM can use for non-heap purposes")
+    public Long getMaxNonHeapBytes() {
+        return maxNonHeapBytes;
+    }
+
+    public void setMaxNonHeapBytes(Long maxNonHeapBytes) {
+        this.maxNonHeapBytes = maxNonHeapBytes;
+    }
+
+    @ApiModelProperty("The total number of bytes that are available for the JVM heap to use")
+    public Long getTotalHeapBytes() {
+        return totalHeapBytes;
+    }
+
+    public void setTotalHeapBytes(Long totalHeapBytes) {
+        this.totalHeapBytes = totalHeapBytes;
+    }
+
+    @ApiModelProperty("The number of bytes of JVM heap that are currently being used")
+    public Long getUsedHeapBytes() {
+        return usedHeapBytes;
+    }
+
+    public void setUsedHeapBytes(Long usedHeapBytes) {
+        this.usedHeapBytes = usedHeapBytes;
+    }
+
+    @ApiModelProperty("The number of bytes that are allocated to the JVM heap but not currently being used")
+    public Long getFreeHeapBytes() {
+        return freeHeapBytes;
+    }
+
+    public void setFreeHeapBytes(Long freeHeapBytes) {
+        this.freeHeapBytes = freeHeapBytes;
+    }
+
+    @ApiModelProperty("The maximum number of bytes that can be used by the JVM")
+    public Long getMaxHeapBytes() {
+        return maxHeapBytes;
+    }
+
+    public void setMaxHeapBytes(Long maxHeapBytes) {
+        this.maxHeapBytes = maxHeapBytes;
+    }
+
+
+    @Override
+    public SystemDiagnosticsSnapshotDTO clone() {
+        final SystemDiagnosticsSnapshotDTO other = new SystemDiagnosticsSnapshotDTO();
+        other.setAvailableProcessors(getAvailableProcessors());
+        other.setDaemonThreads(getDaemonThreads());
+        other.setFreeHeap(getFreeHeap());
+        other.setFreeHeapBytes(getFreeHeapBytes());
+        other.setFreeNonHeap(getFreeNonHeap());
+        other.setFreeNonHeapBytes(getFreeNonHeapBytes());
+        other.setHeapUtilization(getHeapUtilization());
+        other.setMaxHeap(getMaxHeap());
+        other.setMaxHeapBytes(getMaxHeapBytes());
+        other.setMaxNonHeap(getMaxNonHeap());
+        other.setMaxNonHeapBytes(getMaxNonHeapBytes());
+        other.setNonHeapUtilization(getNonHeapUtilization());
+        other.setProcessorLoadAverage(getProcessorLoadAverage());
+        other.setStatsLastRefreshed(getStatsLastRefreshed());
+        other.setTotalHeap(getTotalHeap());
+        other.setTotalHeapBytes(getTotalHeapBytes());
+        other.setTotalNonHeap(getTotalNonHeap());
+        other.setTotalNonHeapBytes(getTotalNonHeapBytes());
+        other.setTotalThreads(getTotalThreads());
+        other.setUsedHeap(getUsedHeap());
+        other.setUsedHeapBytes(getUsedHeapBytes());
+        other.setUsedNonHeap(getUsedNonHeap());
+        other.setUsedNonHeapBytes(getUsedNonHeapBytes());
+
+        other.setFlowFileRepositoryStorageUsage(getFlowFileRepositoryStorageUsage().clone());
+
+        final Set<StorageUsageDTO> contentRepoStorageUsage = new HashSet<>();
+        other.setContentRepositoryStorageUsage(contentRepoStorageUsage);
+        for (final StorageUsageDTO usage : getContentRepositoryStorageUsage()) {
+            contentRepoStorageUsage.add(usage.clone());
+        }
+
+        final Set<GarbageCollectionDTO> gcUsage = new HashSet<>();
+        other.setGarbageCollection(gcUsage);
+        for (final GarbageCollectionDTO gcDto : getGarbageCollection()) {
+            gcUsage.add(gcDto.clone());
+        }
+
+        return other;
+    }
+
+    /**
+     * Details of storage usage.
+     */
+    @XmlType(name = "storageUsage")
+    public static class StorageUsageDTO implements Cloneable {
+
+        private String identifier;
+        private String freeSpace;
+        private String totalSpace;
+        private String usedSpace;
+        private Long freeSpaceBytes;
+        private Long totalSpaceBytes;
+        private Long usedSpaceBytes;
+        private String utilization;
+
+        /**
+         * @return identifier for this storage location
+         */
+        @ApiModelProperty(
+                value = "The identifier of this storage location. The identifier will correspond to the identifier keyed in the storage configuration."
+        )
+        public String getIdentifier() {
+            return identifier;
+        }
+
+        public void setIdentifier(String identifier) {
+            this.identifier = identifier;
+        }
+
+        /**
+         * @return amount of free space
+         */
+        @ApiModelProperty(
+                value = "Amount of free space."
+        )
+        public String getFreeSpace() {
+            return freeSpace;
+        }
+
+        public void setFreeSpace(String freeSpace) {
+            this.freeSpace = freeSpace;
+        }
+
+        /**
+         * @return freeSpace amount of total space
+         */
+        @ApiModelProperty(
+                value = "Amount of total space."
+        )
+        public String getTotalSpace() {
+            return totalSpace;
+        }
+
+        public void setTotalSpace(String totalSpace) {
+            this.totalSpace = totalSpace;
+        }
+
+        /**
+         * @return amount of used space
+         */
+        @ApiModelProperty(
+                value = "Amount of used space."
+        )
+        public String getUsedSpace() {
+            return usedSpace;
+        }
+
+        public void setUsedSpace(String usedSpace) {
+            this.usedSpace = usedSpace;
+        }
+
+        /**
+         * @return utilization of this storage location
+         */
+        @ApiModelProperty(
+                value = "Utilization of this storage location."
+        )
+        public String getUtilization() {
+            return utilization;
+        }
+
+        public void setUtilization(String utilization) {
+            this.utilization = utilization;
+        }
+
+        /**
+         * @return number of bytes of free space
+         */
+        @ApiModelProperty(
+                value = "The number of bytes of free space."
+        )
+        public Long getFreeSpaceBytes() {
+            return freeSpaceBytes;
+        }
+
+        public void setFreeSpaceBytes(Long freeSpaceBytes) {
+            this.freeSpaceBytes = freeSpaceBytes;
+        }
+
+        /**
+         * @return number of bytes of total space
+         */
+        @ApiModelProperty(
+                value = "The number of bytes of total space."
+        )
+        public Long getTotalSpaceBytes() {
+            return totalSpaceBytes;
+        }
+
+        public void setTotalSpaceBytes(Long totalSpaceBytes) {
+            this.totalSpaceBytes = totalSpaceBytes;
+        }
+
+        /**
+         * @return number of bytes of used space
+         */
+        @ApiModelProperty(
+                value = "The number of bytes of used space."
+        )
+        public Long getUsedSpaceBytes() {
+            return usedSpaceBytes;
+        }
+
+        public void setUsedSpaceBytes(Long usedSpaceBytes) {
+            this.usedSpaceBytes = usedSpaceBytes;
+        }
+
+        @Override
+        public StorageUsageDTO clone() {
+            final StorageUsageDTO other = new StorageUsageDTO();
+            other.setIdentifier(getIdentifier());
+            other.setFreeSpace(getFreeSpace());
+            other.setTotalSpace(getTotalSpace());
+            other.setUsedSpace(getUsedSpace());
+            other.setFreeSpaceBytes(getFreeSpaceBytes());
+            other.setTotalSpaceBytes(getTotalSpaceBytes());
+            other.setUsedSpaceBytes(getUsedSpaceBytes());
+            other.setUtilization(getUtilization());
+            return other;
+        }
+    }
+
+    /**
+     * Details for garbage collection.
+     */
+    @XmlType(name = "garbageCollection")
+    public static class GarbageCollectionDTO implements Cloneable {
+
+        private String name;
+        private long collectionCount;
+        private String collectionTime;
+        private Long collectionMillis;
+
+        @ApiModelProperty("The name of the garbage collector.")
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        @ApiModelProperty("The number of times garbage collection has run.")
+        public long getCollectionCount() {
+            return collectionCount;
+        }
+
+        public void setCollectionCount(long collectionCount) {
+            this.collectionCount = collectionCount;
+        }
+
+        @ApiModelProperty("The total amount of time spent garbage collecting.")
+        public String getCollectionTime() {
+            return collectionTime;
+        }
+
+        public void setCollectionTime(String collectionTime) {
+            this.collectionTime = collectionTime;
+        }
+
+        @ApiModelProperty("The total number of milliseconds spent garbage collecting.")
+        public Long getCollectionMillis() {
+            return collectionMillis;
+        }
+
+        public void setCollectionMillis(Long collectionMillis) {
+            this.collectionMillis = collectionMillis;
+        }
+
+        @Override
+        public GarbageCollectionDTO clone() {
+            final GarbageCollectionDTO other = new GarbageCollectionDTO();
+            other.setName(getName());
+            other.setCollectionCount(getCollectionCount());
+            other.setCollectionTime(getCollectionTime());
+            other.setCollectionMillis(getCollectionMillis());
+            return other;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterConnectionStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterConnectionStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterConnectionStatusDTO.java
deleted file mode 100644
index 34f900f..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterConnectionStatusDTO.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
-import java.util.Date;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
-
-/**
- * DTO for serializing the a connection's status across the cluster.
- */
-@XmlType(name = "clusterConnectionStatus")
-public class ClusterConnectionStatusDTO {
-
-    private Collection<NodeConnectionStatusDTO> nodeConnectionStatus;
-    private Date statsLastRefreshed;
-    private String connectionId;
-    private String connectionName;
-
-    /**
-     * @return time the status were last refreshed
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "The time the status was last refreshed."
-    )
-    public Date getStatsLastRefreshed() {
-        return statsLastRefreshed;
-    }
-
-    public void setStatsLastRefreshed(Date statsLastRefreshed) {
-        this.statsLastRefreshed = statsLastRefreshed;
-    }
-
-    /**
-     * @return connection id
-     */
-    @ApiModelProperty(
-            value = "The id of the connection."
-    )
-    public String getConnectionId() {
-        return connectionId;
-    }
-
-    public void setConnectionId(String connectionId) {
-        this.connectionId = connectionId;
-    }
-
-    /**
-     * @return connection name
-     */
-    @ApiModelProperty(
-            value = "The name of the connection."
-    )
-    public String getConnectionName() {
-        return connectionName;
-    }
-
-    public void setConnectionName(String connectionName) {
-        this.connectionName = connectionName;
-    }
-
-    /**
-     * @return The collection of node connection status DTO
-     */
-    @ApiModelProperty(
-            value = "The connection status for each node."
-    )
-    public Collection<NodeConnectionStatusDTO> getNodeConnectionStatus() {
-        return nodeConnectionStatus;
-    }
-
-    public void setNodeConnectionStatus(Collection<NodeConnectionStatusDTO> nodeConnectionStatus) {
-        this.nodeConnectionStatus = nodeConnectionStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessGroupStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessGroupStatusDTO.java
deleted file mode 100644
index 1a4ad63..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessGroupStatusDTO.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
-import java.util.Date;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
-
-/**
- * DTO for serializing the a process group's status across the cluster.
- */
-@XmlType(name = "clusterProcessGroupStatus")
-public class ClusterProcessGroupStatusDTO {
-
-    private Collection<NodeProcessGroupStatusDTO> nodeProcessGroupStatus;
-    private Date statsLastRefreshed;
-    private String processGroupId;
-    private String processGroupName;
-
-    /**
-     * The time the status were last refreshed.
-     *
-     * @return The time the status were last refreshed
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "The time when the stats was last refreshed."
-    )
-    public Date getStatsLastRefreshed() {
-        return statsLastRefreshed;
-    }
-
-    public void setStatsLastRefreshed(Date statsLastRefreshed) {
-        this.statsLastRefreshed = statsLastRefreshed;
-    }
-
-    /**
-     * The process group id.
-     *
-     * @return The process group id
-     */
-    @ApiModelProperty(
-            value = "The id of the process group."
-    )
-    public String getProcessGroupId() {
-        return processGroupId;
-    }
-
-    public void setProcessGroupId(String processGroupId) {
-        this.processGroupId = processGroupId;
-    }
-
-    /**
-     * The process group name.
-     *
-     * @return The process group name
-     */
-    @ApiModelProperty(
-            value = "The name of the process group."
-    )
-    public String getProcessGroupName() {
-        return processGroupName;
-    }
-
-    public void setProcessGroupName(String processGroupName) {
-        this.processGroupName = processGroupName;
-    }
-
-    /**
-     * Collection of node process group status DTO.
-     *
-     * @return The collection of node process group status DTO
-     */
-    @ApiModelProperty(
-            value = "The process groups status for each node."
-    )
-    public Collection<NodeProcessGroupStatusDTO> getNodeProcessGroupStatus() {
-        return nodeProcessGroupStatus;
-    }
-
-    public void setNodeProcessGroupStatus(Collection<NodeProcessGroupStatusDTO> nodeProcessGroupStatus) {
-        this.nodeProcessGroupStatus = nodeProcessGroupStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessorStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessorStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessorStatusDTO.java
deleted file mode 100644
index faedc57..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterProcessorStatusDTO.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
-import java.util.Date;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
-
-/**
- * DTO for serializing the a processor's status across the cluster.
- */
-@XmlType(name = "clusterProcessorStatus")
-public class ClusterProcessorStatusDTO {
-
-    private Collection<NodeProcessorStatusDTO> nodeProcessorStatus;
-    private Date statsLastRefreshed;
-    private String processorId;
-    private String processorName;
-    private String processorType;
-    private String processorRunStatus;
-
-    /**
-     * @return time the status were last refreshed
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "The time when the status was last refreshed."
-    )
-    public Date getStatsLastRefreshed() {
-        return statsLastRefreshed;
-    }
-
-    public void setStatsLastRefreshed(Date statsLastRefreshed) {
-        this.statsLastRefreshed = statsLastRefreshed;
-    }
-
-    /**
-     * @return processor id
-     */
-    @ApiModelProperty(
-            value = "The processor id."
-    )
-    public String getProcessorId() {
-        return processorId;
-    }
-
-    public void setProcessorId(String processorId) {
-        this.processorId = processorId;
-    }
-
-    /**
-     * @return processor name
-     */
-    @ApiModelProperty(
-            value = "The processor name."
-    )
-    public String getProcessorName() {
-        return processorName;
-    }
-
-    public void setProcessorName(String processorName) {
-        this.processorName = processorName;
-    }
-
-    /**
-     * @return processor type
-     */
-    @ApiModelProperty(
-            value = "The processor type."
-    )
-    public String getProcessorType() {
-        return processorType;
-    }
-
-    public void setProcessorType(String processorType) {
-        this.processorType = processorType;
-    }
-
-    /**
-     * @return processor run status
-     */
-    @ApiModelProperty(
-            value = "The processor state.",
-            allowableValues = "RUNNING, STOPPED, DISABLED, INVALID"
-    )
-    public String getProcessorRunStatus() {
-        return processorRunStatus;
-    }
-
-    public void setProcessorRunStatus(String runStatus) {
-        this.processorRunStatus = runStatus;
-    }
-
-    /**
-     * Collection of node processor status DTO.
-     *
-     * @return The collection of node processor status DTO
-     */
-    @ApiModelProperty(
-            value = "The processor status for each node."
-    )
-    public Collection<NodeProcessorStatusDTO> getNodeProcessorStatus() {
-        return nodeProcessorStatus;
-    }
-
-    public void setNodeProcessorStatus(Collection<NodeProcessorStatusDTO> nodeProcessorStatus) {
-        this.nodeProcessorStatus = nodeProcessorStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterRemoteProcessGroupStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterRemoteProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterRemoteProcessGroupStatusDTO.java
deleted file mode 100644
index 5fef96f..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterRemoteProcessGroupStatusDTO.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
-import java.util.Date;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
-
-/**
- * DTO for serializing the a remote process group's status across the cluster.
- */
-@XmlType(name = "clusterRemoteProcessGroupStatus")
-public class ClusterRemoteProcessGroupStatusDTO {
-
-    private Collection<NodeRemoteProcessGroupStatusDTO> nodeRemoteProcessGroupStatus;
-    private Date statsLastRefreshed;
-    private String remoteProcessGroupId;
-    private String remoteProcessGroupName;
-
-    /**
-     * @return the time the status were last refreshed
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "The time when the remote process group status was last refreshed."
-    )
-    public Date getStatsLastRefreshed() {
-        return statsLastRefreshed;
-    }
-
-    public void setStatsLastRefreshed(Date statsLastRefreshed) {
-        this.statsLastRefreshed = statsLastRefreshed;
-    }
-
-    /**
-     * @return remote process group status from each node in the cluster
-     */
-    @ApiModelProperty(
-            value = "The remote process group status from each node in the cluster."
-    )
-    public Collection<NodeRemoteProcessGroupStatusDTO> getNodeRemoteProcessGroupStatus() {
-        return nodeRemoteProcessGroupStatus;
-    }
-
-    public void setNodeRemoteProcessGroupStatus(Collection<NodeRemoteProcessGroupStatusDTO> nodeRemoteProcessGroupStatus) {
-        this.nodeRemoteProcessGroupStatus = nodeRemoteProcessGroupStatus;
-    }
-
-    /**
-     * @return remote process group id
-     */
-    @ApiModelProperty(
-            value = "The id of the remote process group."
-    )
-    public String getRemoteProcessGroupId() {
-        return remoteProcessGroupId;
-    }
-
-    public void setRemoteProcessGroupId(String remoteProcessGroupId) {
-        this.remoteProcessGroupId = remoteProcessGroupId;
-    }
-
-    /**
-     * @return remote process group name
-     */
-    @ApiModelProperty(
-            value = "The name of the remote process group."
-    )
-    public String getRemoteProcessGroupName() {
-        return remoteProcessGroupName;
-    }
-
-    public void setRemoteProcessGroupName(String remoteProcessGroupName) {
-        this.remoteProcessGroupName = remoteProcessGroupName;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterStatusHistoryDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterStatusHistoryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterStatusHistoryDTO.java
deleted file mode 100644
index 997e24b..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ClusterStatusHistoryDTO.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
-import java.util.Date;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
-
-/**
- * DTO for serializing the a status history across the cluster.
- */
-@XmlType(name = "clusterStatusHistory")
-public class ClusterStatusHistoryDTO {
-
-    private Collection<NodeStatusHistoryDTO> nodeStatusHistory;
-    private StatusHistoryDTO clusterStatusHistory;
-    private Date generated;
-
-    /**
-     * @return when this status history was generated
-     */
-    @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "When the status history was generated."
-    )
-    public Date getGenerated() {
-        return generated;
-    }
-
-    public void setGenerated(Date generated) {
-        this.generated = generated;
-    }
-
-    /**
-     * @return status history from each node in the cluster
-     */
-    @ApiModelProperty(
-            value = "The status history from each node."
-    )
-    public Collection<NodeStatusHistoryDTO> getNodeStatusHistory() {
-        return nodeStatusHistory;
-    }
-
-    public void setNodeStatusHistory(Collection<NodeStatusHistoryDTO> nodeStatusHistory) {
-        this.nodeStatusHistory = nodeStatusHistory;
-    }
-
-    /**
-     * @return status history for this component across the entire cluster
-     */
-    @ApiModelProperty(
-            value = "The status history for the entire cluster."
-    )
-    public StatusHistoryDTO getClusterStatusHistory() {
-        return clusterStatusHistory;
-    }
-
-    public void setClusterStatusHistory(StatusHistoryDTO clusterStatusHistory) {
-        this.clusterStatusHistory = clusterStatusHistory;
-    }
-
-}


[18/18] nifi git commit: NIFI-1552: - Addressing unused imports.

Posted by mc...@apache.org.
NIFI-1552:
- Addressing unused imports.


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

Branch: refs/heads/master
Commit: 9f7dba491f7585216b3bc3ad9fdf9234feb0f165
Parents: 9aa69b2
Author: Matt Gilman <ma...@gmail.com>
Authored: Mon Apr 4 11:49:25 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Apr 4 11:49:25 2016 -0400

----------------------------------------------------------------------
 .../src/main/java/org/apache/nifi/authorization/Authorizer.java     | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/9f7dba49/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java b/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
index eb18cf0..01a76e4 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
@@ -20,7 +20,6 @@ import org.apache.nifi.authorization.exception.AuthorityAccessException;
 import org.apache.nifi.authorization.exception.AuthorizationAccessException;
 import org.apache.nifi.authorization.exception.AuthorizerCreationException;
 import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
-import org.apache.nifi.authorization.exception.UnknownIdentityException;
 
 /**
  * Authorizes user requests.


[03/18] nifi git commit: Updating versions to 1.0.0-SNAPSHOT.

Posted by mc...@apache.org.
Updating versions to 1.0.0-SNAPSHOT.


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

Branch: refs/heads/master
Commit: 2de7f3f8846094c2055753b3a391c6d391d3349d
Parents: 1610846
Author: Matt Gilman <ma...@gmail.com>
Authored: Mon Apr 4 11:36:19 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Apr 4 11:36:20 2016 -0400

----------------------------------------------------------------------
 nifi-api/pom.xml                                |   2 +-
 nifi-assembly/pom.xml                           |   2 +-
 nifi-bootstrap/pom.xml                          |   2 +-
 nifi-commons/nifi-data-provenance-utils/pom.xml |   2 +-
 nifi-commons/nifi-expression-language/pom.xml   |   2 +-
 nifi-commons/nifi-flowfile-packager/pom.xml     |   2 +-
 nifi-commons/nifi-hadoop-utils/pom.xml          |   4 +-
 nifi-commons/nifi-hl7-query-language/pom.xml    |   2 +-
 nifi-commons/nifi-logging-utils/pom.xml         |   2 +-
 nifi-commons/nifi-processor-utilities/pom.xml   |   2 +-
 nifi-commons/nifi-properties/pom.xml            |   2 +-
 nifi-commons/nifi-security-utils/pom.xml        |   2 +-
 nifi-commons/nifi-site-to-site-client/pom.xml   |   4 +-
 nifi-commons/nifi-socket-utils/pom.xml          |   2 +-
 nifi-commons/nifi-utils/pom.xml                 |   4 +-
 nifi-commons/nifi-web-utils/pom.xml             |   2 +-
 nifi-commons/nifi-write-ahead-log/pom.xml       |   2 +-
 nifi-commons/pom.xml                            |   2 +-
 nifi-docs/pom.xml                               |   2 +-
 .../nifi-nifi-example-nar/pom.xml               |   2 +-
 .../nifi-nifi-example-processors/pom.xml        |   2 +-
 nifi-external/nifi-example-bundle/pom.xml       |   4 +-
 nifi-external/nifi-spark-receiver/pom.xml       |   2 +-
 nifi-external/nifi-storm-spout/pom.xml          |   2 +-
 nifi-external/pom.xml                           |   2 +-
 .../nifi-processor-bundle-archetype/pom.xml     |   2 +-
 .../nifi-service-bundle-archetype/pom.xml       |   2 +-
 nifi-maven-archetypes/pom.xml                   |   2 +-
 nifi-mock/pom.xml                               |   2 +-
 .../nifi-ambari-bundle/nifi-ambari-nar/pom.xml  |   4 +-
 .../nifi-ambari-reporting-task/pom.xml          |   2 +-
 nifi-nar-bundles/nifi-ambari-bundle/pom.xml     |   2 +-
 .../nifi-amqp-bundle/nifi-amqp-nar/pom.xml      |   4 +-
 .../nifi-amqp-processors/pom.xml                |   2 +-
 nifi-nar-bundles/nifi-amqp-bundle/pom.xml       |   6 +-
 .../nifi-avro-bundle/nifi-avro-nar/pom.xml      |   6 +-
 .../nifi-avro-processors/pom.xml                |   2 +-
 nifi-nar-bundles/nifi-avro-bundle/pom.xml       |   4 +-
 .../nifi-aws-bundle/nifi-aws-nar/pom.xml        |   4 +-
 .../nifi-aws-bundle/nifi-aws-processors/pom.xml |   2 +-
 nifi-nar-bundles/nifi-aws-bundle/pom.xml        |   2 +-
 .../nifi-azure-bundle/nifi-azure-nar/pom.xml    |   6 +-
 .../nifi-azure-processors/pom.xml               |   2 +-
 nifi-nar-bundles/nifi-azure-bundle/pom.xml      |   4 +-
 .../nifi-cassandra-nar/pom.xml                  |   2 +-
 .../nifi-cassandra-processors/pom.xml           |   2 +-
 nifi-nar-bundles/nifi-cassandra-bundle/pom.xml  |   4 +-
 .../nifi-couchbase-nar/pom.xml                  |   6 +-
 .../nifi-couchbase-processors/pom.xml           |   2 +-
 nifi-nar-bundles/nifi-couchbase-bundle/pom.xml  |   4 +-
 .../nifi-elasticsearch-nar/pom.xml              |   2 +-
 .../nifi-elasticsearch-processors/pom.xml       |   2 +-
 .../nifi-elasticsearch-bundle/pom.xml           |   4 +-
 .../nifi-flume-bundle/nifi-flume-nar/pom.xml    |   4 +-
 .../nifi-flume-processors/pom.xml               |   2 +-
 nifi-nar-bundles/nifi-flume-bundle/pom.xml      |   6 +-
 .../nifi-framework-nar/pom.xml                  |   2 +-
 .../nifi-framework/nifi-administration/pom.xml  |   2 +-
 .../nifi-framework/nifi-client-dto/pom.xml      |   2 +-
 .../nifi-cluster-authorization-provider/pom.xml |   2 +-
 .../nifi-framework/nifi-documentation/pom.xml   |   2 +-
 .../nifi-file-authorization-provider/pom.xml    |   2 +-
 .../nifi-framework-cluster-protocol/pom.xml     |   2 +-
 .../nifi-framework-cluster-web/pom.xml          |   2 +-
 .../nifi-framework-cluster/pom.xml              |   2 +-
 .../nifi-framework-core-api/pom.xml             |   2 +-
 .../nifi-framework/nifi-framework-core/pom.xml  |   2 +-
 .../nifi-framework/nifi-nar-utils/pom.xml       |   2 +-
 .../nifi-framework/nifi-resources/pom.xml       |   2 +-
 .../nifi-framework/nifi-runtime/pom.xml         |   2 +-
 .../nifi-framework/nifi-security/pom.xml        |   2 +-
 .../nifi-framework/nifi-site-to-site/pom.xml    |   2 +-
 .../nifi-framework/nifi-user-actions/pom.xml    |   2 +-
 .../nifi-web/nifi-custom-ui-utilities/pom.xml   |   2 +-
 .../nifi-framework/nifi-web/nifi-jetty/pom.xml  |   2 +-
 .../nifi-web/nifi-ui-extension/pom.xml          |   2 +-
 .../nifi-web/nifi-web-api/pom.xml               |   2 +-
 .../nifi-web/nifi-web-content-access/pom.xml    |   2 +-
 .../nifi-web/nifi-web-content-viewer/pom.xml    |   2 +-
 .../nifi-web/nifi-web-docs/pom.xml              |   2 +-
 .../nifi-web/nifi-web-error/pom.xml             |   2 +-
 .../nifi-web-optimistic-locking/pom.xml         |   2 +-
 .../nifi-web/nifi-web-security/pom.xml          |   2 +-
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |   2 +-
 .../nifi-framework/nifi-web/pom.xml             |  12 +-
 .../nifi-framework/pom.xml                      |   2 +-
 nifi-nar-bundles/nifi-framework-bundle/pom.xml  |  38 +++---
 .../nifi-geo-bundle/nifi-geo-nar/pom.xml        |   2 +-
 .../nifi-geo-bundle/nifi-geo-processors/pom.xml |   2 +-
 nifi-nar-bundles/nifi-geo-bundle/pom.xml        |   4 +-
 .../nifi-hadoop-bundle/nifi-hadoop-nar/pom.xml  |   2 +-
 .../nifi-hdfs-processors/pom.xml                |   2 +-
 nifi-nar-bundles/nifi-hadoop-bundle/pom.xml     |   4 +-
 .../nifi-hadoop-libraries-nar/pom.xml           |   2 +-
 .../nifi-hadoop-libraries-bundle/pom.xml        |   2 +-
 .../nifi-hbase-bundle/nifi-hbase-nar/pom.xml    |   2 +-
 .../nifi-hbase-processors/pom.xml               |   6 +-
 nifi-nar-bundles/nifi-hbase-bundle/pom.xml      |   4 +-
 .../nifi-hl7-bundle/nifi-hl7-nar/pom.xml        |   4 +-
 .../nifi-hl7-bundle/nifi-hl7-processors/pom.xml |   4 +-
 nifi-nar-bundles/nifi-hl7-bundle/pom.xml        |   2 +-
 .../nifi-html-bundle/nifi-html-nar/pom.xml      |   2 +-
 .../nifi-html-processors/pom.xml                |   2 +-
 nifi-nar-bundles/nifi-html-bundle/pom.xml       |   4 +-
 .../nifi-image-bundle/nifi-image-nar/pom.xml    |   8 +-
 .../nifi-image-processors/pom.xml               |   2 +-
 .../nifi-image-bundle/nifi-image-viewer/pom.xml |   2 +-
 nifi-nar-bundles/nifi-image-bundle/pom.xml      |   4 +-
 nifi-nar-bundles/nifi-jetty-bundle/pom.xml      |   2 +-
 .../nifi-jms-cf-service-nar/pom.xml             |   4 +-
 .../nifi-jms-bundle/nifi-jms-cf-service/pom.xml |   2 +-
 .../nifi-jms-processors-nar/pom.xml             |   4 +-
 .../nifi-jms-bundle/nifi-jms-processors/pom.xml |   4 +-
 nifi-nar-bundles/nifi-jms-bundle/pom.xml        |   4 +-
 .../nifi-kafka-bundle/nifi-kafka-nar/pom.xml    |   2 +-
 .../nifi-kafka-processors/pom.xml               |   2 +-
 nifi-nar-bundles/nifi-kafka-bundle/pom.xml      |   4 +-
 .../nifi-kerberos-iaa-providers-nar/pom.xml     |   2 +-
 .../nifi-kerberos-iaa-providers/pom.xml         |   2 +-
 .../nifi-kerberos-iaa-providers-bundle/pom.xml  |   4 +-
 .../nifi-kite-bundle/nifi-kite-nar/pom.xml      |   2 +-
 .../nifi-kite-processors/pom.xml                |   2 +-
 nifi-nar-bundles/nifi-kite-bundle/pom.xml       |   4 +-
 .../nifi-language-translation-nar/pom.xml       |   4 +-
 .../nifi-yandex-processors/pom.xml              |   2 +-
 .../nifi-language-translation-bundle/pom.xml    |   2 +-
 .../nifi-ldap-iaa-providers-nar/pom.xml         |   2 +-
 .../nifi-ldap-iaa-providers/pom.xml             |   2 +-
 .../nifi-ldap-iaa-providers-bundle/pom.xml      |   4 +-
 .../nifi-mongodb-nar/pom.xml                    |   6 +-
 .../nifi-mongodb-processors/pom.xml             |   2 +-
 nifi-nar-bundles/nifi-mongodb-bundle/pom.xml    |   4 +-
 .../pom.xml                                     |   2 +-
 .../nifi-provenance-repository-nar/pom.xml      |   2 +-
 .../nifi-volatile-provenance-repository/pom.xml |   2 +-
 .../nifi-provenance-repository-bundle/pom.xml   |   6 +-
 .../nifi-riemann-nar/pom.xml                    |   2 +-
 .../nifi-riemann-processors/pom.xml             |   2 +-
 nifi-nar-bundles/nifi-riemann-bundle/pom.xml    |   4 +-
 .../nifi-scripting-nar/pom.xml                  |   2 +-
 .../nifi-scripting-processors/pom.xml           |   2 +-
 nifi-nar-bundles/nifi-scripting-bundle/pom.xml  |   4 +-
 .../nifi-social-media-nar/pom.xml               |   4 +-
 .../nifi-twitter-processors/pom.xml             |   2 +-
 .../nifi-social-media-bundle/pom.xml            |   2 +-
 .../nifi-solr-bundle/nifi-solr-nar/pom.xml      |   4 +-
 .../nifi-solr-processors/pom.xml                |   2 +-
 nifi-nar-bundles/nifi-solr-bundle/pom.xml       |   2 +-
 .../nifi-splunk-bundle/nifi-splunk-nar/pom.xml  |   6 +-
 .../nifi-splunk-processors/pom.xml              |   2 +-
 nifi-nar-bundles/nifi-splunk-bundle/pom.xml     |   4 +-
 .../nifi-spring-bundle/nifi-spring-nar/pom.xml  |   2 +-
 .../nifi-spring-processors/pom.xml              |   2 +-
 nifi-nar-bundles/nifi-spring-bundle/pom.xml     |   4 +-
 .../nifi-standard-content-viewer/pom.xml        |   2 +-
 .../nifi-standard-nar/pom.xml                   |   2 +-
 .../nifi-standard-prioritizers/pom.xml          |   2 +-
 .../nifi-standard-processors/pom.xml            |   2 +-
 .../nifi-standard-reporting-tasks/pom.xml       |   2 +-
 nifi-nar-bundles/nifi-standard-bundle/pom.xml   |  10 +-
 .../nifi-dbcp-service-api/pom.xml               |   2 +-
 .../nifi-dbcp-service-nar/pom.xml               |   4 +-
 .../nifi-dbcp-service/pom.xml                   |   2 +-
 .../nifi-dbcp-service-bundle/pom.xml            |   2 +-
 .../pom.xml                                     |   2 +-
 .../pom.xml                                     |   2 +-
 .../nifi-distributed-cache-protocol/pom.xml     |   2 +-
 .../nifi-distributed-cache-server/pom.xml       |   2 +-
 .../nifi-distributed-cache-services-nar/pom.xml |   2 +-
 .../pom.xml                                     |   2 +-
 .../nifi-hbase-client-service-api/pom.xml       |   2 +-
 .../nifi-hbase_1_1_2-client-service-nar/pom.xml |   6 +-
 .../nifi-hbase_1_1_2-client-service/pom.xml     |   4 +-
 .../pom.xml                                     |   4 +-
 .../nifi-http-context-map-api/pom.xml           |   2 +-
 .../nifi-http-context-map-nar/pom.xml           |   2 +-
 .../nifi-http-context-map/pom.xml               |   2 +-
 .../nifi-http-context-map-bundle/pom.xml        |   2 +-
 .../nifi-load-distribution-service-api/pom.xml  |   2 +-
 .../nifi-ssl-context-nar/pom.xml                |   2 +-
 .../nifi-ssl-context-service/pom.xml            |   2 +-
 .../nifi-ssl-context-bundle/pom.xml             |   2 +-
 .../nifi-ssl-context-service-api/pom.xml        |   2 +-
 .../nifi-standard-services-api-nar/pom.xml      |   2 +-
 nifi-nar-bundles/nifi-standard-services/pom.xml |   2 +-
 .../nifi-update-attribute-model/pom.xml         |   2 +-
 .../nifi-update-attribute-nar/pom.xml           |   2 +-
 .../nifi-update-attribute-processor/pom.xml     |   2 +-
 .../nifi-update-attribute-ui/pom.xml            |   2 +-
 .../nifi-update-attribute-bundle/pom.xml        |   8 +-
 nifi-nar-bundles/pom.xml                        |  30 ++---
 pom.xml                                         | 134 +++++++++----------
 192 files changed, 364 insertions(+), 364 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-api/pom.xml b/nifi-api/pom.xml
index e8a8222..103eedd 100644
--- a/nifi-api/pom.xml
+++ b/nifi-api/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-api</artifactId>
     <packaging>jar</packaging>    

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index e697fe6..0422b8e 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -14,7 +14,7 @@ language governing permissions and limitations under the License. -->
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-assembly</artifactId>
     <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-bootstrap/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/pom.xml b/nifi-bootstrap/pom.xml
index 240f343..ce30cd7 100644
--- a/nifi-bootstrap/pom.xml
+++ b/nifi-bootstrap/pom.xml
@@ -14,7 +14,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 	<artifactId>nifi-bootstrap</artifactId>
 	<packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-data-provenance-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-data-provenance-utils/pom.xml b/nifi-commons/nifi-data-provenance-utils/pom.xml
index d1f685d..e379541 100644
--- a/nifi-commons/nifi-data-provenance-utils/pom.xml
+++ b/nifi-commons/nifi-data-provenance-utils/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-data-provenance-utils</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-expression-language/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-expression-language/pom.xml b/nifi-commons/nifi-expression-language/pom.xml
index 6fae46b..ef552e9 100644
--- a/nifi-commons/nifi-expression-language/pom.xml
+++ b/nifi-commons/nifi-expression-language/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-expression-language</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-flowfile-packager/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-flowfile-packager/pom.xml b/nifi-commons/nifi-flowfile-packager/pom.xml
index 0679a7b..e78b645 100644
--- a/nifi-commons/nifi-flowfile-packager/pom.xml
+++ b/nifi-commons/nifi-flowfile-packager/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-flowfile-packager</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-hadoop-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-hadoop-utils/pom.xml b/nifi-commons/nifi-hadoop-utils/pom.xml
index 2dde6f7..5f18400 100644
--- a/nifi-commons/nifi-hadoop-utils/pom.xml
+++ b/nifi-commons/nifi-hadoop-utils/pom.xml
@@ -18,10 +18,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hadoop-utils</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-hl7-query-language/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-hl7-query-language/pom.xml b/nifi-commons/nifi-hl7-query-language/pom.xml
index 166b670..704c75e 100644
--- a/nifi-commons/nifi-hl7-query-language/pom.xml
+++ b/nifi-commons/nifi-hl7-query-language/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hl7-query-language</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-logging-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-logging-utils/pom.xml b/nifi-commons/nifi-logging-utils/pom.xml
index a3b30d3..d200152 100644
--- a/nifi-commons/nifi-logging-utils/pom.xml
+++ b/nifi-commons/nifi-logging-utils/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-logging-utils</artifactId>
     <description>Utilities for logging</description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-processor-utilities/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-processor-utilities/pom.xml b/nifi-commons/nifi-processor-utilities/pom.xml
index 8196818..459026d 100644
--- a/nifi-commons/nifi-processor-utilities/pom.xml
+++ b/nifi-commons/nifi-processor-utilities/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-processor-utils</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-properties/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-properties/pom.xml b/nifi-commons/nifi-properties/pom.xml
index 7577695..f2b42c8 100644
--- a/nifi-commons/nifi-properties/pom.xml
+++ b/nifi-commons/nifi-properties/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-properties</artifactId>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-security-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-security-utils/pom.xml b/nifi-commons/nifi-security-utils/pom.xml
index 030cda0..76d3c9a 100644
--- a/nifi-commons/nifi-security-utils/pom.xml
+++ b/nifi-commons/nifi-security-utils/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-security-utils</artifactId>
     <description>Contains security functionality.</description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-site-to-site-client/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-site-to-site-client/pom.xml b/nifi-commons/nifi-site-to-site-client/pom.xml
index 890abf1..987e42b 100644
--- a/nifi-commons/nifi-site-to-site-client/pom.xml
+++ b/nifi-commons/nifi-site-to-site-client/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-site-to-site-client</artifactId>
@@ -42,7 +42,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-client-dto</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-socket-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-socket-utils/pom.xml b/nifi-commons/nifi-socket-utils/pom.xml
index ebefdd9..f00933a 100644
--- a/nifi-commons/nifi-socket-utils/pom.xml
+++ b/nifi-commons/nifi-socket-utils/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-socket-utils</artifactId>
     <description>Utilities for socket communication</description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-utils/pom.xml b/nifi-commons/nifi-utils/pom.xml
index 18a0199..71854e5 100644
--- a/nifi-commons/nifi-utils/pom.xml
+++ b/nifi-commons/nifi-utils/pom.xml
@@ -18,10 +18,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-utils</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>jar</packaging>
     <!--
     This project intentionally has no additional dependencies beyond that pulled in by the parent.  It is a general purpose utility library

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-web-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-web-utils/pom.xml b/nifi-commons/nifi-web-utils/pom.xml
index 50503cb..dd2f3ef 100644
--- a/nifi-commons/nifi-web-utils/pom.xml
+++ b/nifi-commons/nifi-web-utils/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-web-utils</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/nifi-write-ahead-log/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-write-ahead-log/pom.xml b/nifi-commons/nifi-write-ahead-log/pom.xml
index 6708b13..04b343c 100644
--- a/nifi-commons/nifi-write-ahead-log/pom.xml
+++ b/nifi-commons/nifi-write-ahead-log/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-commons</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-write-ahead-log</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-commons/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-commons/pom.xml b/nifi-commons/pom.xml
index 7878cea..3af904a 100644
--- a/nifi-commons/pom.xml
+++ b/nifi-commons/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-commons</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-docs/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-docs/pom.xml b/nifi-docs/pom.xml
index 005a3bf..2a00534 100644
--- a/nifi-docs/pom.xml
+++ b/nifi-docs/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <packaging>pom</packaging>
     <artifactId>nifi-docs</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-external/nifi-example-bundle/nifi-nifi-example-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-external/nifi-example-bundle/nifi-nifi-example-nar/pom.xml b/nifi-external/nifi-example-bundle/nifi-nifi-example-nar/pom.xml
index 1405da4..bfda530 100644
--- a/nifi-external/nifi-example-bundle/nifi-nifi-example-nar/pom.xml
+++ b/nifi-external/nifi-example-bundle/nifi-nifi-example-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-example-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-example-nar</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-external/nifi-example-bundle/nifi-nifi-example-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-external/nifi-example-bundle/nifi-nifi-example-processors/pom.xml b/nifi-external/nifi-example-bundle/nifi-nifi-example-processors/pom.xml
index 5516244..00243b8 100644
--- a/nifi-external/nifi-example-bundle/nifi-nifi-example-processors/pom.xml
+++ b/nifi-external/nifi-example-bundle/nifi-nifi-example-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-example-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-nifi-example-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-external/nifi-example-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-external/nifi-example-bundle/pom.xml b/nifi-external/nifi-example-bundle/pom.xml
index 7bc5c36..6ac76bd 100644
--- a/nifi-external/nifi-example-bundle/pom.xml
+++ b/nifi-external/nifi-example-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-external</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-example-bundle</artifactId>
@@ -35,7 +35,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-nifi-example-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-external/nifi-spark-receiver/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-external/nifi-spark-receiver/pom.xml b/nifi-external/nifi-spark-receiver/pom.xml
index e461807..4aa6200 100644
--- a/nifi-external/nifi-spark-receiver/pom.xml
+++ b/nifi-external/nifi-spark-receiver/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-external</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-spark-receiver</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-external/nifi-storm-spout/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-external/nifi-storm-spout/pom.xml b/nifi-external/nifi-storm-spout/pom.xml
index 38179b2..65fcdab 100644
--- a/nifi-external/nifi-storm-spout/pom.xml
+++ b/nifi-external/nifi-storm-spout/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-external</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-storm-spout</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-external/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-external/pom.xml b/nifi-external/pom.xml
index 602ee41..edf8ec5 100644
--- a/nifi-external/pom.xml
+++ b/nifi-external/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-external</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-maven-archetypes/nifi-processor-bundle-archetype/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-maven-archetypes/nifi-processor-bundle-archetype/pom.xml b/nifi-maven-archetypes/nifi-processor-bundle-archetype/pom.xml
index 38cc3d5..f4caca9 100644
--- a/nifi-maven-archetypes/nifi-processor-bundle-archetype/pom.xml
+++ b/nifi-maven-archetypes/nifi-processor-bundle-archetype/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-maven-archetypes</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-processor-bundle-archetype</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-maven-archetypes/nifi-service-bundle-archetype/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-maven-archetypes/nifi-service-bundle-archetype/pom.xml b/nifi-maven-archetypes/nifi-service-bundle-archetype/pom.xml
index b8192f9..23283b4 100644
--- a/nifi-maven-archetypes/nifi-service-bundle-archetype/pom.xml
+++ b/nifi-maven-archetypes/nifi-service-bundle-archetype/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-maven-archetypes</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-service-bundle-archetype</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-maven-archetypes/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-maven-archetypes/pom.xml b/nifi-maven-archetypes/pom.xml
index 248fdf2..08684e0 100644
--- a/nifi-maven-archetypes/pom.xml
+++ b/nifi-maven-archetypes/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-maven-archetypes</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-mock/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-mock/pom.xml b/nifi-mock/pom.xml
index 9d90ed2..dd15fef 100644
--- a/nifi-mock/pom.xml
+++ b/nifi-mock/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-mock</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-nar/pom.xml b/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-nar/pom.xml
index 25ea5f2..95a0cb4 100644
--- a/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-ambari-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-ambari-nar</artifactId>
@@ -30,7 +30,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-ambari-reporting-task</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-reporting-task/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-reporting-task/pom.xml b/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-reporting-task/pom.xml
index ed062e4..fd7e8df 100644
--- a/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-reporting-task/pom.xml
+++ b/nifi-nar-bundles/nifi-ambari-bundle/nifi-ambari-reporting-task/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-ambari-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-ambari-reporting-task</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-ambari-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ambari-bundle/pom.xml b/nifi-nar-bundles/nifi-ambari-bundle/pom.xml
index cd38ce2..d635c71 100644
--- a/nifi-nar-bundles/nifi-ambari-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-ambari-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-ambari-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-nar/pom.xml b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-nar/pom.xml
index 049de77..491e0d8 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-nar/pom.xml
@@ -18,10 +18,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-amqp-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-amqp-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/pom.xml b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/pom.xml
index 83339b9..5652bd4 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/pom.xml
@@ -14,7 +14,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi-amqp-bundle</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 	<artifactId>nifi-amqp-processors</artifactId>
 	<packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-amqp-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/pom.xml b/nifi-nar-bundles/nifi-amqp-bundle/pom.xml
index df7d740..756288c 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-amqp-bundle/pom.xml
@@ -18,10 +18,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-amqp-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <description>A bundle of processors that publish to and consume messages from AMQP.</description>
     <modules>
@@ -33,7 +33,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-amqp-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-nar/pom.xml b/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-nar/pom.xml
index d7b26e3..1cb882d 100644
--- a/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-avro-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-avro-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -34,7 +34,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-avro-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-processors/pom.xml b/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-processors/pom.xml
index 0058779..9c9211d 100644
--- a/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-avro-bundle/nifi-avro-processors/pom.xml
@@ -15,7 +15,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi-avro-bundle</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>nifi-avro-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-avro-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-avro-bundle/pom.xml b/nifi-nar-bundles/nifi-avro-bundle/pom.xml
index 56c37aa..40311bd 100644
--- a/nifi-nar-bundles/nifi-avro-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-avro-bundle/pom.xml
@@ -19,12 +19,12 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-avro-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-nar/pom.xml b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-nar/pom.xml
index 30d85cb..100f064 100644
--- a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-aws-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-aws-nar</artifactId>
@@ -38,7 +38,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-aws-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/pom.xml b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/pom.xml
index dc2b5d5..3a356a2 100644
--- a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-aws-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-aws-processors</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-aws-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-aws-bundle/pom.xml b/nifi-nar-bundles/nifi-aws-bundle/pom.xml
index 5ebc61b..4a06611 100644
--- a/nifi-nar-bundles/nifi-aws-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-aws-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-aws-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
index aebb309..da513f1 100644
--- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-azure-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-azure-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -34,7 +34,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-azure-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml
index f667e75..8562515 100644
--- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml
@@ -15,7 +15,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi-azure-bundle</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>nifi-azure-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-azure-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-azure-bundle/pom.xml b/nifi-nar-bundles/nifi-azure-bundle/pom.xml
index ad88403..5d2b55a 100644
--- a/nifi-nar-bundles/nifi-azure-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-azure-bundle/pom.xml
@@ -19,12 +19,12 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-azure-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-nar/pom.xml b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-nar/pom.xml
index b465f89..1bed7fa 100644
--- a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-cassandra-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-cassandra-nar</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/pom.xml b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/pom.xml
index 6a36a17..68e1eeb 100644
--- a/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-cassandra-bundle/nifi-cassandra-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-cassandra-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-cassandra-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-cassandra-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-cassandra-bundle/pom.xml b/nifi-nar-bundles/nifi-cassandra-bundle/pom.xml
index 2298813..9243af2 100644
--- a/nifi-nar-bundles/nifi-cassandra-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-cassandra-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-cassandra-bundle</artifactId>
@@ -35,7 +35,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-cassandra-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-nar/pom.xml b/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-nar/pom.xml
index 22c334d..e8094d5 100644
--- a/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-couchbase-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-couchbase-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -34,7 +34,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-couchbase-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-processors/pom.xml b/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-processors/pom.xml
index cf99020..2281a69 100644
--- a/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-couchbase-bundle/nifi-couchbase-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-couchbase-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-couchbase-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-couchbase-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-couchbase-bundle/pom.xml b/nifi-nar-bundles/nifi-couchbase-bundle/pom.xml
index 9f4e4ba..b50254c 100644
--- a/nifi-nar-bundles/nifi-couchbase-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-couchbase-bundle/pom.xml
@@ -19,12 +19,12 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-couchbase-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-nar/pom.xml b/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-nar/pom.xml
index 0703a02..77a5881 100644
--- a/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-nar/pom.xml
@@ -14,7 +14,7 @@ language governing permissions and limitations under the License. -->
     <parent>
         <artifactId>nifi-elasticsearch-bundle</artifactId>
         <groupId>org.apache.nifi</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-processors/pom.xml b/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-processors/pom.xml
index 9bc3104..4cf40fe 100644
--- a/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-elasticsearch-bundle/nifi-elasticsearch-processors/pom.xml
@@ -14,7 +14,7 @@ language governing permissions and limitations under the License. -->
     <parent>
         <artifactId>nifi-elasticsearch-bundle</artifactId>
         <groupId>org.apache.nifi</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-elasticsearch-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-elasticsearch-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-elasticsearch-bundle/pom.xml b/nifi-nar-bundles/nifi-elasticsearch-bundle/pom.xml
index ab55b3d..44dd085 100644
--- a/nifi-nar-bundles/nifi-elasticsearch-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-elasticsearch-bundle/pom.xml
@@ -15,7 +15,7 @@ language governing permissions and limitations under the License. -->
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
@@ -36,7 +36,7 @@ language governing permissions and limitations under the License. -->
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-elasticsearch-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-nar/pom.xml b/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-nar/pom.xml
index c4783a2..8a4bfb6 100644
--- a/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-nar/pom.xml
@@ -18,10 +18,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-flume-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-flume-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-processors/pom.xml b/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-processors/pom.xml
index 53f8770..60c7e9e 100644
--- a/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-flume-bundle/nifi-flume-processors/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-flume-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-flume-processors</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-flume-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-flume-bundle/pom.xml b/nifi-nar-bundles/nifi-flume-bundle/pom.xml
index 77bf03c..ff4bd5e 100644
--- a/nifi-nar-bundles/nifi-flume-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-flume-bundle/pom.xml
@@ -18,10 +18,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-flume-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <description>A bundle of processors that run Flume sources/sinks</description>
     <modules>
@@ -33,7 +33,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-flume-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
index 16e7a6d..dca1d97 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
index de95ba6..2fef0c4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-administration</artifactId>
     <build>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/pom.xml
index cc46d7d..1c500eb 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-client-dto</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster-authorization-provider/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster-authorization-provider/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster-authorization-provider/pom.xml
index ecf5c4b..2f0147b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster-authorization-provider/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster-authorization-provider/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-cluster-authorization-provider</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/pom.xml
index 9151d2b..d8c3889 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/pom.xml
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-documentation</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
index 50a9679..caa75de 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorization-provider/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-file-authorization-provider</artifactId>
     <build>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/pom.xml
index c037ac1..be542bc 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-cluster-protocol</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-web/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-web/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-web/pom.xml
index 5688ea0..e559816 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-web/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-web/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-cluster-web</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml
index 456dcd3..1e1eae7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-cluster</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/pom.xml
index d7a5f80..62b2611 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-core-api</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
index 6c8e0c6..dc5b7d3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-core</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/pom.xml
index fe0e1ff..d3f830d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-nar-utils</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
index be9ad84..a738069 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-resources</artifactId>
     <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
index e3aa43f..8f4f954 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-runtime</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-security/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-security/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-security/pom.xml
index a2dea8f..544f7c2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-security/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-security/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-security</artifactId>
     <description>Contains security functionality common to NiFi.</description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
index 326a396..74ff797 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-site-to-site</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-user-actions/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-user-actions/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-user-actions/pom.xml
index 5425650..ee6d175 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-user-actions/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-user-actions/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-user-actions</artifactId>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-custom-ui-utilities/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-custom-ui-utilities/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-custom-ui-utilities/pom.xml
index 7bc8712..e90220a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-custom-ui-utilities/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-custom-ui-utilities/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-custom-ui-utilities</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
index ff152a9..74322bb 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-jetty</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/pom.xml
index ca4a8b1..013c5c9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ui-extension</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
index 76c7427..38bafbd 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-api</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-access/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-access/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-access/pom.xml
index b5bc1d4..0d84d2c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-access/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-access/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-content-access</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/pom.xml
index a4ea12e..22b387c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-content-viewer</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-docs/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-docs/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-docs/pom.xml
index 7ccfdc8..04bd0a1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-docs/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-docs/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-docs</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/pom.xml
index 8809eb6..f4bee48 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-error</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/pom.xml
index 996fca2..78ab058 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-optimistic-locking/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-optimistic-locking</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
index 09eac44..931f682 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-web-security</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index 84c8e60..6e94211 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-web</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-web-ui</artifactId>
     <packaging>war</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
index 5ed64a1..d36c6c4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-web</artifactId>
     <packaging>pom</packaging>
@@ -40,31 +40,31 @@
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-api</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-error</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-docs</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-content-viewer</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-ui</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
index 8f20717..e04d04d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-framework-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework</artifactId>
     <packaging>pom</packaging>


[14/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java
index dc17c21..b9bfd00 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusDTO.java
@@ -14,38 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto.status;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
-/**
- * DTO for serializing the status of a connection.
- */
-@XmlType(name = "connectionStatus")
-public class ConnectionStatusDTO {
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
+@XmlType(name = "connectionStatus")
+public class ConnectionStatusDTO implements Cloneable {
     private String id;
     private String groupId;
     private String name;
-    private String input;
-    private String queuedCount;
-    private String queuedSize;
-    private String queued;
-    private String output;
+    private Date statsLastRefreshed;
 
     private String sourceId;
     private String sourceName;
     private String destinationId;
     private String destinationName;
 
-    /* getters / setters */
-    /**
-     * @return The connection id
-     */
-    @ApiModelProperty(
-            value = "The id of the connection."
-    )
+    private ConnectionStatusSnapshotDTO aggregateSnapshot;
+    private List<NodeConnectionStatusSnapshotDTO> nodeSnapshots;
+
+    @ApiModelProperty("The ID of the connection")
     public String getId() {
         return id;
     }
@@ -54,26 +51,16 @@ public class ConnectionStatusDTO {
         this.id = id;
     }
 
-    /**
-     * @return the ID of the Process Group to which this connection belongs.
-     */
-    @ApiModelProperty(
-            value = "The id of the process group the connection belongs to."
-    )
+    @ApiModelProperty("The ID of the Process Group that the connection belongs to")
     public String getGroupId() {
         return groupId;
     }
 
-    public void setGroupId(final String groupId) {
+    public void setGroupId(String groupId) {
         this.groupId = groupId;
     }
 
-    /**
-     * @return name of this connection
-     */
-    @ApiModelProperty(
-            value = "The name of the connection."
-    )
+    @ApiModelProperty("The name of the connection")
     public String getName() {
         return name;
     }
@@ -82,54 +69,7 @@ public class ConnectionStatusDTO {
         this.name = name;
     }
 
-    /**
-     * @return total count of flow files that are queued
-     */
-    @ApiModelProperty(
-            value = "The number of flowfiles that are queued."
-    )
-    public String getQueuedCount() {
-        return queuedCount;
-    }
-
-    public void setQueuedCount(String queuedCount) {
-        this.queuedCount = queuedCount;
-    }
-
-    /**
-     * @return total size of flow files that are queued
-     */
-    @ApiModelProperty(
-            value = "The total size of flowfiles that are queued formatted."
-    )
-    public String getQueuedSize() {
-        return queuedSize;
-    }
-
-    public void setQueuedSize(String queuedSize) {
-        this.queuedSize = queuedSize;
-    }
-
-    /**
-     * @return The total count and size of queued flow files
-     */
-    @ApiModelProperty(
-            value = "The total count and size of queued flowfiles formatted."
-    )
-    public String getQueued() {
-        return queued;
-    }
-
-    public void setQueued(String queued) {
-        this.queued = queued;
-    }
-
-    /**
-     * @return id of the source of this connection
-     */
-    @ApiModelProperty(
-            value = "The id of the source of the connection."
-    )
+    @ApiModelProperty("The ID of the source component")
     public String getSourceId() {
         return sourceId;
     }
@@ -138,12 +78,7 @@ public class ConnectionStatusDTO {
         this.sourceId = sourceId;
     }
 
-    /**
-     * @return name of the source of this connection
-     */
-    @ApiModelProperty(
-            value = "The name of the source of the connection."
-    )
+    @ApiModelProperty("The name of the source component")
     public String getSourceName() {
         return sourceName;
     }
@@ -152,12 +87,7 @@ public class ConnectionStatusDTO {
         this.sourceName = sourceName;
     }
 
-    /**
-     * @return id of the destination of this connection
-     */
-    @ApiModelProperty(
-            value = "The id of the destination of the connection."
-    )
+    @ApiModelProperty("The ID of the destination component")
     public String getDestinationId() {
         return destinationId;
     }
@@ -166,12 +96,7 @@ public class ConnectionStatusDTO {
         this.destinationId = destinationId;
     }
 
-    /**
-     * @return name of the destination of this connection
-     */
-    @ApiModelProperty(
-            value = "The name of the destination of the connection."
-    )
+    @ApiModelProperty("The name of the destination component")
     public String getDestinationName() {
         return destinationName;
     }
@@ -180,32 +105,53 @@ public class ConnectionStatusDTO {
         this.destinationName = destinationName;
     }
 
-    /**
-     * @return input for this connection
-     */
-    @ApiModelProperty(
-            value = "The input count/size for the connection in the last 5 minutes."
-    )
-    public String getInput() {
-        return input;
+    @ApiModelProperty("The status snapshot that represents the aggregate stats of the cluster")
+    public ConnectionStatusSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
     }
 
-    public void setInput(String input) {
-        this.input = input;
+    public void setAggregateSnapshot(ConnectionStatusSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
     }
 
-    /**
-     * @return output for this connection
-     */
-    @ApiModelProperty(
-            value = "The output count/sie for the connection in the last 5 minutes."
-    )
-    public String getOutput() {
-        return output;
+    @ApiModelProperty("A list of status snapshots for each node")
+    public List<NodeConnectionStatusSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
     }
 
-    public void setOutput(String output) {
-        this.output = output;
+    public void setNodeSnapshots(List<NodeConnectionStatusSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    @ApiModelProperty("The timestamp of when the stats were last refreshed")
+    public Date getStatsLastRefreshed() {
+        return statsLastRefreshed;
+    }
+
+    public void setStatsLastRefreshed(Date statsLastRefreshed) {
+        this.statsLastRefreshed = statsLastRefreshed;
+    }
+
+    @Override
+    public ConnectionStatusDTO clone() {
+        final ConnectionStatusDTO other = new ConnectionStatusDTO();
+        other.setDestinationId(getDestinationId());
+        other.setDestinationName(getDestinationName());
+        other.setGroupId(getGroupId());
+        other.setId(getId());
+        other.setName(getName());
+        other.setSourceId(getSourceId());
+        other.setSourceName(getSourceName());
+        other.setAggregateSnapshot(getAggregateSnapshot().clone());
+
+        final List<NodeConnectionStatusSnapshotDTO> nodeStatuses = getNodeSnapshots();
+        final List<NodeConnectionStatusSnapshotDTO> nodeStatusClones = new ArrayList<>(nodeStatuses.size());
+        for (final NodeConnectionStatusSnapshotDTO nodeStatus : nodeStatuses) {
+            nodeStatusClones.add(nodeStatus.clone());
+        }
+        other.setNodeSnapshots(nodeStatusClones);
+
+        return other;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java
new file mode 100644
index 0000000..928fc71
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ConnectionStatusSnapshotDTO.java
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * DTO for serializing the status of a connection.
+ */
+@XmlType(name = "connectionStatusSnapshot")
+public class ConnectionStatusSnapshotDTO implements Cloneable {
+
+    private String id;
+    private String groupId;
+    private String name;
+
+    private String sourceId;
+    private String sourceName;
+    private String destinationId;
+    private String destinationName;
+
+    private Integer flowFilesIn = 0;
+    private Long bytesIn = 0L;
+    private String input;
+    private Integer flowFilesOut = 0;
+    private Long bytesOut = 0L;
+    private String output;
+    private Integer flowFilesQueued = 0;
+    private Long bytesQueued = 0L;
+    private String queued;
+    private String queuedSize;
+    private String queuedCount;
+
+    /* getters / setters */
+    /**
+     * @return The connection id
+     */
+    @ApiModelProperty("The id of the connection.")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the ID of the Process Group to which this connection belongs.
+     */
+    @ApiModelProperty("The id of the process group the connection belongs to.")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(final String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * @return name of this connection
+     */
+    @ApiModelProperty("The name of the connection.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return total count of flow files that are queued
+     */
+    @ApiModelProperty("The number of flowfiles that are queued, pretty printed.")
+    public String getQueuedCount() {
+        return queuedCount;
+    }
+
+    public void setQueuedCount(String queuedCount) {
+        this.queuedCount = queuedCount;
+    }
+
+
+    /**
+     * @return total size of flow files that are queued
+     */
+    @ApiModelProperty("The total size of flowfiles that are queued formatted.")
+    public String getQueuedSize() {
+        return queuedSize;
+    }
+
+
+    public void setInput(String input) {
+        this.input = input;
+    }
+
+    public void setOutput(String output) {
+        this.output = output;
+    }
+
+    public void setQueued(String queued) {
+        this.queued = queued;
+    }
+
+    public void setQueuedSize(String queuedSize) {
+        this.queuedSize = queuedSize;
+    }
+
+    /**
+     * @return The total count and size of queued flow files
+     */
+    @ApiModelProperty("The total count and size of queued flowfiles formatted.")
+    public String getQueued() {
+        return queued;
+    }
+
+
+    /**
+     * @return id of the source of this connection
+     */
+    @ApiModelProperty("The id of the source of the connection.")
+    public String getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(String sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    /**
+     * @return name of the source of this connection
+     */
+    @ApiModelProperty("The name of the source of the connection.")
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * @return id of the destination of this connection
+     */
+    @ApiModelProperty("The id of the destination of the connection.")
+    public String getDestinationId() {
+        return destinationId;
+    }
+
+    public void setDestinationId(String destinationId) {
+        this.destinationId = destinationId;
+    }
+
+    /**
+     * @return name of the destination of this connection
+     */
+    @ApiModelProperty("The name of the destination of the connection.")
+    public String getDestinationName() {
+        return destinationName;
+    }
+
+    public void setDestinationName(String destinationName) {
+        this.destinationName = destinationName;
+    }
+
+    /**
+     * @return input for this connection
+     */
+    @ApiModelProperty("The input count/size for the connection in the last 5 minutes, pretty printed.")
+    public String getInput() {
+        return input;
+    }
+
+
+    /**
+     * @return output for this connection
+     */
+    @ApiModelProperty("The output count/sie for the connection in the last 5 minutes, pretty printed.")
+    public String getOutput() {
+        return output;
+    }
+
+
+    @ApiModelProperty("The number of FlowFiles that have come into the connection in the last 5 minutes.")
+    public Integer getFlowFilesIn() {
+        return flowFilesIn;
+    }
+
+    public void setFlowFilesIn(Integer flowFilesIn) {
+        this.flowFilesIn = flowFilesIn;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles that have come into the connection in the last 5 minutes.")
+    public Long getBytesIn() {
+        return bytesIn;
+    }
+
+    public void setBytesIn(Long bytesIn) {
+        this.bytesIn = bytesIn;
+    }
+
+    @ApiModelProperty("The number of FlowFiles that have left the connection in the last 5 minutes.")
+    public Integer getFlowFilesOut() {
+        return flowFilesOut;
+    }
+
+    public void setFlowFilesOut(Integer flowFilesOut) {
+        this.flowFilesOut = flowFilesOut;
+    }
+
+    @ApiModelProperty("The number of bytes that have left the connection in the last 5 minutes.")
+    public Long getBytesOut() {
+        return bytesOut;
+    }
+
+    public void setBytesOut(Long bytesOut) {
+        this.bytesOut = bytesOut;
+    }
+
+    @ApiModelProperty("The number of FlowFiles that are currently queued in the connection.")
+    public Integer getFlowFilesQueued() {
+        return flowFilesQueued;
+    }
+
+    public void setFlowFilesQueued(Integer flowFilesQueued) {
+        this.flowFilesQueued = flowFilesQueued;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles that are currently queued in the connection.")
+    public Long getBytesQueued() {
+        return bytesQueued;
+    }
+
+    public void setBytesQueued(Long bytesQueued) {
+        this.bytesQueued = bytesQueued;
+    }
+
+
+    @Override
+    public ConnectionStatusSnapshotDTO clone() {
+        final ConnectionStatusSnapshotDTO other = new ConnectionStatusSnapshotDTO();
+        other.setDestinationId(getDestinationId());
+        other.setDestinationName(getDestinationName());
+        other.setGroupId(getGroupId());
+        other.setId(getId());
+        other.setName(getName());
+        other.setSourceId(getSourceId());
+        other.setSourceName(getSourceName());
+
+        other.setFlowFilesIn(getFlowFilesIn());
+        other.setBytesIn(getBytesIn());
+        other.setInput(getInput());
+        other.setFlowFilesOut(getFlowFilesOut());
+        other.setBytesOut(getBytesOut());
+        other.setOutput(getOutput());
+        other.setFlowFilesQueued(getFlowFilesQueued());
+        other.setBytesQueued(getBytesQueued());
+        other.setQueued(getQueued());
+        other.setQueuedCount(getQueuedCount());
+        other.setQueuedSize(getQueuedSize());
+
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ControllerStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ControllerStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ControllerStatusDTO.java
index 5d5eddf..03e2124 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ControllerStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ControllerStatusDTO.java
@@ -17,6 +17,8 @@
 package org.apache.nifi.web.api.dto.status;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
+
+import java.util.ArrayList;
 import java.util.List;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.nifi.web.api.dto.BulletinDTO;
@@ -25,19 +27,25 @@ import org.apache.nifi.web.api.dto.BulletinDTO;
  * The status of this NiFi controller.
  */
 @XmlType(name = "controllerStatus")
-public class ControllerStatusDTO {
+public class ControllerStatusDTO implements Cloneable {
 
-    private Integer activeThreadCount;
+    private Integer activeThreadCount = 0;
     private String queued;
+    private Integer flowFilesQueued = 0;
+    private Long bytesQueued = 0L;
+
     private String connectedNodes;
+    private Integer connectedNodeCount = 0;
+    private Integer totalNodeCount = 0;
+
     private Boolean hasPendingAccounts;
 
-    private Integer runningCount;
-    private Integer stoppedCount;
-    private Integer invalidCount;
-    private Integer disabledCount;
-    private Integer activeRemotePortCount;
-    private Integer inactiveRemotePortCount;
+    private Integer runningCount = 0;
+    private Integer stoppedCount = 0;
+    private Integer invalidCount = 0;
+    private Integer disabledCount = 0;
+    private Integer activeRemotePortCount = 0;
+    private Integer inactiveRemotePortCount = 0;
 
     private List<BulletinDTO> bulletins;
     private List<BulletinDTO> controllerServiceBulletins;
@@ -48,9 +56,7 @@ public class ControllerStatusDTO {
      *
      * @return The active thread count
      */
-    @ApiModelProperty(
-            value = "The number of active threads in the NiFi."
-    )
+    @ApiModelProperty("The number of active threads in the NiFi.")
     public Integer getActiveThreadCount() {
         return activeThreadCount;
     }
@@ -62,9 +68,7 @@ public class ControllerStatusDTO {
     /**
      * @return queue for the controller
      */
-    @ApiModelProperty(
-            value = "The number of flowfilew queued in the NiFi."
-    )
+    @ApiModelProperty("The number of flowfilew queued in the NiFi.")
     public String getQueued() {
         return queued;
     }
@@ -77,9 +81,7 @@ public class ControllerStatusDTO {
      * @return Used in clustering, will report the number of nodes connected vs
      * the number of nodes in the cluster
      */
-    @ApiModelProperty(
-            value = "When clustered, reports the number of nodes connected vs the number of nodes in the cluster."
-    )
+    @ApiModelProperty("When clustered, reports the number of nodes connected vs the number of nodes in the cluster.")
     public String getConnectedNodes() {
         return connectedNodes;
     }
@@ -91,9 +93,7 @@ public class ControllerStatusDTO {
     /**
      * @return System bulletins to be reported to the user
      */
-    @ApiModelProperty(
-            value = "System level bulletins to be reported to the user."
-    )
+    @ApiModelProperty("System level bulletins to be reported to the user.")
     public List<BulletinDTO> getBulletins() {
         return bulletins;
     }
@@ -105,9 +105,7 @@ public class ControllerStatusDTO {
     /**
      * @return Controller service bulletins to be reported to the user
      */
-    @ApiModelProperty(
-            value = "Controller service bulletins to be reported to the user."
-    )
+    @ApiModelProperty("Controller service bulletins to be reported to the user.")
     public List<BulletinDTO> getControllerServiceBulletins() {
         return controllerServiceBulletins;
     }
@@ -119,9 +117,7 @@ public class ControllerStatusDTO {
     /**
      * @return Reporting task bulletins to be reported to the user
      */
-    @ApiModelProperty(
-            value = "Reporting task bulletins to be reported to the user."
-    )
+    @ApiModelProperty("Reporting task bulletins to be reported to the user.")
     public List<BulletinDTO> getReportingTaskBulletins() {
         return reportingTaskBulletins;
     }
@@ -133,9 +129,7 @@ public class ControllerStatusDTO {
     /**
      * @return whether or not there are pending user requests
      */
-    @ApiModelProperty(
-            value = "Whether there are any pending user account requests."
-    )
+    @ApiModelProperty("Whether there are any pending user account requests.")
     public Boolean getHasPendingAccounts() {
         return hasPendingAccounts;
     }
@@ -147,9 +141,7 @@ public class ControllerStatusDTO {
     /**
      * @return number of running components in this controller
      */
-    @ApiModelProperty(
-            value = "The number of running components in the NiFi."
-    )
+    @ApiModelProperty("The number of running components in the NiFi.")
     public Integer getRunningCount() {
         return runningCount;
     }
@@ -161,9 +153,7 @@ public class ControllerStatusDTO {
     /**
      * @return number of stopped components in this controller
      */
-    @ApiModelProperty(
-            value = "The number of stopped components in the NiFi."
-    )
+    @ApiModelProperty("The number of stopped components in the NiFi.")
     public Integer getStoppedCount() {
         return stoppedCount;
     }
@@ -175,9 +165,7 @@ public class ControllerStatusDTO {
     /**
      * @return number of invalid components in this controller
      */
-    @ApiModelProperty(
-            value = "The number of invalid components in the NiFi."
-    )
+    @ApiModelProperty("The number of invalid components in the NiFi.")
     public Integer getInvalidCount() {
         return invalidCount;
     }
@@ -189,9 +177,7 @@ public class ControllerStatusDTO {
     /**
      * @return number of disabled components in this controller
      */
-    @ApiModelProperty(
-            value = "The number of disabled components in the NiFi."
-    )
+    @ApiModelProperty("The number of disabled components in the NiFi.")
     public Integer getDisabledCount() {
         return disabledCount;
     }
@@ -203,9 +189,7 @@ public class ControllerStatusDTO {
     /**
      * @return number of active remote ports in this controller
      */
-    @ApiModelProperty(
-            value = "The number of active remote ports in the NiFi."
-    )
+    @ApiModelProperty("The number of active remote ports in the NiFi.")
     public Integer getActiveRemotePortCount() {
         return activeRemotePortCount;
     }
@@ -217,9 +201,7 @@ public class ControllerStatusDTO {
     /**
      * @return number of inactive remote ports in this controller
      */
-    @ApiModelProperty(
-            value = "The number of inactive remote ports in the NiFi."
-    )
+    @ApiModelProperty("The number of inactive remote ports in the NiFi.")
     public Integer getInactiveRemotePortCount() {
         return inactiveRemotePortCount;
     }
@@ -228,4 +210,62 @@ public class ControllerStatusDTO {
         this.inactiveRemotePortCount = inactiveRemotePortCount;
     }
 
+    @ApiModelProperty("The number of FlowFiles queued across the entire flow")
+    public Integer getFlowFilesQueued() {
+        return flowFilesQueued;
+    }
+
+    public void setFlowFilesQueued(Integer flowFilesQueued) {
+        this.flowFilesQueued = flowFilesQueued;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles queued across the entire flow")
+    public Long getBytesQueued() {
+        return bytesQueued;
+    }
+
+    public void setBytesQueued(Long bytesQueued) {
+        this.bytesQueued = bytesQueued;
+    }
+
+    @ApiModelProperty("The number of nodes that are currently connected to the cluster")
+    public Integer getConnectedNodeCount() {
+        return connectedNodeCount;
+    }
+
+    public void setConnectedNodeCount(Integer connectedNodeCount) {
+        this.connectedNodeCount = connectedNodeCount;
+    }
+
+    @ApiModelProperty("The number of nodes in the cluster, regardless of whether or not they are connected")
+    public Integer getTotalNodeCount() {
+        return totalNodeCount;
+    }
+
+    public void setTotalNodeCount(Integer totalNodeCount) {
+        this.totalNodeCount = totalNodeCount;
+    }
+
+    @Override
+    public ControllerStatusDTO clone() {
+        final ControllerStatusDTO other = new ControllerStatusDTO();
+        other.setActiveThreadCount(getActiveThreadCount());
+        other.setQueued(getQueued());
+        other.setFlowFilesQueued(getFlowFilesQueued());
+        other.setBytesQueued(getBytesQueued());
+        other.setConnectedNodes(getConnectedNodes());
+        other.setConnectedNodeCount(getConnectedNodeCount());
+        other.setTotalNodeCount(getTotalNodeCount());
+        other.setHasPendingAccounts(getHasPendingAccounts());
+        other.setRunningCount(getRunningCount());
+        other.setStoppedCount(getStoppedCount());
+        other.setInvalidCount(getInvalidCount());
+        other.setDisabledCount(getDisabledCount());
+        other.setActiveRemotePortCount(getActiveRemotePortCount());
+        other.setInactiveRemotePortCount(getInactiveRemotePortCount());
+        other.setBulletins(getBulletins() == null ? null : new ArrayList<>(getBulletins()));
+        other.setControllerServiceBulletins(getControllerServiceBulletins() == null ? null : new ArrayList<>(getControllerServiceBulletins()));
+        other.setReportingTaskBulletins(getReportingTaskBulletins() == null ? null : new ArrayList<>(getReportingTaskBulletins()));
+        return other;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusDTO.java
deleted file mode 100644
index bcc4045..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusDTO.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.nifi.web.api.dto.NodeDTO;
-
-/**
- * DTO for serializing the connection status for a particular node.
- */
-@XmlType(name = "nodeConnectionStatus")
-public class NodeConnectionStatusDTO {
-
-    private NodeDTO node;
-    private ConnectionStatusDTO connectionStatus;
-
-    /**
-     * @return the node
-     */
-    @ApiModelProperty(
-            value = "The node."
-    )
-    public NodeDTO getNode() {
-        return node;
-    }
-
-    public void setNode(NodeDTO node) {
-        this.node = node;
-    }
-
-    /**
-     * @return connection's status
-     */
-    @ApiModelProperty(
-            value = "The connection status from the node."
-    )
-    public ConnectionStatusDTO getConnectionStatus() {
-        return connectionStatus;
-    }
-
-    public void setConnectionStatus(ConnectionStatusDTO connectionStatus) {
-        this.connectionStatus = connectionStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusSnapshotDTO.java
new file mode 100644
index 0000000..41f7433
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeConnectionStatusSnapshotDTO.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+@XmlType(name = "nodeConnectionStatusSnapshot")
+public class NodeConnectionStatusSnapshotDTO implements Cloneable {
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private ConnectionStatusSnapshotDTO statusSnapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The connection status snapshot from the node.")
+    public ConnectionStatusSnapshotDTO getStatusSnapshot() {
+        return statusSnapshot;
+    }
+
+    public void setStatusSnapshot(ConnectionStatusSnapshotDTO statusSnapshot) {
+        this.statusSnapshot = statusSnapshot;
+    }
+
+    @Override
+    public NodeConnectionStatusSnapshotDTO clone() {
+        final NodeConnectionStatusSnapshotDTO other = new NodeConnectionStatusSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setStatusSnapshot(getStatusSnapshot().clone());
+        return other;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodePortStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodePortStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodePortStatusSnapshotDTO.java
new file mode 100644
index 0000000..a8dc1ff
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodePortStatusSnapshotDTO.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+@XmlType(name = "nodePortStatusSnapshot")
+public class NodePortStatusSnapshotDTO implements Cloneable {
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private PortStatusSnapshotDTO statusSnapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The port status snapshot from the node.")
+    public PortStatusSnapshotDTO getStatusSnapshot() {
+        return statusSnapshot;
+    }
+
+    public void setStatusSnapshot(PortStatusSnapshotDTO status) {
+        this.statusSnapshot = status;
+    }
+
+    @Override
+    public NodePortStatusSnapshotDTO clone() {
+        final NodePortStatusSnapshotDTO other = new NodePortStatusSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setStatusSnapshot(getStatusSnapshot().clone());
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusDTO.java
deleted file mode 100644
index 96c59fa..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusDTO.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.nifi.web.api.dto.NodeDTO;
-
-/**
- * DTO for serializing the process group status for a particular node.
- */
-@XmlType(name = "nodeProcessGroupStatus")
-public class NodeProcessGroupStatusDTO {
-
-    private NodeDTO node;
-    private ProcessGroupStatusDTO processGroupStatus;
-
-    /**
-     * The node.
-     *
-     * @return The node DTO
-     */
-    @ApiModelProperty(
-            value = "The node."
-    )
-    public NodeDTO getNode() {
-        return node;
-    }
-
-    public void setNode(NodeDTO node) {
-        this.node = node;
-    }
-
-    /**
-     * The process group's status.
-     *
-     * @return The process group status
-     */
-    @ApiModelProperty(
-            value = "The process group status from the node."
-    )
-    public ProcessGroupStatusDTO getProcessGroupStatus() {
-        return processGroupStatus;
-    }
-
-    public void setProcessGroupStatus(ProcessGroupStatusDTO processGroupStatus) {
-        this.processGroupStatus = processGroupStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusSnapshotDTO.java
new file mode 100644
index 0000000..854b077
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessGroupStatusSnapshotDTO.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto.status;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+public class NodeProcessGroupStatusSnapshotDTO implements Cloneable {
+
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private ProcessGroupStatusSnapshotDTO statusSnapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The process group status snapshot from the node.")
+    public ProcessGroupStatusSnapshotDTO getStatusSnapshot() {
+        return statusSnapshot;
+    }
+
+    public void setStatusSnapshot(ProcessGroupStatusSnapshotDTO statusSnapshot) {
+        this.statusSnapshot = statusSnapshot;
+    }
+
+    @Override
+    public NodeProcessGroupStatusSnapshotDTO clone() {
+        final NodeProcessGroupStatusSnapshotDTO other = new NodeProcessGroupStatusSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setStatusSnapshot(getStatusSnapshot().clone());
+        return other;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusDTO.java
deleted file mode 100644
index 8c8f604..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusDTO.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.nifi.web.api.dto.NodeDTO;
-
-/**
- * DTO for serializing the processor status for a particular node.
- */
-@XmlType(name = "nodeProcessorStatus")
-public class NodeProcessorStatusDTO {
-
-    private NodeDTO node;
-    private ProcessorStatusDTO processorStatus;
-
-    /**
-     * @return the node
-     */
-    @ApiModelProperty(
-            value = "The node."
-    )
-    public NodeDTO getNode() {
-        return node;
-    }
-
-    public void setNode(NodeDTO node) {
-        this.node = node;
-    }
-
-    /**
-     * @return processor's status
-     */
-    @ApiModelProperty(
-            value = "The processor status from the node."
-    )
-    public ProcessorStatusDTO getProcessorStatus() {
-        return processorStatus;
-    }
-
-    public void setProcessorStatus(ProcessorStatusDTO processorStatus) {
-        this.processorStatus = processorStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusSnapshotDTO.java
new file mode 100644
index 0000000..5ea4697
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeProcessorStatusSnapshotDTO.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+/**
+ * DTO for serializing the processor status for a particular node.
+ */
+@XmlType(name = "nodeProcessorStatusSnapshot")
+public class NodeProcessorStatusSnapshotDTO implements Cloneable {
+
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private ProcessorStatusSnapshotDTO statusSnapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The processor status snapshot from the node.")
+    public ProcessorStatusSnapshotDTO getStatusSnapshot() {
+        return statusSnapshot;
+    }
+
+    public void setStatusSnapshot(ProcessorStatusSnapshotDTO processorStatusSnapshot) {
+        this.statusSnapshot = processorStatusSnapshot;
+    }
+
+    @Override
+    public NodeProcessorStatusSnapshotDTO clone() {
+        final NodeProcessorStatusSnapshotDTO other = new NodeProcessorStatusSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setStatusSnapshot(getStatusSnapshot().clone());
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java
new file mode 100644
index 0000000..3cd93bc
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemotePortStatusSnapshotDTO.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+@XmlType(name = "nodeRemotePortStatusSnapshot")
+public class NodeRemotePortStatusSnapshotDTO implements Cloneable {
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private RemotePortStatusDTO statusSnapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The remote port status snapshot from the node.")
+    public RemotePortStatusDTO getStatusSnapshot() {
+        return statusSnapshot;
+    }
+
+    public void setStatusSnapshot(RemotePortStatusDTO statusSnapshot) {
+        this.statusSnapshot = statusSnapshot;
+    }
+
+    @Override
+    public NodeRemotePortStatusSnapshotDTO clone() {
+        final NodeRemotePortStatusSnapshotDTO other = new NodeRemotePortStatusSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setStatusSnapshot(getStatusSnapshot().clone());
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusDTO.java
deleted file mode 100644
index 512b4c2..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusDTO.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.nifi.web.api.dto.NodeDTO;
-
-/**
- * DTO for serializing the remote process group status for a particular node.
- */
-@XmlType(name = "nodeRemoteProcessGroupStatus")
-public class NodeRemoteProcessGroupStatusDTO {
-
-    private NodeDTO node;
-    private RemoteProcessGroupStatusDTO remoteProcessGroupStatus;
-
-    /**
-     * @return the node
-     */
-    @ApiModelProperty(
-            value = "The node."
-    )
-    public NodeDTO getNode() {
-        return node;
-    }
-
-    public void setNode(NodeDTO node) {
-        this.node = node;
-    }
-
-    /**
-     * @return remote process group's status
-     */
-    @ApiModelProperty(
-            value = "The remote process group status from the node."
-    )
-    public RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus() {
-        return remoteProcessGroupStatus;
-    }
-
-    public void setRemoteProcessGroupStatus(RemoteProcessGroupStatusDTO remoteProcessGroupStatus) {
-        this.remoteProcessGroupStatus = remoteProcessGroupStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusSnapshotDTO.java
new file mode 100644
index 0000000..57658f2
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeRemoteProcessGroupStatusSnapshotDTO.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+@XmlType(name = "nodeRemoteProcessGroupStatusSnapshot")
+public class NodeRemoteProcessGroupStatusSnapshotDTO implements Cloneable {
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+
+    private RemoteProcessGroupStatusSnapshotDTO statusSnapshot;
+
+    @ApiModelProperty("The unique ID that identifies the node")
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @ApiModelProperty("The API address of the node")
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @ApiModelProperty("The API port used to communicate with the node")
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer apiPort) {
+        this.apiPort = apiPort;
+    }
+
+    @ApiModelProperty("The remote process group status snapshot from the node.")
+    public RemoteProcessGroupStatusSnapshotDTO getStatusSnapshot() {
+        return statusSnapshot;
+    }
+
+    public void setStatusSnapshot(RemoteProcessGroupStatusSnapshotDTO statusSnapshot) {
+        this.statusSnapshot = statusSnapshot;
+    }
+
+    @Override
+    public NodeRemoteProcessGroupStatusSnapshotDTO clone() {
+        final NodeRemoteProcessGroupStatusSnapshotDTO other = new NodeRemoteProcessGroupStatusSnapshotDTO();
+        other.setNodeId(getNodeId());
+        other.setAddress(getAddress());
+        other.setApiPort(getApiPort());
+        other.setStatusSnapshot(getStatusSnapshot().clone());
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusHistoryDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusHistoryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusHistoryDTO.java
deleted file mode 100644
index 5cf9f41..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusHistoryDTO.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.nifi.web.api.dto.NodeDTO;
-
-/**
- * DTO for serializing the status history for a particular node.
- */
-@XmlType(name = "nodeStatusHistory")
-public class NodeStatusHistoryDTO {
-
-    private NodeDTO node;
-    private StatusHistoryDTO statusHistory;
-
-    /**
-     * @return the node
-     */
-    @ApiModelProperty(
-            value = "The node."
-    )
-    public NodeDTO getNode() {
-        return node;
-    }
-
-    public void setNode(NodeDTO node) {
-        this.node = node;
-    }
-
-    /**
-     * @return processor status history
-     */
-    @ApiModelProperty(
-            value = "The processor status for each node."
-    )
-    public StatusHistoryDTO getStatusHistory() {
-        return statusHistory;
-    }
-
-    public void setStatusHistory(StatusHistoryDTO statusHistory) {
-        this.statusHistory = statusHistory;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusSnapshotsDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusSnapshotsDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusSnapshotsDTO.java
new file mode 100644
index 0000000..f70da4a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/NodeStatusSnapshotsDTO.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+import javax.xml.bind.annotation.XmlType;
+import java.util.List;
+
+/**
+ * DTO for serializing the status history of a single component across the cluster.
+ */
+@XmlType(name = "nodeStatusSnapshots")
+public class NodeStatusSnapshotsDTO {
+
+    private String nodeId;
+    private String address;
+    private Integer apiPort;
+    private List<StatusSnapshotDTO> statusSnapshots;
+
+    /**
+     * @return node's host/IP address
+     */
+    @ApiModelProperty(
+        value = "The node's host/ip address."
+    )
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    /**
+     * @return node ID
+     */
+    @ApiModelProperty(
+        value = "The id of the node."
+    )
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    /**
+     * @return port the node is listening for API requests
+     */
+    @ApiModelProperty(
+        value = "The port the node is listening for API requests."
+    )
+    public Integer getApiPort() {
+        return apiPort;
+    }
+
+    public void setApiPort(Integer port) {
+        this.apiPort = port;
+    }
+
+    @ApiModelProperty("A list of StatusSnapshotDTO objects that provide the actual metric values for the component for this node.")
+    public List<StatusSnapshotDTO> getStatusSnapshots() {
+        return statusSnapshots;
+    }
+
+    public void setStatusSnapshots(List<StatusSnapshotDTO> statusSnapshots) {
+        this.statusSnapshots = statusSnapshots;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java
index c1d95d0..5e44e71 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusDTO.java
@@ -14,32 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto.status;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import java.util.Date;
+import java.util.List;
+
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
-/**
- * The status for a port in this NiFi.
- */
-@XmlType(name = "portStatus")
-public class PortStatusDTO extends StatusDTO {
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
+@XmlType(name = "portStatus")
+public class PortStatusDTO {
     private String id;
     private String groupId;
     private String name;
-    private Integer activeThreadCount;
-    private String input;
-    private String output;
     private Boolean transmitting;
     private String runStatus;
+    private Date statsLastRefreshed;
 
-    /**
-     * @return whether this port has incoming or outgoing connections to a remote NiFi
-     */
-    @ApiModelProperty(
-            value = "Whether the port has incoming or outgoing connections to a remote NiFi."
-    )
+    private PortStatusSnapshotDTO aggregateSnapshot;
+    private List<NodePortStatusSnapshotDTO> nodeSnapshots;
+
+    @ApiModelProperty("Whether the port has incoming or outgoing connections to a remote NiFi.")
     public Boolean isTransmitting() {
         return transmitting;
     }
@@ -48,26 +47,8 @@ public class PortStatusDTO extends StatusDTO {
         this.transmitting = transmitting;
     }
 
-    /**
-     * @return the active thread count for this port
-     */
-    @ApiModelProperty(
-            value = "The active thread count for the port."
-    )
-    public Integer getActiveThreadCount() {
-        return activeThreadCount;
-    }
-
-    public void setActiveThreadCount(Integer activeThreadCount) {
-        this.activeThreadCount = activeThreadCount;
-    }
 
-    /**
-     * @return id of this port
-     */
-    @ApiModelProperty(
-            value = "The id of the port."
-    )
+    @ApiModelProperty("The id of the port.")
     public String getId() {
         return id;
     }
@@ -76,12 +57,8 @@ public class PortStatusDTO extends StatusDTO {
         this.id = id;
     }
 
-    /**
-     * @return id of the group this port resides in
-     */
-    @ApiModelProperty(
-            value = "The id of the parent process group of the port."
-    )
+
+    @ApiModelProperty("The id of the parent process group of the port.")
     public String getGroupId() {
         return groupId;
     }
@@ -90,12 +67,8 @@ public class PortStatusDTO extends StatusDTO {
         this.groupId = groupId;
     }
 
-    /**
-     * @return name of this port
-     */
-    @ApiModelProperty(
-            value = "The name of the port."
-    )
+
+    @ApiModelProperty("The name of the port.")
     public String getName() {
         return name;
     }
@@ -104,12 +77,8 @@ public class PortStatusDTO extends StatusDTO {
         this.name = name;
     }
 
-    /**
-     * @return run status of this port
-     */
-    @ApiModelProperty(
-            value = "The run status of the port."
-    )
+
+    @ApiModelProperty("The run status of the port.")
     public String getRunStatus() {
         return runStatus;
     }
@@ -118,32 +87,40 @@ public class PortStatusDTO extends StatusDTO {
         this.runStatus = runStatus;
     }
 
-    /**
-     * @return The total count and size of flow files that have been accepted in the last five minutes
-     */
-    @ApiModelProperty(
-            value = "The count/size of flowfiles that have been accepted in the last 5 minutes."
-    )
-    public String getInput() {
-        return input;
+    @ApiModelProperty("A status snapshot that represents the aggregate stats of all nodes in the cluster. If the NiFi instance is "
+        + "a standalone instance, rather than a cluster, this represents the stats of the single instance.")
+    public PortStatusSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
     }
 
-    public void setInput(String input) {
-        this.input = input;
+    public void setAggregateSnapshot(PortStatusSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
+    }
+
+    @ApiModelProperty("A status snapshot for each node in the cluster. If the NiFi instance is a standalone instance, rather than "
+        + "a cluster, this may be null.")
+    public List<NodePortStatusSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
+    }
+
+    public void setNodeSnapshots(List<NodePortStatusSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 
     /**
-     * @return The total count and size of flow files that have been processed in the last five minutes
+     * When the status for this process group was calculated.
+     *
+     * @return The the status was calculated
      */
+    @XmlJavaTypeAdapter(TimeAdapter.class)
     @ApiModelProperty(
-            value = "The count/size of flowfiles that have been processed in the last 5 minutes."
+        value = "The time the status for the process group was last refreshed."
     )
-    public String getOutput() {
-        return output;
+    public Date getStatsLastRefreshed() {
+        return statsLastRefreshed;
     }
 
-    public void setOutput(String output) {
-        this.output = output;
+    public void setStatsLastRefreshed(Date statsLastRefreshed) {
+        this.statsLastRefreshed = statsLastRefreshed;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java
new file mode 100644
index 0000000..b5f11e5
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/PortStatusSnapshotDTO.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+/**
+ * The status for a port in this NiFi.
+ */
+@XmlType(name = "portStatusSnapshot")
+public class PortStatusSnapshotDTO implements Cloneable {
+
+    private String id;
+    private String groupId;
+    private String name;
+
+    private Integer activeThreadCount = 0;
+    private Integer flowFilesIn = 0;
+    private Long bytesIn = 0L;
+    private String input;
+    private Integer flowFilesOut = 0;
+    private Long bytesOut = 0L;
+    private String output;
+
+    private Boolean transmitting;
+    private String runStatus;
+
+    /**
+     * @return whether this port has incoming or outgoing connections to a remote NiFi
+     */
+    @ApiModelProperty("Whether the port has incoming or outgoing connections to a remote NiFi.")
+    public Boolean isTransmitting() {
+        return transmitting;
+    }
+
+    public void setTransmitting(Boolean transmitting) {
+        this.transmitting = transmitting;
+    }
+
+    /**
+     * @return the active thread count for this port
+     */
+    @ApiModelProperty("The active thread count for the port.")
+    public Integer getActiveThreadCount() {
+        return activeThreadCount;
+    }
+
+    public void setActiveThreadCount(Integer activeThreadCount) {
+        this.activeThreadCount = activeThreadCount;
+    }
+
+    /**
+     * @return id of this port
+     */
+    @ApiModelProperty("The id of the port.")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return id of the group this port resides in
+     */
+    @ApiModelProperty("The id of the parent process group of the port.")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * @return name of this port
+     */
+    @ApiModelProperty("The name of the port.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return run status of this port
+     */
+    @ApiModelProperty("The run status of the port.")
+    public String getRunStatus() {
+        return runStatus;
+    }
+
+    public void setRunStatus(String runStatus) {
+        this.runStatus = runStatus;
+    }
+
+    /**
+     * @return The total count and size of flow files that have been accepted in the last five minutes
+     */
+    @ApiModelProperty("The count/size of flowfiles that have been accepted in the last 5 minutes.")
+    public String getInput() {
+        return input;
+    }
+
+    public void setInput(String input) {
+        this.input = input;
+    }
+
+    /**
+     * @return The total count and size of flow files that have been processed in the last five minutes
+     */
+    @ApiModelProperty("The count/size of flowfiles that have been processed in the last 5 minutes.")
+    public String getOutput() {
+        return output;
+    }
+
+    public void setOutput(String output) {
+        this.output = output;
+    }
+
+    @ApiModelProperty("The number of FlowFiles that have been accepted in the last 5 minutes.")
+    public Integer getFlowFilesIn() {
+        return flowFilesIn;
+    }
+
+    public void setFlowFilesIn(Integer flowFilesIn) {
+        this.flowFilesIn = flowFilesIn;
+    }
+
+    @ApiModelProperty("The size of hte FlowFiles that have been accepted in the last 5 minutes.")
+    public Long getBytesIn() {
+        return bytesIn;
+    }
+
+    public void setBytesIn(Long bytesIn) {
+        this.bytesIn = bytesIn;
+    }
+
+    @ApiModelProperty("The number of FlowFiles that have been processed in the last 5 minutes.")
+    public Integer getFlowFilesOut() {
+        return flowFilesOut;
+    }
+
+    public void setFlowFilesOut(Integer flowFilesOut) {
+        this.flowFilesOut = flowFilesOut;
+    }
+
+    @ApiModelProperty("The number of bytes that have been processed in the last 5 minutes.")
+    public Long getBytesOut() {
+        return bytesOut;
+    }
+
+    public void setBytesOut(Long bytesOut) {
+        this.bytesOut = bytesOut;
+    }
+
+    @Override
+    public PortStatusSnapshotDTO clone() {
+        final PortStatusSnapshotDTO other = new PortStatusSnapshotDTO();
+        other.setId(getId());
+        other.setGroupId(getGroupId());
+        other.setName(getName());
+        other.setActiveThreadCount(getActiveThreadCount());
+        other.setFlowFilesIn(getFlowFilesIn());
+        other.setBytesIn(getBytesIn());
+        other.setFlowFilesOut(getFlowFilesOut());
+        other.setBytesOut(getBytesOut());
+        other.setTransmitting(isTransmitting());
+        other.setRunStatus(getRunStatus());
+        other.setInput(getInput());
+        other.setOutput(getOutput());
+
+        return other;
+    }
+}


[04/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
index a48758a..49ad85b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
@@ -29,12 +29,6 @@ nf.SummaryTable = (function () {
         urls: {
             status: '../nifi-api/controller/process-groups/root/status',
             processGroups: '../nifi-api/controller/process-groups/',
-            clusterProcessor: '../nifi-api/cluster/processors/',
-            clusterConnection: '../nifi-api/cluster/connections/',
-            clusterProcessGroup: '../nifi-api/cluster/process-groups/',
-            clusterInputPort: '../nifi-api/cluster/input-ports/',
-            clusterOutputPort: '../nifi-api/cluster/output-ports/',
-            clusterRemoteProcessGroup: '../nifi-api/cluster/remote-process-groups/',
             systemDiagnostics: '../nifi-api/system-diagnostics',
             controllerConfig: '../nifi-api/controller/config',
             d3Script: 'js/d3/d3.min.js',
@@ -364,11 +358,7 @@ nf.SummaryTable = (function () {
                 }
 
                 if (nf.Common.SUPPORTS_SVG) {
-                    if (isClustered) {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-cluster-processor-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    } else {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-processor-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    }
+                    markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-processor-status-history" style="margin-top: 2px;"/>&nbsp;';
                 }
 
                 if (isClustered) {
@@ -432,13 +422,11 @@ nf.SummaryTable = (function () {
             if (processorsGrid.getColumns()[args.cell].id === 'actions') {
                 if (target.hasClass('go-to')) {
                     goTo(item.groupId, item.id);
-                } else if (target.hasClass('show-cluster-processor-status-history')) {
-                    nf.StatusHistory.showClusterProcessorChart(item.groupId, item.id);
                 } else if (target.hasClass('show-processor-status-history')) {
-                    nf.StatusHistory.showStandaloneProcessorChart(item.groupId, item.id);
+                    nf.StatusHistory.showProcessorChart(item.groupId, item.id);
                 } else if (target.hasClass('show-cluster-processor-summary')) {
                     // load the cluster processor summary
-                    loadClusterProcessorSummary(item.id);
+                    loadClusterProcessorSummary(item.groupId, item.id);
 
                     // hide the summary loading indicator
                     $('#summary-loading-container').hide();
@@ -526,7 +514,7 @@ nf.SummaryTable = (function () {
         
         // cluster processor refresh
         nf.Common.addHoverEffect('#cluster-processor-refresh-button', 'button-refresh', 'button-refresh-hover').click(function () {
-            loadClusterProcessorSummary($('#cluster-processor-id').text());
+            loadClusterProcessorSummary($('#cluster-processor-group-id').text(), $('#cluster-processor-id').text());
         });
 
         // initialize the cluster processor column model
@@ -616,11 +604,7 @@ nf.SummaryTable = (function () {
                 }
 
                 if (nf.Common.SUPPORTS_SVG) {
-                    if (isClustered) {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-cluster-connection-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    } else {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-connection-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    }
+                    markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-connection-status-history" style="margin-top: 2px;"/>&nbsp;';
                 }
 
                 if (isClustered) {
@@ -684,13 +668,11 @@ nf.SummaryTable = (function () {
             if (connectionsGrid.getColumns()[args.cell].id === 'actions') {
                 if (target.hasClass('go-to')) {
                     goTo(item.groupId, item.id);
-                } else if (target.hasClass('show-cluster-connection-status-history')) {
-                    nf.StatusHistory.showClusterConnectionChart(item.groupId, item.id);
                 } else if (target.hasClass('show-connection-status-history')) {
-                    nf.StatusHistory.showStandaloneConnectionChart(item.groupId, item.id);
+                    nf.StatusHistory.showConnectionChart(item.groupId, item.id);
                 } else if (target.hasClass('show-cluster-connection-summary')) {
                     // load the cluster processor summary
-                    loadClusterConnectionSummary(item.id);
+                    loadClusterConnectionSummary(item.groupId, item.id);
 
                     // hide the summary loading indicator
                     $('#summary-loading-container').hide();
@@ -750,7 +732,7 @@ nf.SummaryTable = (function () {
         
         // cluster connection refresh
         nf.Common.addHoverEffect('#cluster-connection-refresh-button', 'button-refresh', 'button-refresh-hover').click(function () {
-            loadClusterConnectionSummary($('#cluster-connection-id').text());
+            loadClusterConnectionSummary($('#cluster-connection-group-id').text(), $('#cluster-connection-id').text());
         });
 
         // initialize the cluster processor column model
@@ -848,11 +830,7 @@ nf.SummaryTable = (function () {
                 }
 
                 if (nf.Common.SUPPORTS_SVG) {
-                    if (isClustered) {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-cluster-process-group-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    } else {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-process-group-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    }
+                    markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-process-group-status-history" style="margin-top: 2px;"/>&nbsp;';
                 }
 
                 if (isClustered) {
@@ -919,10 +897,8 @@ nf.SummaryTable = (function () {
                         parent.nf.CanvasUtils.enterGroup(item.id);
                         parent.$('#shell-close-button').click();
                     }
-                } else if (target.hasClass('show-cluster-process-group-status-history')) {
-                    nf.StatusHistory.showClusterProcessGroupChart(item.groupId, item.id);
                 } else if (target.hasClass('show-process-group-status-history')) {
-                    nf.StatusHistory.showStandaloneProcessGroupChart(item.groupId, item.id);
+                    nf.StatusHistory.showProcessGroupChart(item.groupId, item.id);
                 } else if (target.hasClass('show-cluster-process-group-summary')) {
                     // load the cluster processor summary
                     loadClusterProcessGroupSummary(item.id);
@@ -1151,7 +1127,7 @@ nf.SummaryTable = (function () {
                     goTo(item.groupId, item.id);
                 } else if (target.hasClass('show-cluster-input-port-summary')) {
                     // load the cluster processor summary
-                    loadClusterInputPortSummary(item.id);
+                    loadClusterInputPortSummary(item.groupId, item.id);
 
                     // hide the summary loading indicator
                     $('#summary-loading-container').hide();
@@ -1235,7 +1211,7 @@ nf.SummaryTable = (function () {
         
         // cluster input port refresh
         nf.Common.addHoverEffect('#cluster-input-port-refresh-button', 'button-refresh', 'button-refresh-hover').click(function () {
-            loadClusterInputPortSummary($('#cluster-input-port-id').text());
+            loadClusterInputPortSummary($('#cluster-input-port-group-id').text(), $('#cluster-input-port-id').text());
         });
 
         // initialize the cluster input port column model
@@ -1373,7 +1349,7 @@ nf.SummaryTable = (function () {
                     goTo(item.groupId, item.id);
                 } else if (target.hasClass('show-cluster-output-port-summary')) {
                     // load the cluster processor summary
-                    loadClusterOutputPortSummary(item.id);
+                    loadClusterOutputPortSummary(item.groupId, item.id);
 
                     // hide the summary loading indicator
                     $('#summary-loading-container').hide();
@@ -1457,7 +1433,7 @@ nf.SummaryTable = (function () {
         
         // cluster output port refresh
         nf.Common.addHoverEffect('#cluster-output-port-refresh-button', 'button-refresh', 'button-refresh-hover').click(function () {
-            loadClusterOutputPortSummary($('#cluster-output-port-id').text());
+            loadClusterOutputPortSummary($('#cluster-output-port-group-id').text(), $('#cluster-output-port-id').text());
         });
 
         // initialize the cluster output port column model
@@ -1563,11 +1539,7 @@ nf.SummaryTable = (function () {
                 }
 
                 if (nf.Common.SUPPORTS_SVG) {
-                    if (isClustered) {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-cluster-remote-process-group-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    } else {
-                        markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-remote-process-group-status-history" style="margin-top: 2px;"/>&nbsp;';
-                    }
+                    markup += '<img src="images/iconChart.png" title="Show History" class="pointer show-remote-process-group-status-history" style="margin-top: 2px;"/>&nbsp;';
                 }
 
                 if (isClustered) {
@@ -1631,13 +1603,11 @@ nf.SummaryTable = (function () {
             if (remoteProcessGroupsGrid.getColumns()[args.cell].id === 'actions') {
                 if (target.hasClass('go-to')) {
                     goTo(item.groupId, item.id);
-                } else if (target.hasClass('show-cluster-remote-process-group-status-history')) {
-                    nf.StatusHistory.showClusterRemoteProcessGroupChart(item.groupId, item.id);
                 } else if (target.hasClass('show-remote-process-group-status-history')) {
-                    nf.StatusHistory.showStandaloneRemoteProcessGroupChart(item.groupId, item.id);
+                    nf.StatusHistory.showRemoteProcessGroupChart(item.groupId, item.id);
                 } else if (target.hasClass('show-cluster-remote-process-group-summary')) {
                     // load the cluster processor summary
-                    loadClusterRemoteProcessGroupSummary(item.id);
+                    loadClusterRemoteProcessGroupSummary(item.groupId, item.id);
 
                     // hide the summary loading indicator
                     $('#summary-loading-container').hide();
@@ -1721,7 +1691,7 @@ nf.SummaryTable = (function () {
         
         // cluster remote process group refresh
         nf.Common.addHoverEffect('#cluster-remote-process-group-refresh-button', 'button-refresh', 'button-refresh-hover').click(function () {
-            loadClusterRemoteProcessGroupSummary($('#cluster-remote-process-group-id').text());
+            loadClusterRemoteProcessGroupSummary($('#cluster-remote-process-group-group-id').text(), $('#cluster-remote-process-group-id').text());
         });
 
         // initialize the cluster remote process group column model
@@ -1987,67 +1957,81 @@ nf.SummaryTable = (function () {
      * Refreshes the system diagnostics.
      */
     var refreshSystemDiagnostics = function () {
+        var systemDiagnosticsUri = config.urls.systemDiagnostics;
+
+        // add the parameter if appropriate
+        var parameters = {};
+        if (!nf.Common.isNull(clusterNodeId)) {
+            parameters['clusterNodeId'] = clusterNodeId;
+        }
+
+        // update the status uri if appropriate
+        if (!$.isEmptyObject(parameters)) {
+            systemDiagnosticsUri += '?' + $.param(parameters);
+        }
+
         return $.ajax({
             type: 'GET',
-            url: nf.SummaryTable.systemDiagnosticsUrl,
+            url: systemDiagnosticsUri,
             dataType: 'json'
         }).done(function (response) {
             var systemDiagnostics = response.systemDiagnostics;
+            var aggregateSnapshot = systemDiagnostics.aggregateSnapshot;
 
             // heap
-            $('#max-heap').text(systemDiagnostics.maxHeap);
-            $('#total-heap').text(systemDiagnostics.totalHeap);
-            $('#used-heap').text(systemDiagnostics.usedHeap);
-            $('#free-heap').text(systemDiagnostics.freeHeap);
+            $('#max-heap').text(aggregateSnapshot.maxHeap);
+            $('#total-heap').text(aggregateSnapshot.totalHeap);
+            $('#used-heap').text(aggregateSnapshot.usedHeap);
+            $('#free-heap').text(aggregateSnapshot.freeHeap);
 
             // ensure the heap utilization could be calculated
-            if (nf.Common.isDefinedAndNotNull(systemDiagnostics.heapUtilization)) {
-                $('#utilization-heap').text('(' + systemDiagnostics.heapUtilization + ')');
+            if (nf.Common.isDefinedAndNotNull(aggregateSnapshot.heapUtilization)) {
+                $('#utilization-heap').text('(' + aggregateSnapshot.heapUtilization + ')');
             } else {
                 $('#utilization-heap').text('');
             }
 
             // non heap
-            $('#max-non-heap').text(systemDiagnostics.maxNonHeap);
-            $('#total-non-heap').text(systemDiagnostics.totalNonHeap);
-            $('#used-non-heap').text(systemDiagnostics.usedNonHeap);
-            $('#free-non-heap').text(systemDiagnostics.freeNonHeap);
+            $('#max-non-heap').text(aggregateSnapshot.maxNonHeap);
+            $('#total-non-heap').text(aggregateSnapshot.totalNonHeap);
+            $('#used-non-heap').text(aggregateSnapshot.usedNonHeap);
+            $('#free-non-heap').text(aggregateSnapshot.freeNonHeap);
 
             // enure the non heap utilization could be calculated
-            if (nf.Common.isDefinedAndNotNull(systemDiagnostics.nonHeapUtilization)) {
-                $('#utilization-non-heap').text('(' + systemDiagnostics.nonHeapUtilization + ')');
+            if (nf.Common.isDefinedAndNotNull(aggregateSnapshot.nonHeapUtilization)) {
+                $('#utilization-non-heap').text('(' + aggregateSnapshot.nonHeapUtilization + ')');
             } else {
                 $('#utilization-non-heap').text('');
             }
 
             // garbage collection
             var garbageCollectionContainer = $('#garbage-collection-table tbody').empty();
-            $.each(systemDiagnostics.garbageCollection, function (_, garbageCollection) {
+            $.each(aggregateSnapshot.garbageCollection, function (_, garbageCollection) {
                 addGarbageCollection(garbageCollectionContainer, garbageCollection);
             });
 
             // available processors
-            $('#available-processors').text(systemDiagnostics.availableProcessors);
+            $('#available-processors').text(aggregateSnapshot.availableProcessors);
 
             // load
-            if (nf.Common.isDefinedAndNotNull(systemDiagnostics.processorLoadAverage)) {
-                $('#processor-load-average').text(nf.Common.formatFloat(systemDiagnostics.processorLoadAverage));
+            if (nf.Common.isDefinedAndNotNull(aggregateSnapshot.processorLoadAverage)) {
+                $('#processor-load-average').text(nf.Common.formatFloat(aggregateSnapshot.processorLoadAverage));
             } else {
-                $('#processor-load-average').html(nf.Common.formatValue(systemDiagnostics.processorLoadAverage));
+                $('#processor-load-average').html(nf.Common.formatValue(aggregateSnapshot.processorLoadAverage));
             }
 
             // database storage usage
             var flowFileRepositoryStorageUsageContainer = $('#flow-file-repository-storage-usage-container').empty();
-            addStorageUsage(flowFileRepositoryStorageUsageContainer, systemDiagnostics.flowFileRepositoryStorageUsage);
+            addStorageUsage(flowFileRepositoryStorageUsageContainer, aggregateSnapshot.flowFileRepositoryStorageUsage);
 
             // database storage usage
             var contentRepositoryUsageContainer = $('#content-repository-storage-usage-container').empty();
-            $.each(systemDiagnostics.contentRepositoryStorageUsage, function (_, contentRepository) {
+            $.each(aggregateSnapshot.contentRepositoryStorageUsage, function (_, contentRepository) {
                 addStorageUsage(contentRepositoryUsageContainer, contentRepository);
             });
 
             // update the stats last refreshed timestamp
-            $('#system-diagnostics-last-refreshed').text(systemDiagnostics.statsLastRefreshed);
+            $('#system-diagnostics-last-refreshed').text(aggregateSnapshot.statsLastRefreshed);
         }).fail(nf.Common.handleAjaxError);
     };
 
@@ -2106,39 +2090,39 @@ nf.SummaryTable = (function () {
      * @argument {array} inputPortItems                 The input port data
      * @argument {array} outputPortItems                The input port data
      * @argument {array} remoteProcessGroupItems        The remote process group data
-     * @argument {object} processGroupStatus            The process group status
+     * @argument {object} aggregateSnapshot            The process group status
      */
-    var populateProcessGroupStatus = function (processorItems, connectionItems, processGroupItems, inputPortItems, outputPortItems, remoteProcessGroupItems, processGroupStatus) {
+    var populateProcessGroupStatus = function (processorItems, connectionItems, processGroupItems, inputPortItems, outputPortItems, remoteProcessGroupItems, aggregateSnapshot) {
         // add the processors to the summary grid
-        $.each(processGroupStatus.processorStatus, function (i, procStatus) {
+        $.each(aggregateSnapshot.processorStatusSnapshots, function (i, procStatus) {
             processorItems.push(procStatus);
         });
 
         // add the processors to the summary grid
-        $.each(processGroupStatus.connectionStatus, function (i, connStatus) {
+        $.each(aggregateSnapshot.connectionStatusSnapshots, function (i, connStatus) {
             connectionItems.push(connStatus);
         });
 
         // add the input ports to the summary grid
-        $.each(processGroupStatus.inputPortStatus, function (i, portStatus) {
+        $.each(aggregateSnapshot.inputPortStatusSnapshots, function (i, portStatus) {
             inputPortItems.push(portStatus);
         });
 
         // add the input ports to the summary grid
-        $.each(processGroupStatus.outputPortStatus, function (i, portStatus) {
+        $.each(aggregateSnapshot.outputPortStatusSnapshots, function (i, portStatus) {
             outputPortItems.push(portStatus);
         });
 
         // add the input ports to the summary grid
-        $.each(processGroupStatus.remoteProcessGroupStatus, function (i, rpgStatus) {
+        $.each(aggregateSnapshot.remoteProcessGroupStatusSnapshots, function (i, rpgStatus) {
             remoteProcessGroupItems.push(rpgStatus);
         });
         
         // add the process group status as well
-        processGroupItems.push(processGroupStatus);
+        processGroupItems.push(aggregateSnapshot);
 
         // add any child group's status
-        $.each(processGroupStatus.processGroupStatus, function (i, childProcessGroup) {
+        $.each(aggregateSnapshot.processGroupStatusSnapshots, function (i, childProcessGroup) {
             populateProcessGroupStatus(processorItems, connectionItems, processGroupItems, inputPortItems, outputPortItems, remoteProcessGroupItems, childProcessGroup);
         });
     };
@@ -2169,21 +2153,22 @@ nf.SummaryTable = (function () {
 
     /**
      * Loads  the cluster processor details dialog for the specified processor.
-     * 
-     * @argument {string} rowId     The row id
+     *
+     * @argument {string} groupId         The group id
+     * @argument {string} processorId     The processor id
      */
-    var loadClusterProcessorSummary = function (rowId) {
+    var loadClusterProcessorSummary = function (groupId, processorId) {
         // get the summary
         $.ajax({
             type: 'GET',
-            url: config.urls.clusterProcessor + encodeURIComponent(rowId) + '/status',
+            url: config.urls.processGroups + encodeURIComponent(groupId) + '/processors/' + encodeURIComponent(processorId) + '/status',
             data: {
-                verbose: true
+                nodewise: true
             },
             dataType: 'json'
         }).done(function (response) {
-            if (nf.Common.isDefinedAndNotNull(response.clusterProcessorStatus)) {
-                var clusterProcessorStatus = response.clusterProcessorStatus;
+            if (nf.Common.isDefinedAndNotNull(response.processorStatus)) {
+                var processorStatus = response.processorStatus;
 
                 var clusterProcessorsGrid = $('#cluster-processor-summary-table').data('gridInstance');
                 var clusterProcessorsData = clusterProcessorsGrid.getData();
@@ -2191,18 +2176,19 @@ nf.SummaryTable = (function () {
                 var clusterProcessors = [];
 
                 // populate the table
-                $.each(clusterProcessorStatus.nodeProcessorStatus, function (i, nodeProcessorStatus) {
+                $.each(processorStatus.nodeSnapshots, function (i, nodeSnapshot) {
+                    var snapshot = nodeSnapshot.statusSnapshot;
                     clusterProcessors.push({
-                        id: nodeProcessorStatus.node.nodeId,
-                        node: nodeProcessorStatus.node.address + ':' + nodeProcessorStatus.node.apiPort,
-                        runStatus: nodeProcessorStatus.processorStatus.runStatus,
-                        activeThreadCount: nodeProcessorStatus.processorStatus.activeThreadCount,
-                        input: nodeProcessorStatus.processorStatus.input,
-                        read: nodeProcessorStatus.processorStatus.read,
-                        written: nodeProcessorStatus.processorStatus.written,
-                        output: nodeProcessorStatus.processorStatus.output,
-                        tasks: nodeProcessorStatus.processorStatus.tasks,
-                        tasksDuration: nodeProcessorStatus.processorStatus.tasksDuration
+                        id: nodeSnapshot.nodeId,
+                        node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
+                        runStatus: snapshot.runStatus,
+                        activeThreadCount: snapshot.activeThreadCount,
+                        input: snapshot.input,
+                        read: snapshot.read,
+                        written: snapshot.written,
+                        output: snapshot.output,
+                        tasks: snapshot.tasks,
+                        tasksDuration: snapshot.tasksDuration
                     });
                 });
 
@@ -2212,32 +2198,34 @@ nf.SummaryTable = (function () {
                 clusterProcessorsGrid.invalidate();
 
                 // populate the processor details
-                $('#cluster-processor-name').text(clusterProcessorStatus.processorName).ellipsis();
-                $('#cluster-processor-id').text(clusterProcessorStatus.processorId);
+                $('#cluster-processor-name').text(processorStatus.name).ellipsis();
+                $('#cluster-processor-id').text(processorStatus.id);
+                $('#cluster-processor-group-id').text(processorStatus.groupId);
 
                 // update the stats last refreshed timestamp
-                $('#cluster-processor-summary-last-refreshed').text(clusterProcessorStatus.statsLastRefreshed);
+                $('#cluster-processor-summary-last-refreshed').text(processorStatus.statsLastRefreshed);
             }
         }).fail(nf.Common.handleAjaxError);
     };
 
     /**
      * Loads the cluster connection details dialog for the specified processor.
-     * 
-     * @argument {string} rowId     The row id
+     *
+     * @argument {string} groupId   The group id
+     * @argument {string} connectionId     The connection id
      */
-    var loadClusterConnectionSummary = function (rowId) {
+    var loadClusterConnectionSummary = function (groupId, connectionId) {
         // get the summary
         $.ajax({
             type: 'GET',
-            url: config.urls.clusterConnection + encodeURIComponent(rowId) + '/status',
+            url: config.urls.processGroups + encodeURIComponent(groupId) + '/connections/' + encodeURIComponent(connectionId) + '/status',
             data: {
-                verbose: true
+                nodewise: true
             },
             dataType: 'json'
         }).done(function (response) {
-            if (nf.Common.isDefinedAndNotNull(response.clusterConnectionStatus)) {
-                var clusterConnectionStatus = response.clusterConnectionStatus;
+            if (nf.Common.isDefinedAndNotNull(response.connectionStatus)) {
+                var connectionStatus = response.connectionStatus;
 
                 var clusterConnectionsGrid = $('#cluster-connection-summary-table').data('gridInstance');
                 var clusterConnectionsData = clusterConnectionsGrid.getData();
@@ -2245,15 +2233,16 @@ nf.SummaryTable = (function () {
                 var clusterConnections = [];
 
                 // populate the table
-                $.each(clusterConnectionStatus.nodeConnectionStatus, function (i, nodeConnectionStatus) {
+                $.each(connectionStatus.nodeSnapshots, function (i, nodeSnapshot) {
+                    var snapshot = nodeSnapshot.statusSnapshot;
                     clusterConnections.push({
-                        id: nodeConnectionStatus.node.nodeId,
-                        node: nodeConnectionStatus.node.address + ':' + nodeConnectionStatus.node.apiPort,
-                        input: nodeConnectionStatus.connectionStatus.input,
-                        queued: nodeConnectionStatus.connectionStatus.queued,
-                        queuedCount: nodeConnectionStatus.connectionStatus.queuedCount,
-                        queuedSize: nodeConnectionStatus.connectionStatus.queuedSize,
-                        output: nodeConnectionStatus.connectionStatus.output
+                        id: nodeSnapshot.nodeId,
+                        node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
+                        input: snapshot.input,
+                        queued: snapshot.queued,
+                        queuedCount: snapshot.queuedCount,
+                        queuedSize: snapshot.queuedSize,
+                        output: snapshot.output
                     });
                 });
 
@@ -2263,11 +2252,12 @@ nf.SummaryTable = (function () {
                 clusterConnectionsGrid.invalidate();
 
                 // populate the processor details
-                $('#cluster-connection-name').text(clusterConnectionStatus.connectionName).ellipsis();
-                $('#cluster-connection-id').text(clusterConnectionStatus.connectionId);
+                $('#cluster-connection-name').text(connectionStatus.name).ellipsis();
+                $('#cluster-connection-id').text(connectionStatus.id);
+                $('#cluster-connection-group-id').text(connectionStatus.groupId);
 
                 // update the stats last refreshed timestamp
-                $('#cluster-connection-summary-last-refreshed').text(clusterConnectionStatus.statsLastRefreshed);
+                $('#cluster-connection-summary-last-refreshed').text(connectionStatus.statsLastRefreshed);
             }
         }).fail(nf.Common.handleAjaxError);
     };
@@ -2275,20 +2265,21 @@ nf.SummaryTable = (function () {
     /**
      * Loads the cluster input port details dialog for the specified processor.
      * 
-     * @argument {string} rowId     The row id
+     * @argument {string} processGroupId     The process group id
      */
-    var loadClusterProcessGroupSummary = function (rowId) {
+    var loadClusterProcessGroupSummary = function (processGroupId) {
         // get the summary
         $.ajax({
             type: 'GET',
-            url: config.urls.clusterProcessGroup + encodeURIComponent(rowId) + '/status',
+            url: config.urls.processGroups + encodeURIComponent(processGroupId) + '/status',
             data: {
-                verbose: true
+                nodewise: true,
+                recursive: false
             },
             dataType: 'json'
         }).done(function (response) {
-            if (nf.Common.isDefinedAndNotNull(response.clusterProcessGroupStatus)) {
-                var clusterProcessGroupStatus = response.clusterProcessGroupStatus;
+            if (nf.Common.isDefinedAndNotNull(response.processGroupStatus)) {
+                var processGroupStatus = response.processGroupStatus;
 
                 var clusterProcessGroupsGrid = $('#cluster-process-group-summary-table').data('gridInstance');
                 var clusterProcessGroupsData = clusterProcessGroupsGrid.getData();
@@ -2296,21 +2287,22 @@ nf.SummaryTable = (function () {
                 var clusterProcessGroups = [];
 
                 // populate the table
-                $.each(clusterProcessGroupStatus.nodeProcessGroupStatus, function (i, nodeProcessGroupStatus) {
+                $.each(processGroupStatus.nodeSnapshots, function (i, nodeSnapshot) {
+                    var snapshot = nodeSnapshot.statusSnapshot;
                     clusterProcessGroups.push({
-                        id: nodeProcessGroupStatus.node.nodeId,
-                        node: nodeProcessGroupStatus.node.address + ':' + nodeProcessGroupStatus.node.apiPort,
-                        activeThreadCount: nodeProcessGroupStatus.processGroupStatus.activeThreadCount,
-                        transferred: nodeProcessGroupStatus.processGroupStatus.transferred,
-                        input: nodeProcessGroupStatus.processGroupStatus.input,
-                        queued: nodeProcessGroupStatus.processGroupStatus.queued,
-                        queuedCount: nodeProcessGroupStatus.processGroupStatus.queuedCount,
-                        queuedSize: nodeProcessGroupStatus.processGroupStatus.queuedSize,
-                        output: nodeProcessGroupStatus.processGroupStatus.output,
-                        read: nodeProcessGroupStatus.processGroupStatus.read,
-                        written: nodeProcessGroupStatus.processGroupStatus.written,
-                        sent: nodeProcessGroupStatus.processGroupStatus.sent,
-                        received: nodeProcessGroupStatus.processGroupStatus.received
+                        id: nodeSnapshot.nodeId,
+                        node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
+                        activeThreadCount: snapshot.activeThreadCount,
+                        transferred: snapshot.transferred,
+                        input: snapshot.input,
+                        queued: snapshot.queued,
+                        queuedCount: snapshot.queuedCount,
+                        queuedSize: snapshot.queuedSize,
+                        output: snapshot.output,
+                        read: snapshot.read,
+                        written: snapshot.written,
+                        sent: snapshot.sent,
+                        received: snapshot.received
                     });
                 });
 
@@ -2320,32 +2312,33 @@ nf.SummaryTable = (function () {
                 clusterProcessGroupsGrid.invalidate();
 
                 // populate the input port details
-                $('#cluster-process-group-name').text(clusterProcessGroupStatus.processGroupName).ellipsis();
-                $('#cluster-process-group-id').text(clusterProcessGroupStatus.processGroupId);
+                $('#cluster-process-group-name').text(processGroupStatus.name).ellipsis();
+                $('#cluster-process-group-id').text(processGroupStatus.id);
 
                 // update the stats last refreshed timestamp
-                $('#cluster-process-group-summary-last-refreshed').text(clusterProcessGroupStatus.statsLastRefreshed);
+                $('#cluster-process-group-summary-last-refreshed').text(processGroupStatus.statsLastRefreshed);
             }
         }).fail(nf.Common.handleAjaxError);
     };
 
     /**
      * Loads the cluster input port details dialog for the specified processor.
-     * 
-     * @argument {string} rowId     The row id
+     *
+     * @argument {string} groupId         The group id
+     * @argument {string} inputPortId     The input port id
      */
-    var loadClusterInputPortSummary = function (rowId) {
+    var loadClusterInputPortSummary = function (groupId, inputPortId) {
         // get the summary
         $.ajax({
             type: 'GET',
-            url: config.urls.clusterInputPort + encodeURIComponent(rowId) + '/status',
+            url: config.urls.processGroups + encodeURIComponent(groupId) + '/input-ports/' + encodeURIComponent(inputPortId) + '/status',
             data: {
-                verbose: true
+                nodewise: true
             },
             dataType: 'json'
         }).done(function (response) {
-            if (nf.Common.isDefinedAndNotNull(response.clusterPortStatus)) {
-                var clusterInputPortStatus = response.clusterPortStatus;
+            if (nf.Common.isDefinedAndNotNull(response.portStatus)) {
+                var inputPortStatus = response.portStatus;
 
                 var clusterInputPortsGrid = $('#cluster-input-port-summary-table').data('gridInstance');
                 var clusterInputPortsData = clusterInputPortsGrid.getData();
@@ -2353,13 +2346,14 @@ nf.SummaryTable = (function () {
                 var clusterInputPorts = [];
 
                 // populate the table
-                $.each(clusterInputPortStatus.nodePortStatus, function (i, nodeInputPortStatus) {
+                $.each(inputPortStatus.nodeSnapshots, function (i, nodeSnapshot) {
+                    var snapshot = nodeSnapshot.statusSnapshot;
                     clusterInputPorts.push({
-                        id: nodeInputPortStatus.node.nodeId,
-                        node: nodeInputPortStatus.node.address + ':' + nodeInputPortStatus.node.apiPort,
-                        runStatus: nodeInputPortStatus.portStatus.runStatus,
-                        activeThreadCount: nodeInputPortStatus.portStatus.activeThreadCount,
-                        output: nodeInputPortStatus.portStatus.output
+                        id: nodeSnapshot.nodeId,
+                        node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
+                        runStatus: snapshot.runStatus,
+                        activeThreadCount: snapshot.activeThreadCount,
+                        output: snapshot.output
                     });
                 });
 
@@ -2369,32 +2363,34 @@ nf.SummaryTable = (function () {
                 clusterInputPortsGrid.invalidate();
 
                 // populate the input port details
-                $('#cluster-input-port-name').text(clusterInputPortStatus.portName).ellipsis();
-                $('#cluster-input-port-id').text(clusterInputPortStatus.portId);
+                $('#cluster-input-port-name').text(inputPortStatus.name).ellipsis();
+                $('#cluster-input-port-id').text(inputPortStatus.id);
+                $('#cluster-input-port-group-id').text(inputPortStatus.groupId);
 
                 // update the stats last refreshed timestamp
-                $('#cluster-input-port-summary-last-refreshed').text(clusterInputPortStatus.statsLastRefreshed);
+                $('#cluster-input-port-summary-last-refreshed').text(inputPortStatus.statsLastRefreshed);
             }
         }).fail(nf.Common.handleAjaxError);
     };
 
     /**
      * Loads the cluster output port details dialog for the specified processor.
-     * 
-     * @argument {string} rowId     The row id
+     *
+     * @argument {string} groupId          The group id
+     * @argument {string} outputPortId     The row id
      */
-    var loadClusterOutputPortSummary = function (rowId) {
+    var loadClusterOutputPortSummary = function (groupId, outputPortId) {
         // get the summary
         $.ajax({
             type: 'GET',
-            url: config.urls.clusterOutputPort + encodeURIComponent(rowId) + '/status',
+            url: config.urls.processGroups + encodeURIComponent(groupId) + '/output-ports/' + encodeURIComponent(outputPortId) + '/status',
             data: {
-                verbose: true
+                nodewise: true
             },
             dataType: 'json'
         }).done(function (response) {
-            if (nf.Common.isDefinedAndNotNull(response.clusterPortStatus)) {
-                var clusterOutputPortStatus = response.clusterPortStatus;
+            if (nf.Common.isDefinedAndNotNull(response.portStatus)) {
+                var outputPortStatus = response.portStatus;
 
                 var clusterOutputPortsGrid = $('#cluster-output-port-summary-table').data('gridInstance');
                 var clusterOutputPortsData = clusterOutputPortsGrid.getData();
@@ -2402,13 +2398,14 @@ nf.SummaryTable = (function () {
                 var clusterOutputPorts = [];
 
                 // populate the table
-                $.each(clusterOutputPortStatus.nodePortStatus, function (i, nodeOutputPortStatus) {
+                $.each(outputPortStatus.nodeSnapshots, function (i, nodeSnapshot) {
+                    var snapshot = nodeSnapshot.statusSnapshot;
                     clusterOutputPorts.push({
-                        id: nodeOutputPortStatus.node.nodeId,
-                        node: nodeOutputPortStatus.node.address + ':' + nodeOutputPortStatus.node.apiPort,
-                        runStatus: nodeOutputPortStatus.portStatus.runStatus,
-                        activeThreadCount: nodeOutputPortStatus.portStatus.activeThreadCount,
-                        input: nodeOutputPortStatus.portStatus.input
+                        id: nodeSnapshot.nodeId,
+                        node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
+                        runStatus: snapshot.runStatus,
+                        activeThreadCount: snapshot.activeThreadCount,
+                        input: snapshot.input
                     });
                 });
 
@@ -2418,32 +2415,34 @@ nf.SummaryTable = (function () {
                 clusterOutputPortsGrid.invalidate();
 
                 // populate the output port details
-                $('#cluster-output-port-name').text(clusterOutputPortStatus.portName).ellipsis();
-                $('#cluster-output-port-id').text(clusterOutputPortStatus.portId);
+                $('#cluster-output-port-name').text(outputPortStatus.name).ellipsis();
+                $('#cluster-output-port-id').text(outputPortStatus.id);
+                $('#cluster-output-port-group-id').text(outputPortStatus.groupId);
 
                 // update the stats last refreshed timestamp
-                $('#cluster-output-port-summary-last-refreshed').text(clusterOutputPortStatus.statsLastRefreshed);
+                $('#cluster-output-port-summary-last-refreshed').text(outputPortStatus.statsLastRefreshed);
             }
         }).fail(nf.Common.handleAjaxError);
     };
 
     /**
      * Loads the cluster remote process group details dialog for the specified processor.
-     * 
-     * @argument {string} rowId     The row id
+     *
+     * @argument {string} groupId   The group id
+     * @argument {string} remoteProcessGroupId     The remote process group id
      */
-    var loadClusterRemoteProcessGroupSummary = function (rowId) {
+    var loadClusterRemoteProcessGroupSummary = function (groupId, remoteProcessGroupId) {
         // get the summary
         $.ajax({
             type: 'GET',
-            url: config.urls.clusterRemoteProcessGroup + encodeURIComponent(rowId) + '/status',
+            url: config.urls.processGroups + encodeURIComponent(groupId) + '/remote-process-groups/' + encodeURIComponent(remoteProcessGroupId) + '/status',
             data: {
-                verbose: true
+                nodewise: true
             },
             dataType: 'json'
         }).done(function (response) {
-            if (nf.Common.isDefinedAndNotNull(response.clusterRemoteProcessGroupStatus)) {
-                var clusterRemoteProcessGroupStatus = response.clusterRemoteProcessGroupStatus;
+            if (nf.Common.isDefinedAndNotNull(response.remoteProcessGroupStatus)) {
+                var remoteProcessGroupStatus = response.remoteProcessGroupStatus;
 
                 var clusterRemoteProcessGroupsGrid = $('#cluster-remote-process-group-summary-table').data('gridInstance');
                 var clusterRemoteProcessGroupsData = clusterRemoteProcessGroupsGrid.getData();
@@ -2451,16 +2450,17 @@ nf.SummaryTable = (function () {
                 var clusterRemoteProcessGroups = [];
 
                 // populate the table
-                $.each(clusterRemoteProcessGroupStatus.nodeRemoteProcessGroupStatus, function (i, nodeRemoteProcessGroupStatus) {
+                $.each(remoteProcessGroupStatus.nodeSnapshots, function (i, nodeSnapshot) {
+                    var snapshot = nodeSnapshot.statusSnapshot;
                     clusterRemoteProcessGroups.push({
-                        id: nodeRemoteProcessGroupStatus.node.nodeId,
-                        node: nodeRemoteProcessGroupStatus.node.address + ':' + nodeRemoteProcessGroupStatus.node.apiPort,
-                        targetUri: nodeRemoteProcessGroupStatus.remoteProcessGroupStatus.targetUri,
-                        transmissionStatus: nodeRemoteProcessGroupStatus.remoteProcessGroupStatus.transmissionStatus,
-                        sent: nodeRemoteProcessGroupStatus.remoteProcessGroupStatus.sent,
-                        received: nodeRemoteProcessGroupStatus.remoteProcessGroupStatus.received,
-                        activeThreadCount: nodeRemoteProcessGroupStatus.remoteProcessGroupStatus.activeThreadCount,
-                        authorizationIssues: nodeRemoteProcessGroupStatus.remoteProcessGroupStatus.authorizationIssues
+                        id: nodeSnapshot.nodeId,
+                        node: nodeSnapshot.address + ':' + nodeSnapshot.apiPort,
+                        targetUri: snapshot.targetUri,
+                        transmissionStatus: snapshot.transmissionStatus,
+                        sent: snapshot.sent,
+                        received: snapshot.received,
+                        activeThreadCount: snapshot.activeThreadCount,
+                        authorizationIssues: snapshot.authorizationIssues
                     });
                 });
 
@@ -2470,37 +2470,26 @@ nf.SummaryTable = (function () {
                 clusterRemoteProcessGroupsGrid.invalidate();
 
                 // populate the remote process group details
-                $('#cluster-remote-process-group-name').text(clusterRemoteProcessGroupStatus.remoteProcessGroupName).ellipsis();
-                $('#cluster-remote-process-group-id').text(clusterRemoteProcessGroupStatus.remoteProcessGroupId);
+                $('#cluster-remote-process-group-name').text(remoteProcessGroupStatus.name).ellipsis();
+                $('#cluster-remote-process-group-id').text(remoteProcessGroupStatus.id);
+                $('#cluster-remote-process-group-group-id').text(remoteProcessGroupStatus.groupId);
 
                 // update the stats last refreshed timestamp
-                $('#cluster-remote-process-group-summary-last-refreshed').text(clusterRemoteProcessGroupStatus.statsLastRefreshed);
+                $('#cluster-remote-process-group-summary-last-refreshed').text(remoteProcessGroupStatus.statsLastRefreshed);
             }
         }).fail(nf.Common.handleAjaxError);
     };
 
+    var clusterNodeId = null;
+
     return {
         
         /**
-         * URL for loading system diagnostics.
-         */
-        systemDiagnosticsUrl: null,
-        
-        /**
-         * URL for loading the summary.
-         */
-        url: null,
-        
-        /**
          * Initializes the status table.
          * 
          * @argument {boolean} isClustered Whether or not this NiFi is clustered.
          */
         init: function (isClustered) {
-            // initialize the summary urls
-            nf.SummaryTable.url = config.urls.status;
-            nf.SummaryTable.systemDiagnosticsUrl = config.urls.systemDiagnostics;
-
             return $.Deferred(function (deferred) {
                 loadChartCapabilities().done(function () {
                     // initialize the processor/connection details dialog
@@ -2514,7 +2503,16 @@ nf.SummaryTable = (function () {
                 });
             }).promise();
         },
-        
+
+        /**
+         * Sets the cluster node id which will only show status from this node on subsequent reloads.
+         *
+         * @param nodeId
+         */
+        setClusterNodeId: function (nodeId) {
+            clusterNodeId = nodeId;
+        },
+
         /**
          * Update the size of the grid based on its container's current size.
          */
@@ -2551,20 +2549,34 @@ nf.SummaryTable = (function () {
         },
         
         /**
-         * Load the processor status table.
+         * Load the summary table.
          */
-        loadProcessorSummaryTable: function () {
+        loadSummaryTable: function () {
+            var statusUri = config.urls.status;
+
+            // add the parameter if appropriate
+            var parameters = {};
+            if (!nf.Common.isNull(clusterNodeId)) {
+                parameters['clusterNodeId'] = clusterNodeId;
+            }
+
+            // update the status uri if appropriate
+            if (!$.isEmptyObject(parameters)) {
+                statusUri += '?' + $.param(parameters);
+            }
+
             return $.ajax({
                 type: 'GET',
-                url: nf.SummaryTable.url,
+                url: statusUri,
                 data: {
                     recursive: true
                 },
                 dataType: 'json'
             }).done(function (response) {
                 var processGroupStatus = response.processGroupStatus;
+                var aggregateSnapshot = processGroupStatus.aggregateSnapshot;
 
-                if (nf.Common.isDefinedAndNotNull(processGroupStatus)) {
+                if (nf.Common.isDefinedAndNotNull(aggregateSnapshot)) {
                     // remove any tooltips from the processor table
                     var processorsGridElement = $('#processor-summary-table');
                     nf.Common.cleanUpTooltips(processorsGridElement, 'img.has-bulletins');
@@ -2617,7 +2629,7 @@ nf.SummaryTable = (function () {
                     var remoteProcessGroupItems = [];
 
                     // populate the tables
-                    populateProcessGroupStatus(processorItems, connectionItems, processGroupItems, inputPortItems, outputPortItems, remoteProcessGroupItems, processGroupStatus);
+                    populateProcessGroupStatus(processorItems, connectionItems, processGroupItems, inputPortItems, outputPortItems, remoteProcessGroupItems, aggregateSnapshot);
 
                     // update the processors
                     processorsData.setItems(processorItems);

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
index 4f06662..c16a670 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
@@ -70,7 +70,7 @@ nf.Summary = (function () {
     var initializeSummaryPage = function () {
         // define mouse over event for the refresh buttons
         nf.Common.addHoverEffect('#refresh-button', 'button-refresh', 'button-refresh-hover').click(function () {
-            nf.SummaryTable.loadProcessorSummaryTable();
+            nf.SummaryTable.loadSummaryTable();
         });
 
         // return a deferred for page initialization
@@ -133,7 +133,7 @@ nf.Summary = (function () {
             // intialize the summary table
             initializeSummaryTable().done(function () {
                 // load the table
-                nf.SummaryTable.loadProcessorSummaryTable().done(function () {
+                nf.SummaryTable.loadSummaryTable().done(function () {
                     // once the table is initialized, finish initializing the page
                     initializeSummaryPage().done(function () {
                         // configure the initial grid height


[05/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
index 60e8bcf..6c2165f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
@@ -163,6 +163,8 @@
     </bean>
     <bean id="bulletinBoardResource" class="org.apache.nifi.web.api.BulletinBoardResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>
+        <property name="properties" ref="nifiProperties"/>
+        <property name="clusterManager" ref="clusterManager"/>
     </bean>
     <bean id="templateResource" class="org.apache.nifi.web.api.TemplateResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>
@@ -252,6 +254,8 @@
     </bean>
     <bean id="systemDiagnosticsResource" class="org.apache.nifi.web.api.SystemDiagnosticsResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>
+        <property name="properties" ref="nifiProperties"/>
+        <property name="clusterManager" ref="clusterManager"/>
     </bean>
     <bean id="accessResource" class="org.apache.nifi.web.api.AccessResource" scope="singleton">
         <property name="properties" ref="nifiProperties"/>

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-connection-summary-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-connection-summary-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-connection-summary-dialog.jsp
index d374459..6091c92 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-connection-summary-dialog.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-connection-summary-dialog.jsp
@@ -28,6 +28,7 @@
                 <div id="cluster-connection-details">
                     <div id="cluster-connection-name"></div>
                     <div id="cluster-connection-id"></div>
+                    <div id="cluster-connection-group-id" class="hidden"></div>
                 </div>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-input-port-summary-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-input-port-summary-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-input-port-summary-dialog.jsp
index 6241c3a..d87de98 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-input-port-summary-dialog.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-input-port-summary-dialog.jsp
@@ -28,6 +28,7 @@
                 <div id="cluster-input-port-details">
                     <div id="cluster-input-port-name"></div>
                     <div id="cluster-input-port-id"></div>
+                    <div id="cluster-input-port-group-id" class="hidden"></div>
                 </div>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-output-port-summary-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-output-port-summary-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-output-port-summary-dialog.jsp
index ef0d4a8..a6e3a1c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-output-port-summary-dialog.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-output-port-summary-dialog.jsp
@@ -28,6 +28,7 @@
                 <div id="cluster-output-port-details">
                     <div id="cluster-output-port-name"></div>
                     <div id="cluster-output-port-id"></div>
+                    <div id="cluster-output-port-group-id" class="hidden"></div>
                 </div>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-processor-summary-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-processor-summary-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-processor-summary-dialog.jsp
index a25ac31..7444bf5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-processor-summary-dialog.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-processor-summary-dialog.jsp
@@ -28,6 +28,7 @@
                 <div id="cluster-processor-details">
                     <div id="cluster-processor-name"></div>
                     <div id="cluster-processor-id"></div>
+                    <div id="cluster-processor-group-id" class="hidden"></div>
                 </div>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-remote-process-group-summary-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-remote-process-group-summary-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-remote-process-group-summary-dialog.jsp
index 3cd6438..e27fe2c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-remote-process-group-summary-dialog.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/summary/cluster-remote-process-group-summary-dialog.jsp
@@ -28,6 +28,7 @@
                 <div id="cluster-remote-process-group-details">
                     <div id="cluster-remote-process-group-name"></div>
                     <div id="cluster-remote-process-group-id"></div>
+                    <div id="cluster-remote-process-group-group-id" class="hidden"></div>
                 </div>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
index c0e4e61..d92ebc2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
@@ -722,26 +722,14 @@ nf.Actions = (function () {
         showStats: function (selection) {
             if (selection.size() === 1) {
                 var selectionData = selection.datum();
-                if (nf.Canvas.isClustered()) {
-                    if (nf.CanvasUtils.isProcessor(selection)) {
-                        nf.StatusHistory.showClusterProcessorChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    } else if (nf.CanvasUtils.isProcessGroup(selection)) {
-                        nf.StatusHistory.showClusterProcessGroupChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    } else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
-                        nf.StatusHistory.showClusterRemoteProcessGroupChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    } else if (nf.CanvasUtils.isConnection(selection)) {
-                        nf.StatusHistory.showClusterConnectionChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    }
-                } else {
-                    if (nf.CanvasUtils.isProcessor(selection)) {
-                        nf.StatusHistory.showStandaloneProcessorChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    } else if (nf.CanvasUtils.isProcessGroup(selection)) {
-                        nf.StatusHistory.showStandaloneProcessGroupChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    } else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
-                        nf.StatusHistory.showStandaloneRemoteProcessGroupChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    } else if (nf.CanvasUtils.isConnection(selection)) {
-                        nf.StatusHistory.showStandaloneConnectionChart(nf.Canvas.getGroupId(), selectionData.component.id);
-                    }
+                if (nf.CanvasUtils.isProcessor(selection)) {
+                    nf.StatusHistory.showProcessorChart(nf.Canvas.getGroupId(), selectionData.component.id);
+                } else if (nf.CanvasUtils.isProcessGroup(selection)) {
+                    nf.StatusHistory.showProcessGroupChart(nf.Canvas.getGroupId(), selectionData.component.id);
+                } else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
+                    nf.StatusHistory.showRemoteProcessGroupChart(nf.Canvas.getGroupId(), selectionData.component.id);
+                } else if (nf.CanvasUtils.isConnection(selection)) {
+                    nf.StatusHistory.showConnectionChart(nf.Canvas.getGroupId(), selectionData.component.id);
                 }
             }
         },

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index cfeb4a5..abe9f97 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -845,9 +845,10 @@ nf.Canvas = (function () {
                 // report the updated stats
                 if (nf.Common.isDefinedAndNotNull(response.processGroupStatus)) {
                     var processGroupStatus = response.processGroupStatus;
+                    var aggregateSnapshot = processGroupStatus.aggregateSnapshot;
 
                     // update all the stats
-                    nf.Graph.setStatus(processGroupStatus);
+                    nf.Graph.setStatus(aggregateSnapshot);
 
                     // update the timestamp
                     $('#stats-last-refreshed').text(processGroupStatus.statsLastRefreshed);

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
index 99f978e..db720d0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
@@ -32,12 +32,12 @@ nf.Graph = (function () {
     };
 
     var combinePortStatus = function (status) {
-        if (nf.Common.isDefinedAndNotNull(status.inputPortStatus) && nf.Common.isDefinedAndNotNull(status.outputPortStatus)) {
-            return status.inputPortStatus.concat(status.outputPortStatus);
-        } else if (nf.Common.isDefinedAndNotNull(status.inputPortStatus)) {
-            return status.inputPortStatus;
-        } else if (nf.Common.isDefinedAndNotNull(status.outputPortStatus)) {
-            return status.outputPortStatus;
+        if (nf.Common.isDefinedAndNotNull(status.inputPortStatusSnapshots) && nf.Common.isDefinedAndNotNull(status.outputPortStatusSnapshots)) {
+            return status.inputPortStatusSnapshots.concat(status.outputPortStatusSnapshots);
+        } else if (nf.Common.isDefinedAndNotNull(status.inputPortStatusSnapshots)) {
+            return status.inputPortStatusSnapshots;
+        } else if (nf.Common.isDefinedAndNotNull(status.outputPortStatusSnapshots)) {
+            return status.outputPortStatusSnapshots;
         } else {
             return [];
         }
@@ -158,18 +158,18 @@ nf.Graph = (function () {
          * of the existing components on the graph and will not cause them to be repainted. 
          * This operation must be very inexpensive due to the frequency it is called.
          * 
-         * @argument {object} processGroupStatus    The status of the process group
+         * @argument {object} aggregateSnapshot    The status of the process group aggregated accross the cluster
          */
-        setStatus: function (processGroupStatus) {
+        setStatus: function (aggregateSnapshot) {
             // merge the port status together
-            var portStatus = combinePortStatus(processGroupStatus);
+            var portStatus = combinePortStatus(aggregateSnapshot);
 
             // set the component status
             nf.Port.setStatus(portStatus);
-            nf.RemoteProcessGroup.setStatus(processGroupStatus.remoteProcessGroupStatus);
-            nf.ProcessGroup.setStatus(processGroupStatus.processGroupStatus);
-            nf.Processor.setStatus(processGroupStatus.processorStatus);
-            nf.Connection.setStatus(processGroupStatus.connectionStatus);
+            nf.RemoteProcessGroup.setStatus(aggregateSnapshot.remoteProcessGroupStatusSnapshots);
+            nf.ProcessGroup.setStatus(aggregateSnapshot.processGroupStatusSnapshots);
+            nf.Processor.setStatus(aggregateSnapshot.processorStatusSnapshots);
+            nf.Connection.setStatus(aggregateSnapshot.connectionStatusSnapshots);
         },
         
         /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
index 5688118..c30c726 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/counters/nf-counters-table.js
@@ -281,22 +281,23 @@ nf.CountersTable = (function () {
                 dataType: 'json'
             }).done(function (response) {
                 var report = response.counters;
+                var aggregateSnapshot = report.aggregateSnapshot;
 
                 // ensure there are groups specified
-                if (nf.Common.isDefinedAndNotNull(report.counters)) {
+                if (nf.Common.isDefinedAndNotNull(aggregateSnapshot.counters)) {
                     var countersGrid = $('#counters-table').data('gridInstance');
                     var countersData = countersGrid.getData();
 
                     // set the items
-                    countersData.setItems(report.counters);
+                    countersData.setItems(aggregateSnapshot.counters);
                     countersData.reSort();
                     countersGrid.invalidate();
 
                     // update the stats last refreshed timestamp
-                    $('#counters-last-refreshed').text(report.generated);
+                    $('#counters-last-refreshed').text(aggregateSnapshot.generated);
 
                     // update the total number of processors
-                    $('#total-counters').text(report.counters.length);
+                    $('#total-counters').text(aggregateSnapshot.counters.length);
                 } else {
                     $('#total-counters').text('0');
                 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
index ac97726..57f91fb 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
@@ -19,8 +19,8 @@
 
 nf.StatusHistory = (function () {
     var config = {
-        clusterInstanceId: 'cluster-instance-id',
-        clusterInstanceLabel: 'Cluster',
+        nifiInstanceId: 'nifi-instance-id',
+        nifiInstanceLabel: 'NiFi',
         type: {
             processor: 'Processor',
             inputPort: 'Input Port',
@@ -33,11 +33,7 @@ nf.StatusHistory = (function () {
             label: 'Label'
         },
         urls: {
-            processGroups: '../nifi-api/controller/process-groups/',
-            clusterProcessor: '../nifi-api/cluster/processors/',
-            clusterProcessGroup: '../nifi-api/cluster/process-groups/',
-            clusterRemoteProcessGroup: '../nifi-api/cluster/remote-process-groups/',
-            clusterConnection: '../nifi-api/cluster/connections/'
+            processGroups: '../nifi-api/controller/process-groups/'
         }
     };
 
@@ -83,73 +79,51 @@ nf.StatusHistory = (function () {
     var instances = null;
 
     /**
-     * Handles the status history response from a clustered NiFi.
+     * Handles the status history response.
      * 
-     * @param {type} groupId
-     * @param {type} id
-     * @param {type} clusterStatusHistory
-     * @param {type} componentType
-     * @param {type} selectedDescriptor
+     * @param {string} groupId
+     * @param {string} id
+     * @param {object} componentStatusHistory
+     * @param {string} componentType
+     * @param {object} selectedDescriptor
      */
-    var handleClusteredStatusHistoryResponse = function (groupId, id, clusterStatusHistory, componentType, selectedDescriptor) {
+    var handleStatusHistoryResponse = function (groupId, id, componentStatusHistory, componentType, selectedDescriptor) {
         // update the last refreshed
-        $('#status-history-last-refreshed').text(clusterStatusHistory.generated);
+        $('#status-history-last-refreshed').text(componentStatusHistory.generated);
 
         // initialize the status history
         var statusHistory = {
             groupId: groupId,
             id: id,
             type: componentType,
-            clustered: true,
             instances: []
         };
 
-        var descriptors = null;
-
-        // get the status history for the entire cluster
-        var aggregateStatusHistory = clusterStatusHistory.clusterStatusHistory;
+        // get the descriptors
+        var descriptors = componentStatusHistory.fieldDescriptors;
+        statusHistory.details = componentStatusHistory.componentDetails;
+        statusHistory.selectedDescriptor = nf.Common.isUndefined(selectedDescriptor) ? descriptors[0] : selectedDescriptor;
 
         // ensure enough status snapshots
-        if (aggregateStatusHistory.statusSnapshots.length > 1) {
-            // only do these once
-            if (descriptors === null) {
-                // get the descriptors
-                descriptors = aggregateStatusHistory.fieldDescriptors;
-
-                statusHistory.details = aggregateStatusHistory.details;
-                statusHistory.selectedDescriptor = nf.Common.isUndefined(selectedDescriptor) ? descriptors[0] : selectedDescriptor;
-            }
-
-            // but ensure each instance is added
+        if (nf.Common.isDefinedAndNotNull(componentStatusHistory.aggregateSnapshots) && componentStatusHistory.aggregateSnapshots.length > 1) {
             statusHistory.instances.push({
-                id: config.clusterInstanceId,
-                label: config.clusterInstanceLabel,
-                snapshots: aggregateStatusHistory.statusSnapshots
+                id: config.nifiInstanceId,
+                label: config.nifiInstanceLabel,
+                snapshots: componentStatusHistory.aggregateSnapshots
             });
+        } else {
+        	insufficientHistory();
+        	return;
         }
 
-        // get the status for each node in the cluster
-        $.each(clusterStatusHistory.nodeStatusHistory, function (_, nodeStatusHistory) {
-            var node = nodeStatusHistory.node;
-            var statusHistoryForNode = nodeStatusHistory.statusHistory;
-
+        // get the status for each node in the cluster if applicable
+        $.each(componentStatusHistory.nodeSnapshots, function (_, nodeSnapshots) {
             // ensure enough status snapshots
-            if (statusHistoryForNode.statusSnapshots.length > 1) {
-
-                // only do these once
-                if (descriptors === null) {
-                    // get the descriptors
-                    descriptors = statusHistoryForNode.fieldDescriptors;
-
-                    statusHistory.details = statusHistoryForNode.details;
-                    statusHistory.selectedDescriptor = nf.Common.isUndefined(selectedDescriptor) ? descriptors[0] : selectedDescriptor;
-                }
-
-                // but ensure each instance is added
+            if (nf.Common.isDefinedAndNotNull(nodeSnapshots.statusSnapshots) && nodeSnapshots.statusSnapshots.length > 1) {
                 statusHistory.instances.push({
-                    id: node.nodeId,
-                    label: node.address + ':' + node.apiPort,
-                    snapshots: statusHistoryForNode.statusSnapshots
+                    id: nodeSnapshots.nodeId,
+                    label: nodeSnapshots.address + ':' + nodeSnapshots.apiPort,
+                    snapshots: nodeSnapshots.statusSnapshots
                 });
             }
         });
@@ -167,50 +141,6 @@ nf.StatusHistory = (function () {
     };
 
     /**
-     * Handles the status history response for a standalone NiFi.
-     * 
-     * @param {type} groupId
-     * @param {type} id
-     * @param {type} statusHistory
-     * @param {type} componentType
-     * @param {type} selectedDescriptor
-     */
-    var handleStandaloneStatusHistoryResponse = function (groupId, id, statusHistory, componentType, selectedDescriptor) {
-        // ensure there are sufficent snapshots
-        if (statusHistory.statusSnapshots.length > 1) {
-            // update the last refreshed
-            $('#status-history-last-refreshed').text(statusHistory.generated);
-
-            // detect the available fields
-            var descriptors = statusHistory.fieldDescriptors;
-
-            // build the status history
-            var statusHistory = {
-                groupId: groupId,
-                id: id,
-                details: statusHistory.details,
-                type: componentType,
-                clustered: false,
-                selectedDescriptor: nf.Common.isUndefined(selectedDescriptor) ? descriptors[0] : selectedDescriptor,
-                instances: [{
-                        id: '',
-                        label: '',
-                        snapshots: statusHistory.statusSnapshots
-                    }]
-            };
-
-            // store the status history
-            $('#status-history-dialog').data('status-history', statusHistory);
-
-            // chart the status history
-            chart(statusHistory, descriptors);
-            return;
-        }
-
-        insufficientHistory();
-    };
-
-    /**
      * Shows an error message stating there is insufficient history available.
      */
     var insufficientHistory = function () {
@@ -785,127 +715,107 @@ nf.StatusHistory = (function () {
                 });
             });
 
-            if (statusHistory.clustered) {
-                // consider visible nodes with data in the brush
-                var nodes = $.grep(withinBrush, function (d) {
-                    return d.id !== config.clusterInstanceId && d.visible && d.values.length > 0;
-                });
-
-                var nodeMinValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(nodes));
-                var nodeMeanValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(nodes));
-                var nodeMaxValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(nodes));
-
-                // update the currently displayed min/max/mean
-                $('#node-aggregate-statistics').text(nodeMinValue + ' / ' + nodeMaxValue + ' / ' + nodeMeanValue);
+            // consider visible nodes with data in the brush
+            var nodes = $.grep(withinBrush, function (d) {
+                return d.id !== config.nifiInstanceId && d.visible && d.values.length > 0;
+            });
 
-                // only consider the cluster with data in the brush
-                var cluster = $.grep(withinBrush, function (d) {
-                    return d.id === config.clusterInstanceId && d.visible && d.values.length > 0;
-                });
+            var nodeMinValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(nodes));
+            var nodeMeanValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(nodes));
+            var nodeMaxValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(nodes));
 
-                // determine the cluster values
-                var clusterMinValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(cluster));
-                var clusterMeanValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(cluster));
-                var clusterMaxValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(cluster));
+            // update the currently displayed min/max/mean
+            $('#node-aggregate-statistics').text(nodeMinValue + ' / ' + nodeMaxValue + ' / ' + nodeMeanValue);
 
-                // update the cluster min/max/mean
-                $('#cluster-aggregate-statistics').text(clusterMinValue + ' / ' + clusterMaxValue + ' / ' + clusterMeanValue);
-            } else {
-                // only consider data in the brush
-                var instance = $.grep(withinBrush, function (d) {
-                    return d.values.length > 0;
-                });
+            // only consider the cluster with data in the brush
+            var cluster = $.grep(withinBrush, function (d) {
+                return d.id === config.nifiInstanceId && d.visible && d.values.length > 0;
+            });
 
-                // determine the min, max, mean
-                var instanceMinValue = instance.length === 0 ? 0 : formatters[selectedDescriptor.formatter](getMinValue(instance));
-                var instanceMeanValue = instance.length === 0 ? 0 : formatters[selectedDescriptor.formatter](getMeanValue(instance));
-                var instanceMaxValue = instance.length === 0 ? 0 : formatters[selectedDescriptor.formatter](getMaxValue(instance));
+            // determine the cluster values
+            var clusterMinValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(cluster));
+            var clusterMeanValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(cluster));
+            var clusterMaxValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(cluster));
 
-                // update the instance min/max/mean
-                $('#instance-aggregate-statistics').text(instanceMinValue + ' / ' + instanceMaxValue + ' / ' + instanceMeanValue);
-            }
+            // update the cluster min/max/mean
+            $('#cluster-aggregate-statistics').text(clusterMinValue + ' / ' + clusterMaxValue + ' / ' + clusterMeanValue);
         };
 
         // ----------------
         // build the legend
         // ----------------
 
-        if (statusHistory.clustered) {
-            // identify all nodes and sort
-            var nodes = $.grep(statusData, function (status) {
-                return status.id !== config.clusterInstanceId;
-            }).sort(function (a, b) {
-                return a.label < b.label ? -1 : a.label > b.label ? 1 : 0;
-            });
-
-            // adds a legend entry for the specified instance
-            var addLegendEntry = function (legend, instance) {
-                // create the label and the checkbox
-                var instanceLabelElement = $('<div></div>').addClass('legend-label').css('color', color(instance.label)).text(instance.label).ellipsis();
-                var instanceCheckboxElement = $('<div class="nf-checkbox"></div>').on('click', function () {
-                    // get the line and the control points for this instance (select all for the line to update control and main charts)
-                    var chartLine = d3.selectAll('path.chart-line-' + instance.id);
-                    var markGroup = d3.select('g.mark-group-' + instance.id);
-
-                    // determine if it was hidden
-                    var isHidden = markGroup.classed('hidden');
-
-                    // toggle the visibility
-                    chartLine.classed('hidden', function () {
-                        return !isHidden;
-                    });
-                    markGroup.classed('hidden', function () {
-                        return !isHidden;
-                    });
-
-                    // update whether its visible
-                    instance.visible = isHidden;
+        // identify all nodes and sort
+        var nodes = $.grep(statusData, function (status) {
+            return status.id !== config.nifiInstanceId;
+        }).sort(function (a, b) {
+            return a.label < b.label ? -1 : a.label > b.label ? 1 : 0;
+        });
 
-                    // record the current status so it persists across refreshes
-                    instances[instance.id] = instance.visible;
+        // adds a legend entry for the specified instance
+        var addLegendEntry = function (legend, instance) {
+            // create the label and the checkbox
+            var instanceLabelElement = $('<div></div>').addClass('legend-label').css('color', color(instance.label)).text(instance.label).ellipsis();
+            var instanceCheckboxElement = $('<div class="nf-checkbox"></div>').on('click', function () {
+                // get the line and the control points for this instance (select all for the line to update control and main charts)
+                var chartLine = d3.selectAll('path.chart-line-' + instance.id);
+                var markGroup = d3.select('g.mark-group-' + instance.id);
+
+                // determine if it was hidden
+                var isHidden = markGroup.classed('hidden');
+
+                // toggle the visibility
+                chartLine.classed('hidden', function () {
+                    return !isHidden;
+                });
+                markGroup.classed('hidden', function () {
+                    return !isHidden;
+                });
 
-                    // update the brush
-                    brushed();
-                }).addClass(instance.visible ? 'checkbox-checked' : 'checkbox-unchecked');
+                // update whether its visible
+                instance.visible = isHidden;
 
-                // add the legend entry
-                $('<div class="legend-entry"></div>').append(instanceCheckboxElement).append(instanceLabelElement).on('mouseenter', function () {
-                    d3.selectAll('path.chart-line-' + instance.id).classed('over', true);
-                }).on('mouseleave', function () {
-                    d3.selectAll('path.chart-line-' + instance.id).classed('over', false);
-                }).appendTo(legend);
-            };
+                // record the current status so it persists across refreshes
+                instances[instance.id] = instance.visible;
 
-            // get the cluster instance
-            var cluster = $.grep(statusData, function (status) {
-                return status.id === config.clusterInstanceId;
-            });
+                // update the brush
+                brushed();
+            }).addClass(instance.visible ? 'checkbox-checked' : 'checkbox-unchecked');
+
+            // add the legend entry
+            $('<div class="legend-entry"></div>').append(instanceCheckboxElement).append(instanceLabelElement).on('mouseenter', function () {
+                d3.selectAll('path.chart-line-' + instance.id).classed('over', true);
+            }).on('mouseleave', function () {
+                d3.selectAll('path.chart-line-' + instance.id).classed('over', false);
+            }).appendTo(legend);
+        };
 
-            // build the cluster container
-            var clusterDetailsContainer = buildDetailsContainer('Cluster');
+        // get the cluster instance
+        var cluster = $.grep(statusData, function (status) {
+            return status.id === config.nifiInstanceId;
+        });
 
-            // add the total cluster values
-            addDetailItem(clusterDetailsContainer, 'Min / Max / Mean', '', 'cluster-aggregate-statistics');
+        // build the cluster container
+        var clusterDetailsContainer = buildDetailsContainer('NiFi');
 
-            // build the cluster legend
-            addLegendEntry(clusterDetailsContainer, cluster[0]);
+        // add the total cluster values
+        addDetailItem(clusterDetailsContainer, 'Min / Max / Mean', '', 'cluster-aggregate-statistics');
 
-            // if there are entries to render
-            if (nodes.length > 0) {
-                // build the cluster container
-                var nodeDetailsContainer = buildDetailsContainer('Nodes');
+        // build the cluster legend
+        addLegendEntry(clusterDetailsContainer, cluster[0]);
 
-                // add the total cluster values
-                addDetailItem(nodeDetailsContainer, 'Min / Max / Mean', '', 'node-aggregate-statistics');
+        // if there are entries to render
+        if (nodes.length > 0) {
+            // build the cluster container
+            var nodeDetailsContainer = buildDetailsContainer('Nodes');
 
-                // add each legend entry
-                $.each(nodes, function (_, instance) {
-                    addLegendEntry(nodeDetailsContainer, instance);
-                });
-            }
-        } else {
             // add the total cluster values
-            addDetailItem(detailsContainer, 'Min / Max / Mean', '', 'instance-aggregate-statistics');
+            addDetailItem(nodeDetailsContainer, 'Min / Max / Mean', '', 'node-aggregate-statistics');
+
+            // add each legend entry
+            $.each(nodes, function (_, instance) {
+                addLegendEntry(nodeDetailsContainer, instance);
+            });
         }
 
         // update the brush
@@ -1135,29 +1045,13 @@ nf.StatusHistory = (function () {
                 var statusHistory = $('#status-history-dialog').data('status-history');
                 if (statusHistory !== null) {
                     if (statusHistory.type === config.type.processor) {
-                        if (statusHistory.clustered === true) {
-                            nf.StatusHistory.showClusterProcessorChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        } else {
-                            nf.StatusHistory.showStandaloneProcessorChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        }
+                        nf.StatusHistory.showProcessorChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
                     } else if (statusHistory.type === config.type.processGroup) {
-                        if (statusHistory.clustered === true) {
-                            nf.StatusHistory.showClusterProcessGroupChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        } else {
-                            nf.StatusHistory.showStandaloneProcessGroupChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        }
+                        nf.StatusHistory.showProcessGroupChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
                     } else if (statusHistory.type === config.type.remoteProcessGroup) {
-                        if (statusHistory.clustered === true) {
-                            nf.StatusHistory.showClusterRemoteProcessGroupChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        } else {
-                            nf.StatusHistory.showStandaloneRemoteProcessGroupChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        }
+                        nf.StatusHistory.showRemoteProcessGroupChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
                     } else {
-                        if (statusHistory.clustered === true) {
-                            nf.StatusHistory.showClusterConnectionChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        } else {
-                            nf.StatusHistory.showStandaloneConnectionChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
-                        }
+                        nf.StatusHistory.showConnectionChart(statusHistory.groupId, statusHistory.id, statusHistory.selectedDescriptor);
                     }
                 }
             });
@@ -1196,87 +1090,19 @@ nf.StatusHistory = (function () {
         },
         
         /**
-         * Shows the status history for the specified connection across the cluster.
-         * 
-         * @param {type} groupId 
-         * @param {type} connectionId
-         * @param {type} selectedDescriptor
-         */
-        showClusterConnectionChart: function (groupId, connectionId, selectedDescriptor) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.clusterConnection + encodeURIComponent(connectionId) + '/status/history',
-                dataType: 'json'
-            }).done(function (response) {
-                handleClusteredStatusHistoryResponse(groupId, connectionId, response.clusterStatusHistory, config.type.connection, selectedDescriptor);
-            }).fail(nf.Common.handleAjaxError);
-        },
-        
-        /**
-         * Shows the status history for the specified processor across the cluster.
-         * 
-         * @param {type} groupId
-         * @param {type} processorId
-         * @param {type} selectedDescriptor
-         */
-        showClusterProcessorChart: function (groupId, processorId, selectedDescriptor) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.clusterProcessor + encodeURIComponent(processorId) + '/status/history',
-                dataType: 'json'
-            }).done(function (response) {
-                handleClusteredStatusHistoryResponse(groupId, processorId, response.clusterStatusHistory, config.type.processor, selectedDescriptor);
-            }).fail(nf.Common.handleAjaxError);
-        },
-        
-        /**
-         * Shows the status history for the specified process group across the cluster.
-         * 
-         * @param {type} groupId
-         * @param {type} processGroupId
-         * @param {type} selectedDescriptor
-         */
-        showClusterProcessGroupChart: function (groupId, processGroupId, selectedDescriptor) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.clusterProcessGroup + encodeURIComponent(processGroupId) + '/status/history',
-                dataType: 'json'
-            }).done(function (response) {
-                handleClusteredStatusHistoryResponse(groupId, processGroupId, response.clusterStatusHistory, config.type.processGroup, selectedDescriptor);
-            }).fail(nf.Common.handleAjaxError);
-        },
-        
-        /**
-         * Shows the status history for the specified remote process group across the cluster.
-         * 
-         * @param {type} groupId
-         * @param {type} remoteProcessGroupId
-         * @param {type} selectedDescriptor
-         */
-        showClusterRemoteProcessGroupChart: function (groupId, remoteProcessGroupId, selectedDescriptor) {
-            $.ajax({
-                type: 'GET',
-                url: config.urls.clusterRemoteProcessGroup + encodeURIComponent(remoteProcessGroupId) + '/status/history',
-                dataType: 'json'
-            }).done(function (response) {
-                handleClusteredStatusHistoryResponse(groupId, remoteProcessGroupId, response.clusterStatusHistory, config.type.remoteProcessGroup, selectedDescriptor);
-            }).fail(nf.Common.handleAjaxError);
-        },
-        
-        /**
          * Shows the status history for the specified connection in this instance.
          * 
          * @param {type} groupId
          * @param {type} connectionId
          * @param {type} selectedDescriptor
          */
-        showStandaloneConnectionChart: function (groupId, connectionId, selectedDescriptor) {
+        showConnectionChart: function (groupId, connectionId, selectedDescriptor) {
             $.ajax({
                 type: 'GET',
                 url: config.urls.processGroups + encodeURIComponent(groupId) + '/connections/' + encodeURIComponent(connectionId) + '/status/history',
                 dataType: 'json'
             }).done(function (response) {
-                handleStandaloneStatusHistoryResponse(groupId, connectionId, response.statusHistory, config.type.connection, selectedDescriptor);
+                handleStatusHistoryResponse(groupId, connectionId, response.statusHistory, config.type.connection, selectedDescriptor);
             }).fail(nf.Common.handleAjaxError);
         },
         
@@ -1287,13 +1113,13 @@ nf.StatusHistory = (function () {
          * @param {type} processorId
          * @param {type} selectedDescriptor
          */
-        showStandaloneProcessorChart: function (groupId, processorId, selectedDescriptor) {
+        showProcessorChart: function (groupId, processorId, selectedDescriptor) {
             $.ajax({
                 type: 'GET',
                 url: config.urls.processGroups + encodeURIComponent(groupId) + '/processors/' + encodeURIComponent(processorId) + '/status/history',
                 dataType: 'json'
             }).done(function (response) {
-                handleStandaloneStatusHistoryResponse(groupId, processorId, response.statusHistory, config.type.processor, selectedDescriptor);
+                handleStatusHistoryResponse(groupId, processorId, response.statusHistory, config.type.processor, selectedDescriptor);
             }).fail(nf.Common.handleAjaxError);
         },
         
@@ -1304,13 +1130,13 @@ nf.StatusHistory = (function () {
          * @param {type} processGroupId
          * @param {type} selectedDescriptor
          */
-        showStandaloneProcessGroupChart: function (groupId, processGroupId, selectedDescriptor) {
+        showProcessGroupChart: function (groupId, processGroupId, selectedDescriptor) {
             $.ajax({
                 type: 'GET',
                 url: config.urls.processGroups + encodeURIComponent(processGroupId) + '/status/history',
                 dataType: 'json'
             }).done(function (response) {
-                handleStandaloneStatusHistoryResponse(groupId, processGroupId, response.statusHistory, config.type.processGroup, selectedDescriptor);
+                handleStatusHistoryResponse(groupId, processGroupId, response.statusHistory, config.type.processGroup, selectedDescriptor);
             }).fail(nf.Common.handleAjaxError);
         },
         
@@ -1321,13 +1147,13 @@ nf.StatusHistory = (function () {
          * @param {type} remoteProcessGroupId
          * @param {type} selectedDescriptor
          */
-        showStandaloneRemoteProcessGroupChart: function (groupId, remoteProcessGroupId, selectedDescriptor) {
+        showRemoteProcessGroupChart: function (groupId, remoteProcessGroupId, selectedDescriptor) {
             $.ajax({
                 type: 'GET',
                 url: config.urls.processGroups + encodeURIComponent(groupId) + '/remote-process-groups/' + encodeURIComponent(remoteProcessGroupId) + '/status/history',
                 dataType: 'json'
             }).done(function (response) {
-                handleStandaloneStatusHistoryResponse(groupId, remoteProcessGroupId, response.statusHistory, config.type.remoteProcessGroup, selectedDescriptor);
+                handleStatusHistoryResponse(groupId, remoteProcessGroupId, response.statusHistory, config.type.remoteProcessGroup, selectedDescriptor);
             }).fail(nf.Common.handleAjaxError);
         }
     };

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-cluster-search.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-cluster-search.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-cluster-search.js
index 2254943..9bab660 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-cluster-search.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-cluster-search.js
@@ -68,11 +68,10 @@ nf.ClusterSearch = (function () {
                                         var node = searchResults[0];
 
                                         // update the urls to point to this specific node of the cluster
-                                        nf.SummaryTable.url = '../nifi-api/cluster/nodes/' + encodeURIComponent(node.id) + '/status';
-                                        nf.SummaryTable.systemDiagnosticsUrl = '../nifi-api/cluster/nodes/' + encodeURIComponent(node.id) + '/system-diagnostics';
+                                        nf.SummaryTable.setClusterNodeId(node.id);
 
                                         // load the summary for the selected node
-                                        nf.SummaryTable.loadProcessorSummaryTable();
+                                        nf.SummaryTable.loadSummaryTable();
 
                                         // update the header
                                         $('#summary-header-text').text(node.address + ' Summary');
@@ -168,9 +167,8 @@ nf.ClusterSearch = (function () {
             // handle the view cluster click event
             $('#view-cluster-link').click(function () {
                 // reset the urls and refresh the table
-                nf.SummaryTable.url = config.urls.status;
-                nf.SummaryTable.systemDiagnosticsUrl = config.urls.systemDiagnostics;
-                nf.SummaryTable.loadProcessorSummaryTable();
+                nf.SummaryTable.setClusterNodeId(null);
+                nf.SummaryTable.loadSummaryTable();
 
                 // update the header
                 $('#summary-header-text').text('NiFi Summary');


[09/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java
index 02f7d6b..36288d5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java
@@ -20,19 +20,16 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
-import java.util.concurrent.TimeUnit;
 
 import org.apache.nifi.controller.status.ConnectionStatus;
 import org.apache.nifi.controller.status.ProcessGroupStatus;
 import org.apache.nifi.controller.status.ProcessorStatus;
 import org.apache.nifi.controller.status.RemoteProcessGroupStatus;
-import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter;
 import org.apache.nifi.util.ComponentStatusReport;
-import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.util.ComponentStatusReport.ComponentType;
+import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.util.RingBuffer;
 import org.apache.nifi.util.RingBuffer.ForEachEvaluator;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -233,22 +230,9 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit
         return history;
     }
 
-    private static long calculateTaskMillis(final ProcessGroupStatus status) {
-        long nanos = 0L;
 
-        for (final ProcessorStatus procStatus : status.getProcessorStatus()) {
-            nanos += procStatus.getProcessingNanos();
-        }
-
-        for (final ProcessGroupStatus childStatus : status.getProcessGroupStatus()) {
-            nanos += calculateTaskMillis(childStatus);
-        }
-
-        return TimeUnit.MILLISECONDS.convert(nanos, TimeUnit.NANOSECONDS);
-    }
 
     private static class Capture {
-
         private final Date captureDate;
         private final ComponentStatusReport statusReport;
 
@@ -266,407 +250,7 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit
         }
     }
 
-    public static enum RemoteProcessGroupStatusDescriptor {
-
-        SENT_BYTES(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentBytes", "Bytes Sent (5 mins)",
-                "The cumulative size of all FlowFiles that have been successfully sent to the remote system in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return status.getSentContentSize();
-                    }
-                })),
-        SENT_COUNT(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentCount", "FlowFiles Sent (5 mins)",
-                "The number of FlowFiles that have been successfully sent to the remote system in the past 5 minutes", Formatter.COUNT, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return Long.valueOf(status.getSentCount().longValue());
-                    }
-                })),
-        RECEIVED_BYTES(new StandardMetricDescriptor<RemoteProcessGroupStatus>("receivedBytes", "Bytes Received (5 mins)",
-                "The cumulative size of all FlowFiles that have been received from the remote system in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return status.getReceivedContentSize();
-                    }
-                })),
-        RECEIVED_COUNT(new StandardMetricDescriptor<RemoteProcessGroupStatus>("receivedCount", "FlowFiles Received (5 mins)",
-                "The number of FlowFiles that have been received from the remote system in the past 5 minutes", Formatter.COUNT, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return Long.valueOf(status.getReceivedCount().longValue());
-                    }
-                })),
-        RECEIVED_BYTES_PER_SECOND(new StandardMetricDescriptor<RemoteProcessGroupStatus>("receivedBytesPerSecond", "Received Bytes Per Second",
-                "The data rate at which data was received from the remote system in the past 5 minutes in terms of Bytes Per Second",
-                Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return Long.valueOf(status.getReceivedContentSize().longValue() / 300L);
-                    }
-                })),
-        SENT_BYTES_PER_SECOND(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentBytesPerSecond", "Sent Bytes Per Second",
-                "The data rate at which data was received from the remote system in the past 5 minutes in terms of Bytes Per Second", Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return Long.valueOf(status.getSentContentSize().longValue() / 300L);
-                    }
-                })),
-        TOTAL_BYTES_PER_SECOND(new StandardMetricDescriptor<RemoteProcessGroupStatus>("totalBytesPerSecond", "Total Bytes Per Second",
-                "The sum of the send and receive data rate from the remote system in the past 5 minutes in terms of Bytes Per Second",
-                Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return Long.valueOf((status.getReceivedContentSize().longValue() + status.getSentContentSize().longValue()) / 300L);
-                    }
-                })),
-        AVERAGE_LINEAGE_DURATION(new StandardMetricDescriptor<RemoteProcessGroupStatus>(
-                "averageLineageDuration",
-                "Average Lineage Duration (5 mins)",
-                "The average amount of time that a FlowFile took to process from receipt to drop in the past 5 minutes. For Processors that do not terminate FlowFiles, this value will be 0.",
-                Formatter.DURATION,
-                new ValueMapper<RemoteProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final RemoteProcessGroupStatus status) {
-                        return status.getAverageLineageDuration(TimeUnit.MILLISECONDS);
-                    }
-                }, new ValueReducer<StatusSnapshot, Long>() {
-                    @Override
-                    public Long reduce(final List<StatusSnapshot> values) {
-                        long millis = 0L;
-                        int count = 0;
-
-                        for (final StatusSnapshot snapshot : values) {
-                            final long sent = snapshot.getStatusMetrics().get(SENT_COUNT.getDescriptor()).longValue();
-                            count += sent;
-
-                            final long avgMillis = snapshot.getStatusMetrics().get(AVERAGE_LINEAGE_DURATION.getDescriptor()).longValue();
-                            final long totalMillis = avgMillis * sent;
-                            millis += totalMillis;
-                        }
-
-                        return count == 0 ? 0 : millis / count;
-                    }
-                }
-        ));
-
-        private final MetricDescriptor<RemoteProcessGroupStatus> descriptor;
-
-        private RemoteProcessGroupStatusDescriptor(final MetricDescriptor<RemoteProcessGroupStatus> descriptor) {
-            this.descriptor = descriptor;
-        }
-
-        public String getField() {
-            return descriptor.getField();
-        }
-
-        public MetricDescriptor<RemoteProcessGroupStatus> getDescriptor() {
-            return descriptor;
-        }
-    }
-
-    public static enum ProcessGroupStatusDescriptor {
-
-        BYTES_READ(new StandardMetricDescriptor<ProcessGroupStatus>("bytesRead", "Bytes Read (5 mins)",
-                "The total number of bytes read from Content Repository by Processors in this Process Group in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getBytesRead();
-                    }
-                })),
-        BYTES_WRITTEN(new StandardMetricDescriptor<ProcessGroupStatus>("bytesWritten", "Bytes Written (5 mins)",
-                "The total number of bytes written to Content Repository by Processors in this Process Group in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getBytesWritten();
-                    }
-                })),
-        BYTES_TRANSFERRED(new StandardMetricDescriptor<ProcessGroupStatus>("bytesTransferred", "Bytes Transferred (5 mins)",
-                "The total number of bytes read from or written to Content Repository by Processors in this Process Group in the past 5 minutes",
-                Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getBytesRead() + status.getBytesWritten();
-                    }
-                })),
-        INPUT_BYTES(new StandardMetricDescriptor<ProcessGroupStatus>("inputBytes", "Bytes In (5 mins)",
-                "The cumulative size of all FlowFiles that have entered this Process Group via its Input Ports in the past 5 minutes",
-                Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getInputContentSize();
-                    }
-                })),
-        INPUT_COUNT(new StandardMetricDescriptor<ProcessGroupStatus>("inputCount", "FlowFiles In (5 mins)",
-                "The number of FlowFiles that have entered this Process Group via its Input Ports in the past 5 minutes",
-                Formatter.COUNT, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getInputCount().longValue();
-                    }
-                })),
-        OUTPUT_BYTES(new StandardMetricDescriptor<ProcessGroupStatus>("outputBytes", "Bytes Out (5 mins)",
-                "The cumulative size of all FlowFiles that have exited this Process Group via its Output Ports in the past 5 minutes",
-                Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getOutputContentSize();
-                    }
-                })),
-        OUTPUT_COUNT(new StandardMetricDescriptor<ProcessGroupStatus>("outputCount", "FlowFiles Out (5 mins)",
-                "The number of FlowFiles that have exited this Process Group via its Output Ports in the past 5 minutes",
-                Formatter.COUNT, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getOutputCount().longValue();
-                    }
-                })),
-        QUEUED_BYTES(new StandardMetricDescriptor<ProcessGroupStatus>("queuedBytes", "Queued Bytes",
-                "The cumulative size of all FlowFiles queued in all Connections of this Process Group",
-                Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getQueuedContentSize();
-                    }
-                })),
-        QUEUED_COUNT(new StandardMetricDescriptor<ProcessGroupStatus>("queuedCount", "Queued Count",
-                "The number of FlowFiles queued in all Connections of this Process Group", Formatter.COUNT, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return status.getQueuedCount().longValue();
-                    }
-                })),
-        TASK_MILLIS(new StandardMetricDescriptor<ProcessGroupStatus>("taskMillis", "Total Task Duration (5 mins)",
-                "The total number of thread-milliseconds that the Processors within this ProcessGroup have used to complete their tasks in the past 5 minutes",
-                Formatter.DURATION, new ValueMapper<ProcessGroupStatus>() {
-                    @Override
-                    public Long getValue(final ProcessGroupStatus status) {
-                        return calculateTaskMillis(status);
-                    }
-                }));
-
-        private MetricDescriptor<ProcessGroupStatus> descriptor;
-
-        private ProcessGroupStatusDescriptor(final MetricDescriptor<ProcessGroupStatus> descriptor) {
-            this.descriptor = descriptor;
-        }
-
-        public String getField() {
-            return descriptor.getField();
-        }
-
-        public MetricDescriptor<ProcessGroupStatus> getDescriptor() {
-            return descriptor;
-        }
-    }
-
-    public static enum ConnectionStatusDescriptor {
-
-        INPUT_BYTES(new StandardMetricDescriptor<ConnectionStatus>("inputBytes", "Bytes In (5 mins)",
-                "The cumulative size of all FlowFiles that were transferred to this Connection in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ConnectionStatus>() {
-                    @Override
-                    public Long getValue(final ConnectionStatus status) {
-                        return status.getInputBytes();
-                    }
-                })),
-        INPUT_COUNT(new StandardMetricDescriptor<ConnectionStatus>("inputCount", "FlowFiles In (5 mins)",
-                "The number of FlowFiles that were transferred to this Connection in the past 5 minutes", Formatter.COUNT, new ValueMapper<ConnectionStatus>() {
-                    @Override
-                    public Long getValue(final ConnectionStatus status) {
-                        return Long.valueOf(status.getInputCount());
-                    }
-                })),
-        OUTPUT_BYTES(new StandardMetricDescriptor<ConnectionStatus>("outputBytes", "Bytes Out (5 mins)",
-                "The cumulative size of all FlowFiles that were pulled from this Connection in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ConnectionStatus>() {
-                    @Override
-                    public Long getValue(final ConnectionStatus status) {
-                        return status.getOutputBytes();
-                    }
-                })),
-        OUTPUT_COUNT(new StandardMetricDescriptor<ConnectionStatus>("outputCount", "FlowFiles Out (5 mins)",
-                "The number of FlowFiles that were pulled from this Connection in the past 5 minutes", Formatter.COUNT, new ValueMapper<ConnectionStatus>() {
-                    @Override
-                    public Long getValue(final ConnectionStatus status) {
-                        return Long.valueOf(status.getOutputCount());
-                    }
-                })),
-        QUEUED_BYTES(new StandardMetricDescriptor<ConnectionStatus>("queuedBytes", "Queued Bytes",
-                "The number of Bytes queued in this Connection", Formatter.DATA_SIZE, new ValueMapper<ConnectionStatus>() {
-                    @Override
-                    public Long getValue(final ConnectionStatus status) {
-                        return status.getQueuedBytes();
-                    }
-                })),
-        QUEUED_COUNT(new StandardMetricDescriptor<ConnectionStatus>("queuedCount", "Queued Count",
-                "The number of FlowFiles queued in this Connection", Formatter.COUNT, new ValueMapper<ConnectionStatus>() {
-                    @Override
-                    public Long getValue(final ConnectionStatus status) {
-                        return Long.valueOf(status.getQueuedCount());
-                    }
-                }));
-
-        private MetricDescriptor<ConnectionStatus> descriptor;
-
-        private ConnectionStatusDescriptor(final MetricDescriptor<ConnectionStatus> descriptor) {
-            this.descriptor = descriptor;
-        }
-
-        public String getField() {
-            return descriptor.getField();
-        }
-
-        public MetricDescriptor<ConnectionStatus> getDescriptor() {
-            return descriptor;
-        }
-    }
 
-    public static enum ProcessorStatusDescriptor {
-
-        BYTES_READ(new StandardMetricDescriptor<ProcessorStatus>("bytesRead", "Bytes Read (5 mins)",
-                "The total number of bytes read from the Content Repository by this Processor in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getBytesRead();
-                    }
-                })),
-        BYTES_WRITTEN(new StandardMetricDescriptor<ProcessorStatus>("bytesWritten", "Bytes Written (5 mins)",
-                "The total number of bytes written to the Content Repository by this Processor in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getBytesWritten();
-                    }
-                })),
-        BYTES_TRANSFERRED(new StandardMetricDescriptor<ProcessorStatus>("bytesTransferred", "Bytes Transferred (5 mins)",
-                "The total number of bytes read from or written to the Content Repository by this Processor in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getBytesRead() + status.getBytesWritten();
-                    }
-                })),
-        INPUT_BYTES(new StandardMetricDescriptor<ProcessorStatus>("inputBytes", "Bytes In (5 mins)",
-                "The cumulative size of all FlowFiles that this Processor has pulled from its queues in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getInputBytes();
-                    }
-                })),
-        INPUT_COUNT(new StandardMetricDescriptor<ProcessorStatus>("inputCount", "FlowFiles In (5 mins)",
-                "The number of FlowFiles that this Processor has pulled from its queues in the past 5 minutes", Formatter.COUNT, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return Long.valueOf(status.getInputCount());
-                    }
-                })),
-        OUTPUT_BYTES(new StandardMetricDescriptor<ProcessorStatus>("outputBytes", "Bytes Out (5 mins)",
-                "The cumulative size of all FlowFiles that this Processor has transferred to downstream queues in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getOutputBytes();
-                    }
-                })),
-        OUTPUT_COUNT(new StandardMetricDescriptor<ProcessorStatus>("outputCount", "FlowFiles Out (5 mins)",
-                "The number of FlowFiles that this Processor has transferred to downstream queues in the past 5 minutes", Formatter.COUNT, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return Long.valueOf(status.getOutputCount());
-                    }
-                })),
-        TASK_COUNT(new StandardMetricDescriptor<ProcessorStatus>("taskCount", "Tasks (5 mins)", "The number of tasks that this Processor has completed in the past 5 minutes",
-                Formatter.COUNT, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return Long.valueOf(status.getInvocations());
-                    }
-                })),
-        TASK_MILLIS(new StandardMetricDescriptor<ProcessorStatus>("taskMillis", "Total Task Duration (5 mins)",
-                "The total number of thread-milliseconds that the Processor has used to complete its tasks in the past 5 minutes", Formatter.DURATION, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return TimeUnit.MILLISECONDS.convert(status.getProcessingNanos(), TimeUnit.NANOSECONDS);
-                    }
-                })),
-        FLOWFILES_REMOVED(new StandardMetricDescriptor<ProcessorStatus>("flowFilesRemoved", "FlowFiles Removed (5 mins)",
-                "The total number of FlowFiles removed by this Processor in the last 5 minutes", Formatter.COUNT, new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return Long.valueOf(status.getFlowFilesRemoved());
-                    }
-                })),
-        AVERAGE_LINEAGE_DURATION(new StandardMetricDescriptor<ProcessorStatus>(
-                "averageLineageDuration",
-                "Average Lineage Duration (5 mins)",
-                "The average amount of time that a FlowFile took to process (from receipt until this Processor finished processing it) in the past 5 minutes.",
-                Formatter.DURATION,
-                new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getAverageLineageDuration(TimeUnit.MILLISECONDS);
-                    }
-                }, new ValueReducer<StatusSnapshot, Long>() {
-                    @Override
-                    public Long reduce(final List<StatusSnapshot> values) {
-                        long millis = 0L;
-                        int count = 0;
-
-                        for (final StatusSnapshot snapshot : values) {
-                            final long removed = snapshot.getStatusMetrics().get(FLOWFILES_REMOVED.getDescriptor()).longValue();
-                            count += removed;
-
-                            count += snapshot.getStatusMetrics().get(OUTPUT_COUNT.getDescriptor()).longValue();
-
-                            final long avgMillis = snapshot.getStatusMetrics().get(AVERAGE_LINEAGE_DURATION.getDescriptor()).longValue();
-                            final long totalMillis = avgMillis * removed;
-                            millis += totalMillis;
-                        }
-
-                        return count == 0 ? 0 : millis / count;
-                    }
-                }
-        )),
-        AVERAGE_TASK_MILLIS(new StandardMetricDescriptor<ProcessorStatus>(
-                "averageTaskMillis",
-                "Average Task Duration",
-                "The average duration it took this Processor to complete a task, as averaged over the past 5 minutes",
-                Formatter.DURATION,
-                new ValueMapper<ProcessorStatus>() {
-                    @Override
-                    public Long getValue(final ProcessorStatus status) {
-                        return status.getInvocations() == 0 ? 0 : TimeUnit.MILLISECONDS.convert(status.getProcessingNanos(), TimeUnit.NANOSECONDS) / status.getInvocations();
-                    }
-                },
-                new ValueReducer<StatusSnapshot, Long>() {
-                    @Override
-                    public Long reduce(final List<StatusSnapshot> values) {
-                        long procMillis = 0L;
-                        int invocations = 0;
-
-                        for (final StatusSnapshot snapshot : values) {
-                            procMillis += snapshot.getStatusMetrics().get(TASK_MILLIS.getDescriptor()).longValue();
-                            invocations += snapshot.getStatusMetrics().get(TASK_COUNT.getDescriptor()).intValue();
-                        }
-
-                        if (invocations == 0) {
-                            return 0L;
-                        }
-
-                        return procMillis / invocations;
-                    }
-                }
-        ));
-
-        private MetricDescriptor<ProcessorStatus> descriptor;
-
-        private ProcessorStatusDescriptor(final MetricDescriptor<ProcessorStatus> descriptor) {
-            this.descriptor = descriptor;
-        }
-
-        public String getField() {
-            return descriptor.getField();
-        }
-
-        public MetricDescriptor<ProcessorStatus> getDescriptor() {
-            return descriptor;
-        }
-    }
 
     @Override
     public List<MetricDescriptor<ConnectionStatus>> getConnectionMetricDescriptors() {

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/events/VolatileBulletinRepository.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/events/VolatileBulletinRepository.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/events/VolatileBulletinRepository.java
index 8aeb34d..7202546 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/events/VolatileBulletinRepository.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/events/VolatileBulletinRepository.java
@@ -19,7 +19,6 @@ package org.apache.nifi.events;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.TimeUnit;
@@ -207,25 +206,6 @@ public class VolatileBulletinRepository implements BulletinRepository {
         return controllerBulletins;
     }
 
-    /**
-     * Overrides the default bulletin processing strategy. When a custom
-     * bulletin strategy is employed, bulletins will not be persisted in this
-     * repository and will sent to the specified strategy instead.
-     *
-     * @param strategy bulletin strategy
-     */
-    public void overrideDefaultBulletinProcessing(final BulletinProcessingStrategy strategy) {
-        Objects.requireNonNull(strategy);
-        this.processingStrategy = strategy;
-    }
-
-    /**
-     * Restores the default bulletin processing strategy.
-     */
-    public void restoreDefaultBulletinProcessing() {
-        this.processingStrategy = new DefaultBulletinProcessingStrategy();
-    }
-
     private List<RingBuffer<Bulletin>> getBulletinBuffers(final Bulletin bulletin) {
         final String storageKey = getBulletinStoreKey(bulletin);
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/cluster/HeartbeatPayloadTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/cluster/HeartbeatPayloadTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/cluster/HeartbeatPayloadTest.java
index d6bfca0..af73eef 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/cluster/HeartbeatPayloadTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/cluster/HeartbeatPayloadTest.java
@@ -16,16 +16,12 @@
  */
 package org.apache.nifi.cluster;
 
+import static org.junit.Assert.assertEquals;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.nifi.controller.Counter;
-import org.apache.nifi.controller.StandardCounter;
-import org.apache.nifi.diagnostics.SystemDiagnostics;
+
 import org.apache.nifi.util.NiFiProperties;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -35,15 +31,8 @@ import org.junit.Test;
 public class HeartbeatPayloadTest {
 
     private HeartbeatPayload payload;
-
-    private List<Counter> counters;
-
-    private Counter counter;
-
     private int activeThreadCount;
-
     private int totalFlowFileCount;
-
     private ByteArrayOutputStream marshalledBytes;
 
     @BeforeClass
@@ -53,19 +42,9 @@ public class HeartbeatPayloadTest {
 
     @Before
     public void setup() {
-
         payload = new HeartbeatPayload();
-
         activeThreadCount = 15;
         totalFlowFileCount = 25;
-
-        counters = new ArrayList<>();
-        String identifier = "identifier";
-        String context = "context";
-        String name = "name";
-        counter = new StandardCounter(identifier, context, name);
-        counters.add(counter);
-
         marshalledBytes = new ByteArrayOutputStream();
     }
 
@@ -73,48 +52,19 @@ public class HeartbeatPayloadTest {
     public void testMarshallingWithNoInfo() {
         HeartbeatPayload.marshal(payload, marshalledBytes);
         HeartbeatPayload newPayload = HeartbeatPayload.unmarshal(new ByteArrayInputStream(marshalledBytes.toByteArray()));
-        assertNull(newPayload.getCounters());
         assertEquals(0, newPayload.getActiveThreadCount());
         assertEquals(0, newPayload.getTotalFlowFileCount());
     }
 
     @Test
     public void testMarshalling() {
-
         payload.setActiveThreadCount(activeThreadCount);
         payload.setTotalFlowFileCount(totalFlowFileCount);
-        payload.setCounters(counters);
-        payload.setSystemDiagnostics(new SystemDiagnostics());
 
         HeartbeatPayload.marshal(payload, marshalledBytes);
         HeartbeatPayload newPayload = HeartbeatPayload.unmarshal(new ByteArrayInputStream(marshalledBytes.toByteArray()));
 
-        List<Counter> newCounters = newPayload.getCounters();
-        assertEquals(1, newCounters.size());
-
-        Counter newCounter = newCounters.get(0);
-        assertCounterEquals(counter, newCounter);
-
         assertEquals(activeThreadCount, newPayload.getActiveThreadCount());
         assertEquals(totalFlowFileCount, newPayload.getTotalFlowFileCount());
     }
-
-    private void assertCounterEquals(Counter expected, Counter actual) {
-        assertEquals(expected.getContext(), actual.getContext());
-        assertEquals(expected.getIdentifier(), actual.getIdentifier());
-        assertEquals(expected.getName(), actual.getName());
-        assertEquals(expected.getValue(), actual.getValue());
-    }
-
-//    private void assertRepositoryStatusReportEntryEquals(RepositoryStatusReportEntry expected, RepositoryStatusReportEntry actual) {
-//        assertEquals(expected.getConsumerId(), actual.getConsumerId());
-//        assertEquals(expected.getBytesRead(), actual.getBytesRead());
-//        assertEquals(expected.getBytesWritten(), actual.getBytesWritten());
-//        assertEquals(expected.getContentSizeIn(), actual.getContentSizeIn());
-//        assertEquals(expected.getContentSizeOut(), actual.getContentSizeOut());
-//        assertEquals(expected.getFlowFilesIn(), actual.getFlowFilesIn());
-//        assertEquals(expected.getFlowFilesOut(), actual.getFlowFilesOut());
-//        assertEquals(expected.getInvocations(), actual.getInvocations());
-//        assertEquals(expected.getProcessingNanos(), actual.getProcessingNanos());
-//    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/TestStandardFlowFileQueue.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/TestStandardFlowFileQueue.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/TestStandardFlowFileQueue.java
index 2ba1161..18c55c6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/TestStandardFlowFileQueue.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/TestStandardFlowFileQueue.java
@@ -108,7 +108,7 @@ public class TestStandardFlowFileQueue {
             }
         }).when(provRepo).registerEvents(Mockito.any(Iterable.class));
 
-        queue = new StandardFlowFileQueue("id", connection, flowFileRepo, provRepo, claimManager, scheduler, swapManager, null, 10000, null);
+        queue = new StandardFlowFileQueue("id", connection, flowFileRepo, provRepo, claimManager, scheduler, swapManager, null, 10000);
         TestFlowFile.idGenerator.set(0L);
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestStandardProcessSession.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestStandardProcessSession.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestStandardProcessSession.java
index f8db35e..644018f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestStandardProcessSession.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestStandardProcessSession.java
@@ -139,7 +139,7 @@ public class TestStandardProcessSession {
         final ProcessScheduler processScheduler = Mockito.mock(ProcessScheduler.class);
 
         final FlowFileSwapManager swapManager = Mockito.mock(FlowFileSwapManager.class);
-        flowFileQueue = new StandardFlowFileQueue("1", connection, flowFileRepo, provenanceRepo, null, processScheduler, swapManager, null, 10000, null);
+        flowFileQueue = new StandardFlowFileQueue("1", connection, flowFileRepo, provenanceRepo, null, processScheduler, swapManager, null, 10000);
         when(connection.getFlowFileQueue()).thenReturn(flowFileQueue);
 
         Mockito.doAnswer(new Answer<Object>() {

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestWriteAheadFlowFileRepository.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestWriteAheadFlowFileRepository.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestWriteAheadFlowFileRepository.java
index cd4aa27..4094ca4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestWriteAheadFlowFileRepository.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/repository/TestWriteAheadFlowFileRepository.java
@@ -82,7 +82,7 @@ public class TestWriteAheadFlowFileRepository {
         when(connection.getDestination()).thenReturn(Mockito.mock(Connectable.class));
 
         final FlowFileSwapManager swapMgr = new MockFlowFileSwapManager();
-        final FlowFileQueue queue = new StandardFlowFileQueue("1234", connection, null, null, claimManager, null, swapMgr, null, 10000, null);
+        final FlowFileQueue queue = new StandardFlowFileQueue("1234", connection, null, null, claimManager, null, swapMgr, null, 10000);
 
         when(connection.getFlowFileQueue()).thenReturn(queue);
         queueProvider.addConnection(connection);

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/scheduling/TestStandardProcessScheduler.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/scheduling/TestStandardProcessScheduler.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/scheduling/TestStandardProcessScheduler.java
index 3b33478..8beafdb 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/scheduling/TestStandardProcessScheduler.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/scheduling/TestStandardProcessScheduler.java
@@ -19,7 +19,6 @@ package org.apache.nifi.controller.scheduling;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -36,10 +35,9 @@ import org.apache.nifi.annotation.lifecycle.OnDisabled;
 import org.apache.nifi.annotation.lifecycle.OnEnabled;
 import org.apache.nifi.annotation.lifecycle.OnScheduled;
 import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.state.StateManagerProvider;
 import org.apache.nifi.controller.AbstractControllerService;
 import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.components.state.StateManagerProvider;
-import org.apache.nifi.controller.Heartbeater;
 import org.apache.nifi.controller.ProcessScheduler;
 import org.apache.nifi.controller.ProcessorNode;
 import org.apache.nifi.controller.ReportingTaskNode;
@@ -79,7 +77,7 @@ public class TestStandardProcessScheduler {
     public void setup() throws InitializationException {
         System.setProperty("nifi.properties.file.path", "src/test/resources/nifi.properties");
         this.refreshNiFiProperties();
-        scheduler = new StandardProcessScheduler(Mockito.mock(Heartbeater.class), Mockito.mock(ControllerServiceProvider.class), null, stateMgrProvider);
+        scheduler = new StandardProcessScheduler(Mockito.mock(ControllerServiceProvider.class), null, stateMgrProvider);
         scheduler.setSchedulingAgent(SchedulingStrategy.TIMER_DRIVEN, Mockito.mock(SchedulingAgent.class));
 
         reportingTask = new TestReportingTask();
@@ -507,6 +505,6 @@ public class TestStandardProcessScheduler {
     }
 
     private ProcessScheduler createScheduler() {
-        return new StandardProcessScheduler(mock(Heartbeater.class), null, null, stateMgrProvider);
+        return new StandardProcessScheduler(null, null, stateMgrProvider);
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
index 5abefda..f7a3386 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/TestStandardControllerServiceProvider.java
@@ -29,7 +29,6 @@ import java.util.UUID;
 
 import org.apache.nifi.components.state.StateManager;
 import org.apache.nifi.components.state.StateManagerProvider;
-import org.apache.nifi.controller.Heartbeater;
 import org.apache.nifi.controller.ProcessScheduler;
 import org.apache.nifi.controller.ProcessorNode;
 import org.apache.nifi.controller.ScheduledState;
@@ -76,8 +75,7 @@ public class TestStandardControllerServiceProvider {
     }
 
     private StandardProcessScheduler createScheduler() {
-        final Heartbeater heartbeater = Mockito.mock(Heartbeater.class);
-        return new StandardProcessScheduler(heartbeater, null, null, stateManagerProvider);
+        return new StandardProcessScheduler(null, null, stateManagerProvider);
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index bc5245c..cfe18c5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -22,8 +22,8 @@ import org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.web.api.dto.BulletinBoardDTO;
 import org.apache.nifi.web.api.dto.BulletinQueryDTO;
 import org.apache.nifi.web.api.dto.ClusterDTO;
-import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.ComponentHistoryDTO;
+import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.ConnectionDTO;
 import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
 import org.apache.nifi.web.api.dto.ControllerDTO;
@@ -39,7 +39,6 @@ import org.apache.nifi.web.api.dto.FunnelDTO;
 import org.apache.nifi.web.api.dto.LabelDTO;
 import org.apache.nifi.web.api.dto.ListingRequestDTO;
 import org.apache.nifi.web.api.dto.NodeDTO;
-import org.apache.nifi.web.api.dto.NodeSystemDiagnosticsDTO;
 import org.apache.nifi.web.api.dto.PortDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
@@ -61,16 +60,12 @@ import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO;
 import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO;
 import org.apache.nifi.web.api.dto.search.SearchResultsDTO;
-import org.apache.nifi.web.api.dto.status.ClusterConnectionStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterPortStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterProcessorStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterRemoteProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusHistoryDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
 import org.apache.nifi.web.api.dto.status.ControllerStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodeStatusDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
 import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 
 import java.util.Collection;
@@ -388,6 +383,15 @@ public interface NiFiServiceFacade {
     ProcessorDTO getProcessor(String id);
 
     /**
+     * Gets the processor status.
+     *
+     * @param groupId group
+     * @param id id
+     * @return status
+     */
+    ProcessorStatusDTO getProcessorStatus(String groupId, String id);
+
+    /**
      * Gets the processor status history.
      *
      * @param groupId group
@@ -478,6 +482,15 @@ public interface NiFiServiceFacade {
     ConnectionDTO getConnection(String groupId, String connectionId);
 
     /**
+     * Gets the status of the specified connection.
+     *
+     * @param groupId group
+     * @param connectionId connection
+     * @return status
+     */
+    ConnectionStatusDTO getConnectionStatus(String groupId, String connectionId);
+
+    /**
      * Gets the status history of the specified connection.
      *
      * @param groupId group
@@ -649,6 +662,15 @@ public interface NiFiServiceFacade {
     Set<PortDTO> getInputPorts(String groupId);
 
     /**
+     * Gets the input port status.
+     *
+     * @param groupId group
+     * @param inputPortId input port
+     * @return status
+     */
+    PortStatusDTO getInputPortStatus(String groupId, String inputPortId);
+
+    /**
      * Determines if the input port could be updated.
      *
      * @param groupId The id of the group
@@ -715,6 +737,15 @@ public interface NiFiServiceFacade {
     Set<PortDTO> getOutputPorts(String groupId);
 
     /**
+     * Gets the output port status.
+     *
+     * @param groupId group
+     * @param outputPortId output port
+     * @return status
+     */
+    PortStatusDTO getOutputPortStatus(String groupId, String outputPortId);
+
+    /**
      * Determines if the output port could be updated.
      *
      * @param groupId The id of the group
@@ -851,6 +882,15 @@ public interface NiFiServiceFacade {
     Set<RemoteProcessGroupDTO> getRemoteProcessGroups(String groupId);
 
     /**
+     * Gets the remote process group status.
+     *
+     * @param groupId group
+     * @param id remote process group
+     * @return status
+     */
+    RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(String groupId, String id);
+
+    /**
      * Gets the remote process group status history.
      *
      * @param groupId The id of the parent group
@@ -1507,103 +1547,6 @@ public interface NiFiServiceFacade {
      */
     void deleteNode(String nodeId);
 
-    /**
-     * Returns the status the specified node id.
-     *
-     * @param nodeId The id of the desired node
-     * @return The node status
-     */
-    NodeStatusDTO getNodeStatus(String nodeId);
-
-    /**
-     * Returns the system diagnostics for the specified node id.
-     *
-     * @param nodeId The id of the desired node
-     * @return The node status
-     */
-    NodeSystemDiagnosticsDTO getNodeSystemDiagnostics(String nodeId);
-
-    /**
-     * Returns the cluster's status.
-     *
-     * @return The cluster status
-     */
-    ClusterStatusDTO getClusterStatus();
-
-    /**
-     * Returns a processor's status for each node connected to the cluster.
-     *
-     * @param processorId a processor identifier
-     * @return The cluster processor status transfer object.
-     */
-    ClusterProcessorStatusDTO getClusterProcessorStatus(String processorId);
-
-    /**
-     * @param processorId id
-     * @return the processor status history for each node connected to the cluster
-     */
-    ClusterStatusHistoryDTO getClusterProcessorStatusHistory(String processorId);
-
-    /**
-     * Returns a connection's status for each node connected to the cluster.
-     *
-     * @param connectionId a connection identifier
-     * @return The cluster connection status transfer object.
-     */
-    ClusterConnectionStatusDTO getClusterConnectionStatus(String connectionId);
-
-    /**
-     * @param connectionId id
-     * @return the connection status history for each node connected to the cluster
-     */
-    ClusterStatusHistoryDTO getClusterConnectionStatusHistory(String connectionId);
-
-    /**
-     * @param processGroupId id
-     * @return the process group status history for each node connected to the cluster
-     */
-    ClusterStatusHistoryDTO getClusterProcessGroupStatusHistory(String processGroupId);
-
-    /**
-     * Returns a process group's status for each node connected to the cluster.
-     *
-     * @param processorId a process group identifier
-     * @return The cluster process group status transfer object.
-     */
-    ClusterProcessGroupStatusDTO getClusterProcessGroupStatus(String processorId);
-
-    /**
-     * Returns the remote process group status history for each node connected to the cluster.
-     *
-     * @param remoteProcessGroupId a remote process group identifier
-     * @return The cluster status history
-     */
-    ClusterStatusHistoryDTO getClusterRemoteProcessGroupStatusHistory(String remoteProcessGroupId);
-
-    /**
-     * Returns a remote process group's status for each node connected to the cluster.
-     *
-     * @param remoteProcessGroupId a remote process group identifier
-     * @return The cluster remote process group status transfer object.
-     */
-    ClusterRemoteProcessGroupStatusDTO getClusterRemoteProcessGroupStatus(String remoteProcessGroupId);
-
-    /**
-     * Returns an input port's status for each node connected to the cluster.
-     *
-     * @param inputPortId a port identifier
-     * @return The cluster port status transfer object.
-     */
-    ClusterPortStatusDTO getClusterInputPortStatus(String inputPortId);
-
-    /**
-     * Returns an output port's status for each node connected to the cluster.
-     *
-     * @param outputPortId a port identifier
-     * @return The cluster port status transfer object.
-     */
-    ClusterPortStatusDTO getClusterOutputPortStatus(String outputPortId);
-
     // ----------------------------------------
     // BulletinBoard methods
     // ----------------------------------------


[13/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java
index 3ebae8f..1df212a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusDTO.java
@@ -14,51 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto.status;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Collection;
 import java.util.Date;
+import java.util.List;
+
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
 import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
-/**
- * The status for a process group in this NiFi.
- */
 @XmlType(name = "processGroupStatus")
-public class ProcessGroupStatusDTO extends StatusDTO {
-
+public class ProcessGroupStatusDTO implements Cloneable {
     private String id;
     private String name;
-    private Collection<ConnectionStatusDTO> connectionStatus;
-    private Collection<ProcessorStatusDTO> processorStatus;
-    private Collection<ProcessGroupStatusDTO> processGroupStatus;
-    private Collection<RemoteProcessGroupStatusDTO> remoteProcessGroupStatus;
-    private Collection<PortStatusDTO> inputPortStatus;
-    private Collection<PortStatusDTO> outputPortStatus;
-
-    private String input;
-    private String queuedCount;
-    private String queuedSize;
-    private String queued;
-    private String read;
-    private String written;
-    private String output;
-    private String transferred;
-    private String received;
-    private String sent;
-    private Integer activeThreadCount;
     private Date statsLastRefreshed;
 
-    /**
-     * The id for the process group.
-     *
-     * @return The id for the process group
-     */
-    @ApiModelProperty(
-            value = "The id of the process group."
-    )
+    private ProcessGroupStatusSnapshotDTO aggregateSnapshot;
+    private List<NodeProcessGroupStatusSnapshotDTO> nodeSnapshots;
+
+    @ApiModelProperty("The ID of the Process Group")
     public String getId() {
         return id;
     }
@@ -67,12 +44,7 @@ public class ProcessGroupStatusDTO extends StatusDTO {
         this.id = id;
     }
 
-    /**
-     * @return name of this process group
-     */
-    @ApiModelProperty(
-            value = "The name of this process group."
-    )
+    @ApiModelProperty("The name of the PRocess Group")
     public String getName() {
         return name;
     }
@@ -81,274 +53,23 @@ public class ProcessGroupStatusDTO extends StatusDTO {
         this.name = name;
     }
 
-    /**
-     * @return active thread count for this process group
-     */
-    @ApiModelProperty(
-            value = "The active thread count for this process group."
-    )
-    public Integer getActiveThreadCount() {
-        return activeThreadCount;
-    }
-
-    public void setActiveThreadCount(Integer activeThreadCount) {
-        this.activeThreadCount = activeThreadCount;
-    }
-
-    /**
-     * The status of all connections in this process group.
-     *
-     * @return The status of all connections
-     */
-    @ApiModelProperty(
-            value = "The status of all conenctions in the process group."
-    )
-    public Collection<ConnectionStatusDTO> getConnectionStatus() {
-        return connectionStatus;
-    }
-
-    public void setConnectionStatus(Collection<ConnectionStatusDTO> connectionStatus) {
-        this.connectionStatus = connectionStatus;
-    }
-
-    /**
-     * The status of all process groups in this process group.
-     *
-     * @return The status of all process groups
-     */
-    @ApiModelProperty(
-            value = "The status of all process groups in the process group."
-    )
-    public Collection<ProcessGroupStatusDTO> getProcessGroupStatus() {
-        return processGroupStatus;
-    }
-
-    public void setProcessGroupStatus(Collection<ProcessGroupStatusDTO> processGroupStatus) {
-        this.processGroupStatus = processGroupStatus;
+    @ApiModelProperty("The aggregate status of all nodes in the cluster")
+    public ProcessGroupStatusSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
     }
 
-    /**
-     * The status of all remote process groups in this process group.
-     *
-     * @return The status of all remote process groups
-     */
-    @ApiModelProperty(
-            value = "The status of all remote process groups in the process group.."
-    )
-    public Collection<RemoteProcessGroupStatusDTO> getRemoteProcessGroupStatus() {
-        return remoteProcessGroupStatus;
+    public void setAggregateSnapshot(ProcessGroupStatusSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
     }
 
-    public void setRemoteProcessGroupStatus(final Collection<RemoteProcessGroupStatusDTO> remoteProcessGroupStatus) {
-        this.remoteProcessGroupStatus = remoteProcessGroupStatus;
+    @ApiModelProperty("The status reported by each node in the cluster. If the NiFi instance is a standalone instance, rather than "
+        + "a clustered instance, this value may be null.")
+    public List<NodeProcessGroupStatusSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
     }
 
-    /**
-     * The status of all processors in this process group.
-     *
-     * @return The status of all processors
-     */
-    @ApiModelProperty(
-            value = "The status of all processors in the process group."
-    )
-    public Collection<ProcessorStatusDTO> getProcessorStatus() {
-        return processorStatus;
-    }
-
-    public void setProcessorStatus(Collection<ProcessorStatusDTO> processorStatus) {
-        this.processorStatus = processorStatus;
-    }
-
-    /**
-     * The status of all input ports in this process group.
-     *
-     * @return The status of all input ports
-     */
-    @ApiModelProperty(
-            value = "The status of all input ports in the process group."
-    )
-    public Collection<PortStatusDTO> getInputPortStatus() {
-        return inputPortStatus;
-    }
-
-    public void setInputPortStatus(Collection<PortStatusDTO> inputPortStatus) {
-        this.inputPortStatus = inputPortStatus;
-    }
-
-    /**
-     * The status of all output ports in this process group.
-     *
-     * @return The status of all output ports
-     */
-    @ApiModelProperty(
-            value = "The status of all output ports in the process group."
-    )
-    public Collection<PortStatusDTO> getOutputPortStatus() {
-        return outputPortStatus;
-    }
-
-    public void setOutputPortStatus(Collection<PortStatusDTO> outputPortStatus) {
-        this.outputPortStatus = outputPortStatus;
-    }
-
-    /**
-     * The output stats for this process group.
-     *
-     * @return The output stats
-     */
-    @ApiModelProperty(
-            value = "The output count/size for the process group in the last 5 minutes."
-    )
-    public String getOutput() {
-        return output;
-    }
-
-    public void setOutput(String output) {
-        this.output = output;
-    }
-
-    /**
-     * The transferred stats for this process group. This represents the count/size of flowfiles transferred to/from queues.
-     *
-     * @return The transferred status for this process group
-     */
-    @ApiModelProperty(
-            value = "The count/size transferred to/frome queues in the process group in the last 5 minutes."
-    )
-    public String getTransferred() {
-        return transferred;
-    }
-
-    public void setTransferred(String transferred) {
-        this.transferred = transferred;
-    }
-
-    /**
-     * The received stats for this process group. This represents the count/size of flowfiles received.
-     *
-     * @return The received stats for this process group
-     */
-    @ApiModelProperty(
-            value = "The count/size sent to the process group in the last 5 minutes."
-    )
-    public String getReceived() {
-        return received;
-    }
-
-    public void setReceived(String received) {
-        this.received = received;
-    }
-
-    /**
-     * The sent stats for this process group. This represents the count/size of flowfiles sent.
-     *
-     * @return The sent stats for this process group
-     */
-    @ApiModelProperty(
-            value = "The count/size sent from this process group in the last 5 minutes."
-    )
-    public String getSent() {
-        return sent;
-    }
-
-    public void setSent(String sent) {
-        this.sent = sent;
-    }
-
-    /**
-     * The queued count for this process group.
-     *
-     * @return The queued count for this process group
-     */
-    @ApiModelProperty(
-            value = "The count that is queued for the process group."
-    )
-    public String getQueuedCount() {
-        return queuedCount;
-    }
-
-    public void setQueuedCount(String queuedCount) {
-        this.queuedCount = queuedCount;
-    }
-
-    /**
-     * The queued size for this process group.
-     *
-     * @return The queued size for this process group
-     */
-    @ApiModelProperty(
-            value = "The size that is queued for the process group."
-    )
-    public String getQueuedSize() {
-        return queuedSize;
-    }
-
-    public void setQueuedSize(String queuedSize) {
-        this.queuedSize = queuedSize;
-    }
-
-    /**
-     * The queued stats for this process group.
-     *
-     * @return The queued stats
-     */
-    @ApiModelProperty(
-            value = "The count/size that is queued in the the process group."
-    )
-    public String getQueued() {
-        return queued;
-    }
-
-    public void setQueued(String queued) {
-        this.queued = queued;
-    }
-
-    /**
-     * The read stats for this process group.
-     *
-     * @return The read stats
-     */
-    @ApiModelProperty(
-            value = "The number of bytes read in the last 5 minutes."
-    )
-    public String getRead() {
-        return read;
-    }
-
-    public void setRead(String read) {
-        this.read = read;
-    }
-
-    /**
-     * The written stats for this process group.
-     *
-     * @return The written stats
-     */
-    @ApiModelProperty(
-            value = "The number of bytes written in the last 5 minutes."
-    )
-    public String getWritten() {
-        return written;
-    }
-
-    public void setWritten(String written) {
-        this.written = written;
-    }
-
-    /**
-     * The input stats for this process group.
-     *
-     * @return The input stats
-     */
-    @ApiModelProperty(
-            value = "The input count/size for the process group in the last 5 minutes."
-    )
-    public String getInput() {
-        return input;
-    }
-
-    public void setInput(String input) {
-        this.input = input;
+    public void setNodeSnapshots(List<NodeProcessGroupStatusSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 
     /**
@@ -358,7 +79,7 @@ public class ProcessGroupStatusDTO extends StatusDTO {
      */
     @XmlJavaTypeAdapter(TimeAdapter.class)
     @ApiModelProperty(
-            value = "The time the status for the process group was last refreshed."
+        value = "The time the status for the process group was last refreshed."
     )
     public Date getStatsLastRefreshed() {
         return statsLastRefreshed;
@@ -367,5 +88,4 @@ public class ProcessGroupStatusDTO extends StatusDTO {
     public void setStatsLastRefreshed(Date statsLastRefreshed) {
         this.statsLastRefreshed = statsLastRefreshed;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java
new file mode 100644
index 0000000..e5c61dd
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessGroupStatusSnapshotDTO.java
@@ -0,0 +1,532 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * The status for a process group in this NiFi.
+ */
+@XmlType(name = "processGroupStatusSnapshot")
+public class ProcessGroupStatusSnapshotDTO implements Cloneable {
+
+    private String id;
+    private String name;
+    private Collection<ConnectionStatusSnapshotDTO> connectionStatus;
+    private Collection<ProcessorStatusSnapshotDTO> processorStatus;
+    private Collection<ProcessGroupStatusSnapshotDTO> processGroupStatus;
+    private Collection<RemoteProcessGroupStatusSnapshotDTO> remoteProcessGroupStatus;
+    private Collection<PortStatusSnapshotDTO> inputPortStatus;
+    private Collection<PortStatusSnapshotDTO> outputPortStatus;
+
+    private Integer flowFilesIn = 0;
+    private Long bytesIn = 0L;
+    private String input;
+
+    private Integer flowFilesQueued = 0;
+    private Long bytesQueued = 0L;
+    private String queued;
+    private String queuedCount;
+    private String queuedSize;
+
+    private Long bytesRead = 0L;
+    private String read;
+    private Long bytesWritten = 0L;
+    private String written;
+
+    private Integer flowFilesOut = 0;
+    private Long bytesOut = 0L;
+    private String output;
+
+    private Integer flowFilesTransferred = 0;
+    private Long bytesTransferred = 0L;
+    private String transferred;
+
+    private Long bytesReceived = 0L;
+    private Integer flowFilesReceived = 0;
+    private String received;
+
+    private Long bytesSent = 0L;
+    private Integer flowFilesSent = 0;
+    private String sent;
+
+    private Integer activeThreadCount = 0;
+
+    /**
+     * The id for the process group.
+     *
+     * @return The id for the process group
+     */
+    @ApiModelProperty("The id of the process group.")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return name of this process group
+     */
+    @ApiModelProperty("The name of this process group.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return active thread count for this process group
+     */
+    @ApiModelProperty("The active thread count for this process group.")
+    public Integer getActiveThreadCount() {
+        return activeThreadCount;
+    }
+
+    public void setActiveThreadCount(Integer activeThreadCount) {
+        this.activeThreadCount = activeThreadCount;
+    }
+
+    /**
+     * The status of all connections in this process group.
+     *
+     * @return The status of all connections
+     */
+    @ApiModelProperty("The status of all conenctions in the process group.")
+    public Collection<ConnectionStatusSnapshotDTO> getConnectionStatusSnapshots() {
+        return connectionStatus;
+    }
+
+    public void setConnectionStatusSnapshots(Collection<ConnectionStatusSnapshotDTO> connectionStatus) {
+        this.connectionStatus = connectionStatus;
+    }
+
+    /**
+     * The status of all process groups in this process group.
+     *
+     * @return The status of all process groups
+     */
+    @ApiModelProperty("The status of all process groups in the process group.")
+    public Collection<ProcessGroupStatusSnapshotDTO> getProcessGroupStatusSnapshots() {
+        return processGroupStatus;
+    }
+
+    public void setProcessGroupStatusSnapshots(Collection<ProcessGroupStatusSnapshotDTO> processGroupStatus) {
+        this.processGroupStatus = processGroupStatus;
+    }
+
+    /**
+     * The status of all remote process groups in this process group.
+     *
+     * @return The status of all remote process groups
+     */
+    @ApiModelProperty("The status of all remote process groups in the process group.")
+    public Collection<RemoteProcessGroupStatusSnapshotDTO> getRemoteProcessGroupStatusSnapshots() {
+        return remoteProcessGroupStatus;
+    }
+
+    public void setRemoteProcessGroupStatusSnapshots(final Collection<RemoteProcessGroupStatusSnapshotDTO> remoteProcessGroupStatus) {
+        this.remoteProcessGroupStatus = remoteProcessGroupStatus;
+    }
+
+    /**
+     * The status of all processors in this process group.
+     *
+     * @return The status of all processors
+     */
+    @ApiModelProperty("The status of all processors in the process group.")
+    public Collection<ProcessorStatusSnapshotDTO> getProcessorStatusSnapshots() {
+        return processorStatus;
+    }
+
+    public void setProcessorStatusSnapshots(Collection<ProcessorStatusSnapshotDTO> processorStatus) {
+        this.processorStatus = processorStatus;
+    }
+
+    /**
+     * The status of all input ports in this process group.
+     *
+     * @return The status of all input ports
+     */
+    @ApiModelProperty("The status of all input ports in the process group.")
+    public Collection<PortStatusSnapshotDTO> getInputPortStatusSnapshots() {
+        return inputPortStatus;
+    }
+
+    public void setInputPortStatusSnapshots(Collection<PortStatusSnapshotDTO> inputPortStatus) {
+        this.inputPortStatus = inputPortStatus;
+    }
+
+    /**
+     * The status of all output ports in this process group.
+     *
+     * @return The status of all output ports
+     */
+    @ApiModelProperty("The status of all output ports in the process group.")
+    public Collection<PortStatusSnapshotDTO> getOutputPortStatusSnapshots() {
+        return outputPortStatus;
+    }
+
+    public void setOutputPortStatusSnapshots(Collection<PortStatusSnapshotDTO> outputPortStatus) {
+        this.outputPortStatus = outputPortStatus;
+    }
+
+    /**
+     * The output stats for this process group.
+     *
+     * @return The output stats
+     */
+    @ApiModelProperty("The output count/size for the process group in the last 5 minutes.")
+    public String getOutput() {
+        return output;
+    }
+
+    /**
+     * The transferred stats for this process group. This represents the count/size of flowfiles transferred to/from queues.
+     *
+     * @return The transferred status for this process group
+     */
+    @ApiModelProperty("The count/size transferred to/frome queues in the process group in the last 5 minutes.")
+    public String getTransferred() {
+        return transferred;
+    }
+
+    /**
+     * The received stats for this process group. This represents the count/size of flowfiles received.
+     *
+     * @return The received stats for this process group
+     */
+    @ApiModelProperty("The count/size sent to the process group in the last 5 minutes.")
+    public String getReceived() {
+        return received;
+    }
+
+
+    /**
+     * The sent stats for this process group. This represents the count/size of flowfiles sent.
+     *
+     * @return The sent stats for this process group
+     */
+    @ApiModelProperty("The count/size sent from this process group in the last 5 minutes.")
+    public String getSent() {
+        return sent;
+    }
+
+
+    /**
+     * The queued count for this process group.
+     *
+     * @return The queued count for this process group
+     */
+    @ApiModelProperty("The count that is queued for the process group.")
+    public String getQueuedCount() {
+        return queuedCount;
+    }
+
+
+    /**
+     * The queued size for this process group.
+     *
+     * @return The queued size for this process group
+     */
+    @ApiModelProperty("The size that is queued for the process group.")
+    public String getQueuedSize() {
+        return queuedSize;
+    }
+
+
+    /**
+     * The queued stats for this process group.
+     *
+     * @return The queued stats
+     */
+    @ApiModelProperty("The count/size that is queued in the the process group.")
+    public String getQueued() {
+        return queued;
+    }
+
+
+    /**
+     * The read stats for this process group.
+     *
+     * @return The read stats
+     */
+    @ApiModelProperty("The number of bytes read in the last 5 minutes.")
+    public String getRead() {
+        return read;
+    }
+
+
+    /**
+     * The written stats for this process group.
+     *
+     * @return The written stats
+     */
+    @ApiModelProperty("The number of bytes written in the last 5 minutes.")
+    public String getWritten() {
+        return written;
+    }
+
+
+    /**
+     * The input stats for this process group.
+     *
+     * @return The input stats
+     */
+    @ApiModelProperty("The input count/size for the process group in the last 5 minutes (pretty printed).")
+    public String getInput() {
+        return input;
+    }
+
+
+    @ApiModelProperty("The number of FlowFiles that have come into this ProcessGroup in the last 5 minutes")
+    public Integer getFlowFilesIn() {
+        return flowFilesIn;
+    }
+
+    public void setFlowFilesIn(Integer flowFilesIn) {
+        this.flowFilesIn = flowFilesIn;
+    }
+
+    @ApiModelProperty("The number of bytes that have come into this ProcessGroup in the last 5 minutes")
+    public Long getBytesIn() {
+        return bytesIn;
+    }
+
+    public void setBytesIn(Long bytesIn) {
+        this.bytesIn = bytesIn;
+    }
+
+    @ApiModelProperty("The number of FlowFiles that are queued up in this ProcessGroup right now")
+    public Integer getFlowFilesQueued() {
+        return flowFilesQueued;
+    }
+
+    public void setFlowFilesQueued(Integer flowFilesQueued) {
+        this.flowFilesQueued = flowFilesQueued;
+    }
+
+    @ApiModelProperty("The number of bytes that are queued up in this ProcessGroup right now")
+    public Long getBytesQueued() {
+        return bytesQueued;
+    }
+
+    public void setBytesQueued(Long bytesQueued) {
+        this.bytesQueued = bytesQueued;
+    }
+
+    @ApiModelProperty("The number of bytes read by components in this ProcessGroup in the last 5 minutes")
+    public Long getBytesRead() {
+        return bytesRead;
+    }
+
+    public void setBytesRead(Long bytesRead) {
+        this.bytesRead = bytesRead;
+    }
+
+    @ApiModelProperty("The number of bytes written by components in this ProcessGroup in the last 5 minutes")
+    public Long getBytesWritten() {
+        return bytesWritten;
+    }
+
+    public void setBytesWritten(Long bytesWritten) {
+        this.bytesWritten = bytesWritten;
+    }
+
+    @ApiModelProperty("The number of FlowFiles transferred out of this ProcessGroup in the last 5 minutes")
+    public Integer getFlowFilesOut() {
+        return flowFilesOut;
+    }
+
+    public void setFlowFilesOut(Integer flowFilesOut) {
+        this.flowFilesOut = flowFilesOut;
+    }
+
+    @ApiModelProperty("The number of bytes transferred out of this ProcessGroup in the last 5 minutes")
+    public Long getBytesOut() {
+        return bytesOut;
+    }
+
+    public void setBytesOut(Long bytesOut) {
+        this.bytesOut = bytesOut;
+    }
+
+    @ApiModelProperty("The number of FlowFiles transferred in this ProcessGroup in the last 5 minutes")
+    public Integer getFlowFilesTransferred() {
+        return flowFilesTransferred;
+    }
+
+    public void setFlowFilesTransferred(Integer flowFilesTransferred) {
+        this.flowFilesTransferred = flowFilesTransferred;
+    }
+
+    @ApiModelProperty("The number of bytes transferred in this ProcessGroup in the last 5 minutes")
+    public Long getBytesTransferred() {
+        return bytesTransferred;
+    }
+
+    public void setBytesTransferred(Long bytesTransferred) {
+        this.bytesTransferred = bytesTransferred;
+    }
+
+    @ApiModelProperty("The number of bytes received from external sources by components within this ProcessGroup in the last 5 minutes")
+    public Long getBytesReceived() {
+        return bytesReceived;
+    }
+
+    public void setBytesReceived(Long bytesReceived) {
+        this.bytesReceived = bytesReceived;
+    }
+
+    @ApiModelProperty("The number of bytes sent to an external sink by components within this ProcessGroup in the last 5 minutes")
+    public Long getBytesSent() {
+        return bytesSent;
+    }
+
+    public void setBytesSent(Long bytesSent) {
+        this.bytesSent = bytesSent;
+    }
+
+    @ApiModelProperty("The number of FlowFiles sent to an external sink by components within this ProcessGroup in the last 5 minutes")
+    public Integer getFlowFilesSent() {
+        return flowFilesSent;
+    }
+
+    public void setFlowFilesSent(Integer flowFilesSent) {
+        this.flowFilesSent = flowFilesSent;
+    }
+
+    @ApiModelProperty("The number of FlowFiles received from external sources by components within this ProcessGroup in the last 5 minutes")
+    public Integer getFlowFilesReceived() {
+        return flowFilesReceived;
+    }
+
+    public void setFlowFilesReceived(Integer flowFilesReceived) {
+        this.flowFilesReceived = flowFilesReceived;
+    }
+
+    public void setInput(String input) {
+        this.input = input;
+    }
+
+    public void setQueued(String queued) {
+        this.queued = queued;
+    }
+
+    public void setQueuedCount(String queuedCount) {
+        this.queuedCount = queuedCount;
+    }
+
+    public void setQueuedSize(String queuedSize) {
+        this.queuedSize = queuedSize;
+    }
+
+    public void setRead(String read) {
+        this.read = read;
+    }
+
+    public void setWritten(String written) {
+        this.written = written;
+    }
+
+    public void setOutput(String output) {
+        this.output = output;
+    }
+
+    public void setTransferred(String transferred) {
+        this.transferred = transferred;
+    }
+
+    public void setReceived(String received) {
+        this.received = received;
+    }
+
+    public void setSent(String sent) {
+        this.sent = sent;
+    }
+
+    @Override
+    public ProcessGroupStatusSnapshotDTO clone() {
+        final ProcessGroupStatusSnapshotDTO other = new ProcessGroupStatusSnapshotDTO();
+        other.setId(getId());
+        other.setName(getName());
+
+        other.setBytesIn(getBytesIn());
+        other.setFlowFilesIn(getFlowFilesIn());
+        other.setInput(getInput());
+
+        other.setBytesQueued(getBytesQueued());
+        other.setFlowFilesQueued(getFlowFilesQueued());
+        other.setQueued(getQueued());
+        other.setQueuedCount(getQueuedCount());
+        other.setQueuedSize(getQueuedSize());
+
+        other.setBytesRead(getBytesRead());
+        other.setRead(getRead());
+        other.setBytesWritten(getBytesWritten());
+        other.setWritten(getWritten());
+
+        other.setBytesOut(getBytesOut());
+        other.setFlowFilesOut(getFlowFilesOut());
+        other.setOutput(getOutput());
+
+        other.setBytesTransferred(getBytesTransferred());
+        other.setFlowFilesTransferred(getFlowFilesTransferred());
+        other.setTransferred(getTransferred());
+
+        other.setBytesReceived(getBytesReceived());
+        other.setFlowFilesReceived(getFlowFilesReceived());
+        other.setReceived(getReceived());
+        other.setBytesSent(getBytesSent());
+        other.setFlowFilesSent(getFlowFilesSent());
+        other.setSent(getSent());
+
+        other.setActiveThreadCount(getActiveThreadCount());
+
+        other.setConnectionStatusSnapshots(copy(getConnectionStatusSnapshots()));
+        other.setProcessorStatusSnapshots(copy(getProcessorStatusSnapshots()));
+        other.setRemoteProcessGroupStatusSnapshots(copy(getRemoteProcessGroupStatusSnapshots()));
+        other.setInputPortStatusSnapshots(copy(getInputPortStatusSnapshots()));
+        other.setOutputPortStatusSnapshots(copy(getOutputPortStatusSnapshots()));
+
+        if (processGroupStatus != null) {
+            final List<ProcessGroupStatusSnapshotDTO> childGroups = new ArrayList<>();
+            for (final ProcessGroupStatusSnapshotDTO procGroupStatus : processGroupStatus) {
+                childGroups.add(procGroupStatus.clone());
+            }
+            other.setProcessGroupStatusSnapshots(childGroups);
+        }
+
+        return other;
+    }
+
+    private <T> Collection<T> copy(final Collection<T> original) {
+        if (original == null) {
+            return null;
+        }
+
+        return new ArrayList<T>(original);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java
index 1899418..a4729c4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusDTO.java
@@ -14,40 +14,44 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto.status;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
 /**
  * DTO for serializing the status of a processor.
  */
 @XmlType(name = "processorStatus")
-public class ProcessorStatusDTO extends StatusDTO {
-
-    private String id;
+public class ProcessorStatusDTO implements Cloneable {
     private String groupId;
+    private String id;
     private String name;
     private String type;
     private String runStatus;
+    private Date statsLastRefreshed;
 
-    private String read;
-    private String written;
+    private ProcessorStatusSnapshotDTO aggregateSnapshot;
+    private List<NodeProcessorStatusSnapshotDTO> nodeSnapshots;
 
-    private String input;
-    private String output;
+    @ApiModelProperty("The unique ID of the process group that the Processor belongs to")
+    public String getGroupId() {
+        return groupId;
+    }
 
-    private String tasks;
-    private String tasksDuration;
-    private Integer activeThreadCount;
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
 
-    /* getters / setters */
-    /**
-     * @return The processor id
-     */
-    @ApiModelProperty(
-            value = "The id of the processor."
-    )
+    @ApiModelProperty("The unique ID of the Processor")
     public String getId() {
         return id;
     }
@@ -56,12 +60,7 @@ public class ProcessorStatusDTO extends StatusDTO {
         this.id = id;
     }
 
-    /**
-     * @return The processor name
-     */
-    @ApiModelProperty(
-            value = "The name of the prcessor."
-    )
+    @ApiModelProperty("The name of the Processor")
     public String getName() {
         return name;
     }
@@ -70,12 +69,7 @@ public class ProcessorStatusDTO extends StatusDTO {
         this.name = name;
     }
 
-    /**
-     * @return The processor type
-     */
-    @ApiModelProperty(
-            value = "The type of the processor."
-    )
+    @ApiModelProperty("The type of the Processor")
     public String getType() {
         return type;
     }
@@ -84,13 +78,7 @@ public class ProcessorStatusDTO extends StatusDTO {
         this.type = type;
     }
 
-    /**
-     * @return run status of this processor
-     */
-    @ApiModelProperty(
-            value = "The state of the processor.",
-            allowableValues = "RUNNING, STOPPED, DISABLED, INVALID"
-    )
+    @ApiModelProperty("The run status of the Processor")
     public String getRunStatus() {
         return runStatus;
     }
@@ -99,116 +87,54 @@ public class ProcessorStatusDTO extends StatusDTO {
         this.runStatus = runStatus;
     }
 
-    /**
-     * @return The total count and size of flow files that have been accepted in the last five minutes
-     */
-    @ApiModelProperty(
-            value = "The count/size of flowfiles that have been accepted in the last 5 minutes."
-    )
-    public String getInput() {
-        return input;
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    @ApiModelProperty("The timestamp of when the stats were last refreshed")
+    public Date getStatsLastRefreshed() {
+        return statsLastRefreshed;
     }
 
-    public void setInput(String input) {
-        this.input = input;
+    public void setStatsLastRefreshed(Date statsLastRefreshed) {
+        this.statsLastRefreshed = statsLastRefreshed;
     }
 
-    /**
-     * @return number of bytes read
-     */
-    @ApiModelProperty(
-            value = "The number of bytes read in the last 5 minutes."
-    )
-    public String getRead() {
-        return read;
+    @ApiModelProperty("A status snapshot that represents the aggregate stats of all nodes in the cluster. If the NiFi instance is "
+        + "a standalone instance, rather than a cluster, this represents the stats of the single instance.")
+    public ProcessorStatusSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
     }
 
-    public void setRead(String read) {
-        this.read = read;
+    public void setAggregateSnapshot(ProcessorStatusSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
     }
 
-    /**
-     * @return number of bytes written
-     */
-    @ApiModelProperty(
-            value = "The number of bytes written in the last 5 minutes."
-    )
-    public String getWritten() {
-        return written;
+    @ApiModelProperty("A status snapshot for each node in the cluster. If the NiFi instance is a standalone instance, rather than "
+        + "a cluster, this may be null.")
+    public List<NodeProcessorStatusSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
     }
 
-    public void setWritten(String written) {
-        this.written = written;
+    public void setNodeSnapshots(List<NodeProcessorStatusSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 
-    /**
-     * @return the ID of the Process Group to which this processor belongs.
-     */
-    @ApiModelProperty(
-            value = "The id of the parent process group to which the processor belongs."
-    )
-    public String getGroupId() {
-        return groupId;
-    }
+    @Override
+    public ProcessorStatusDTO clone() {
+        final ProcessorStatusDTO other = new ProcessorStatusDTO();
+        other.setGroupId(getGroupId());
+        other.setId(getId());
+        other.setName(getName());
+        other.setRunStatus(getRunStatus());
+        other.setType(getType());
+        other.setStatsLastRefreshed(getStatsLastRefreshed());
+        other.setAggregateSnapshot(getAggregateSnapshot().clone());
 
-    public void setGroupId(final String groupId) {
-        this.groupId = groupId;
-    }
-
-    /**
-     * @return The total count and size of flow files that have been processed in the last five minutes
-     */
-    @ApiModelProperty(
-            value = "The count/size of flowfiles that have been processed in the last 5 minutes."
-    )
-    public String getOutput() {
-        return output;
-    }
-
-    public void setOutput(String output) {
-        this.output = output;
-    }
-
-    /**
-     * @return number of threads currently running for this Processor
-     */
-    @ApiModelProperty(
-            value = "The number of threads currently executing in the processor."
-    )
-    public Integer getActiveThreadCount() {
-        return activeThreadCount;
-    }
-
-    public void setActiveThreadCount(Integer threadCount) {
-        this.activeThreadCount = threadCount;
-    }
-
-    /**
-     * @return number of task this connectable has had over the last 5 minutes
-     */
-    @ApiModelProperty(
-            value = "The total number of task this connectable has completed over the last 5 minutes."
-    )
-    public String getTasks() {
-        return tasks;
-    }
-
-    public void setTasks(String tasks) {
-        this.tasks = tasks;
-    }
-
-    /**
-     * @return total duration of all tasks for this connectable over the last 5 minutes
-     */
-    @ApiModelProperty(
-            value = "The total duration of all tasks for this connectable over the last 5 minutes."
-    )
-    public String getTasksDuration() {
-        return tasksDuration;
-    }
+        final List<NodeProcessorStatusSnapshotDTO> nodeStatuses = getNodeSnapshots();
+        final List<NodeProcessorStatusSnapshotDTO> nodeStatusClones = new ArrayList<>(nodeStatuses.size());
+        for (final NodeProcessorStatusSnapshotDTO status : nodeStatuses) {
+            nodeStatusClones.add(status.clone());
+        }
+        other.setNodeSnapshots(nodeStatusClones);
 
-    public void setTasksDuration(String tasksDuration) {
-        this.tasksDuration = tasksDuration;
+        return other;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java
new file mode 100644
index 0000000..032fb57
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/ProcessorStatusSnapshotDTO.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+/**
+ * DTO for serializing the status of a processor.
+ */
+@XmlType(name = "processorStatusSnapshot")
+public class ProcessorStatusSnapshotDTO implements Cloneable {
+
+    private String id;
+    private String groupId;
+    private String name;
+    private String type;
+    private String runStatus;
+
+    private Long bytesRead = 0L;
+    private Long bytesWritten = 0L;
+    private String read;
+    private String written;
+
+    private Integer flowFilesIn = 0;
+    private Long bytesIn = 0L;
+    private String input;
+
+    private Integer flowFilesOut = 0;
+    private Long bytesOut = 0L;
+    private String output;
+
+    private Integer taskCount = 0;
+    private Long tasksDurationNanos = 0L;
+    private String tasks;
+    private String tasksDuration;
+    private Integer activeThreadCount = 0;
+
+    /* getters / setters */
+    /**
+     * @return The processor id
+     */
+    @ApiModelProperty("The id of the processor.")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return The processor name
+     */
+    @ApiModelProperty("The name of the prcessor.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return The processor type
+     */
+    @ApiModelProperty("The type of the processor.")
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return run status of this processor
+     */
+    @ApiModelProperty(
+            value = "The state of the processor.",
+            allowableValues = "RUNNING, STOPPED, DISABLED, INVALID"
+    )
+    public String getRunStatus() {
+        return runStatus;
+    }
+
+    public void setRunStatus(String runStatus) {
+        this.runStatus = runStatus;
+    }
+
+    /**
+     * @return The total count and size of flow files that have been accepted in the last five minutes
+     */
+    @ApiModelProperty("The count/size of flowfiles that have been accepted in the last 5 minutes.")
+    public String getInput() {
+        return input;
+    }
+
+    public void setInput(String input) {
+        this.input = input;
+    }
+
+    /**
+     * @return number of bytes read
+     */
+    @ApiModelProperty("The number of bytes read in the last 5 minutes.")
+    public String getRead() {
+        return read;
+    }
+
+    public void setRead(String read) {
+        this.read = read;
+    }
+
+    /**
+     * @return number of bytes written
+     */
+    @ApiModelProperty("The number of bytes written in the last 5 minutes.")
+    public String getWritten() {
+        return written;
+    }
+
+    public void setWritten(String written) {
+        this.written = written;
+    }
+
+    /**
+     * @return the ID of the Process Group to which this processor belongs.
+     */
+    @ApiModelProperty("The id of the parent process group to which the processor belongs.")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(final String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * @return The total count and size of flow files that have been processed in the last five minutes
+     */
+    @ApiModelProperty("The count/size of flowfiles that have been processed in the last 5 minutes.")
+    public String getOutput() {
+        return output;
+    }
+
+    public void setOutput(String output) {
+        this.output = output;
+    }
+
+    /**
+     * @return number of threads currently running for this Processor
+     */
+    @ApiModelProperty("The number of threads currently executing in the processor.")
+    public Integer getActiveThreadCount() {
+        return activeThreadCount;
+    }
+
+    public void setActiveThreadCount(Integer threadCount) {
+        this.activeThreadCount = threadCount;
+    }
+
+    /**
+     * @return number of task this connectable has had over the last 5 minutes
+     */
+    @ApiModelProperty("The total number of task this connectable has completed over the last 5 minutes.")
+    public String getTasks() {
+        return tasks;
+    }
+
+    public void setTasks(String tasks) {
+        this.tasks = tasks;
+    }
+
+    /**
+     * @return total duration of all tasks for this connectable over the last 5 minutes
+     */
+    @ApiModelProperty("The total duration of all tasks for this connectable over the last 5 minutes.")
+    public String getTasksDuration() {
+        return tasksDuration;
+    }
+
+    public void setTasksDuration(String tasksDuration) {
+        this.tasksDuration = tasksDuration;
+    }
+
+    @ApiModelProperty("The number of bytes read by this Processor in the last 5 mintues")
+    public Long getBytesRead() {
+        return bytesRead;
+    }
+
+    public void setBytesRead(Long bytesRead) {
+        this.bytesRead = bytesRead;
+    }
+
+    @ApiModelProperty("The number of bytes written by this Processor in the last 5 minutes")
+    public Long getBytesWritten() {
+        return bytesWritten;
+    }
+
+    public void setBytesWritten(Long bytesWritten) {
+        this.bytesWritten = bytesWritten;
+    }
+
+    @ApiModelProperty("The number of FlowFiles that have been accepted in the last 5 minutes")
+    public Integer getFlowFilesIn() {
+        return flowFilesIn;
+    }
+
+    public void setFlowFilesIn(Integer flowFilesIn) {
+        this.flowFilesIn = flowFilesIn;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles that have been accepted in the last 5 minutes")
+    public Long getBytesIn() {
+        return bytesIn;
+    }
+
+    public void setBytesIn(Long bytesIn) {
+        this.bytesIn = bytesIn;
+    }
+
+    @ApiModelProperty("The number of FlowFiles transferred to a Connection in the last 5 minutes")
+    public Integer getFlowFilesOut() {
+        return flowFilesOut;
+    }
+
+    public void setFlowFilesOut(Integer flowFilesOut) {
+        this.flowFilesOut = flowFilesOut;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles transferred to a Connection in the last 5 minutes")
+    public Long getBytesOut() {
+        return bytesOut;
+    }
+
+    public void setBytesOut(Long bytesOut) {
+        this.bytesOut = bytesOut;
+    }
+
+    @ApiModelProperty("The number of times this Processor has run in the last 5 minutes")
+    public Integer getTaskCount() {
+        return taskCount;
+    }
+
+    public void setTaskCount(Integer taskCount) {
+        this.taskCount = taskCount;
+    }
+
+    @ApiModelProperty("The number of nanoseconds that this Processor has spent running in the last 5 minutes")
+    public Long getTasksDurationNanos() {
+        return tasksDurationNanos;
+    }
+
+    public void setTasksDurationNanos(Long taskNanos) {
+        this.tasksDurationNanos = taskNanos;
+    }
+
+    @Override
+    public ProcessorStatusSnapshotDTO clone() {
+        final ProcessorStatusSnapshotDTO other = new ProcessorStatusSnapshotDTO();
+        other.setId(getId());
+        other.setGroupId(getGroupId());
+        other.setName(getName());
+        other.setType(getType());
+
+        other.setRunStatus(getRunStatus());
+        other.setBytesRead(getBytesRead());
+        other.setBytesWritten(getBytesWritten());
+        other.setFlowFilesIn(getFlowFilesIn());
+        other.setBytesIn(getBytesIn());
+        other.setFlowFilesOut(getFlowFilesOut());
+        other.setBytesOut(getBytesOut());
+        other.setTaskCount(getTaskCount());
+        other.setTasksDuration(getTasksDuration());
+        other.setTasksDurationNanos(getTasksDurationNanos());
+        other.setActiveThreadCount(getActiveThreadCount());
+        other.setInput(getInput());
+        other.setOutput(getOutput());
+        other.setRead(getRead());
+        other.setWritten(getWritten());
+        other.setTasks(getTasks());
+
+        return other;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java
index 6778b0d..a6723c7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemotePortStatusDTO.java
@@ -23,7 +23,7 @@ import javax.xml.bind.annotation.XmlType;
  * The status of a Port on a remote NiFi instance.
  */
 @XmlType(name = "remotePortStatus")
-public class RemotePortStatusDTO {
+public class RemotePortStatusDTO implements Cloneable {
 
     private String id;
     private String connectionId;
@@ -101,4 +101,14 @@ public class RemotePortStatusDTO {
         this.running = running;
     }
 
+    @Override
+    public RemotePortStatusDTO clone() {
+        final RemotePortStatusDTO other = new RemotePortStatusDTO();
+        other.setId(getId());
+        other.setName(getName());
+        other.setConnectionId(getConnectionId());
+        other.setExists(getExists());
+        other.setRunning(getRunning());
+        return other;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java
index f556deb..62685b1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java
@@ -14,50 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.nifi.web.api.dto.status;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import java.util.Date;
 import java.util.List;
+
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
-/**
- * The status of a remote process group in this NiFi.
- */
-@XmlType(name = "remoteProcessGroupStatus")
-public class RemoteProcessGroupStatusDTO extends StatusDTO {
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
-    private String id;
+@XmlType(name = "remoteProcessGroupStatus")
+public class RemoteProcessGroupStatusDTO {
     private String groupId;
+    private String id;
     private String name;
     private String targetUri;
     private String transmissionStatus;
-    private Integer activeThreadCount;
+    private Date statsLastRefreshed;
 
     private List<String> authorizationIssues;
 
-    private String sent;
-    private String received;
+    private RemoteProcessGroupStatusSnapshotDTO aggregateSnapshot;
+    private List<NodeRemoteProcessGroupStatusSnapshotDTO> nodeSnapshots;
 
-    /**
-     * @return The id for the remote process group
-     */
-    @ApiModelProperty(
-            value = "The id of the remote process group."
-    )
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    /**
-     * @return id of the group this remote process group is in
-     */
-    @ApiModelProperty(
-            value = "The id of the parent process group the remote process group resides in."
-    )
+    @ApiModelProperty("The unique ID of the process group that the Processor belongs to")
     public String getGroupId() {
         return groupId;
     }
@@ -66,26 +49,16 @@ public class RemoteProcessGroupStatusDTO extends StatusDTO {
         this.groupId = groupId;
     }
 
-    /**
-     * @return URI of the target system
-     */
-    @ApiModelProperty(
-            value = "The URI of the target system."
-    )
-    public String getTargetUri() {
-        return targetUri;
+    @ApiModelProperty("The unique ID of the Processor")
+    public String getId() {
+        return id;
     }
 
-    public void setTargetUri(String targetUri) {
-        this.targetUri = targetUri;
+    public void setId(String id) {
+        this.id = id;
     }
 
-    /**
-     * @return name of this remote process group
-     */
-    @ApiModelProperty(
-            value = "The name of the remote process group."
-    )
+    @ApiModelProperty("The name of the remote process group.")
     public String getName() {
         return name;
     }
@@ -94,12 +67,7 @@ public class RemoteProcessGroupStatusDTO extends StatusDTO {
         this.name = name;
     }
 
-    /**
-     * @return transmission status of this remote process group
-     */
-    @ApiModelProperty(
-            value = "The transmission status of the remote process group."
-    )
+    @ApiModelProperty("The transmission status of the remote process group.")
     public String getTransmissionStatus() {
         return transmissionStatus;
     }
@@ -108,26 +76,8 @@ public class RemoteProcessGroupStatusDTO extends StatusDTO {
         this.transmissionStatus = transmissionStatus;
     }
 
-    /**
-     * @return number of active threads
-     */
-    @ApiModelProperty(
-            value = "The number of active threads for the remote process group."
-    )
-    public Integer getActiveThreadCount() {
-        return activeThreadCount;
-    }
-
-    public void setActiveThreadCount(Integer activeThreadCount) {
-        this.activeThreadCount = activeThreadCount;
-    }
 
-    /**
-     * @return any remote authorization issues for this remote process group
-     */
-    @ApiModelProperty(
-            value = "Any remote authorization issues for the remote process group."
-    )
+    @ApiModelProperty("Any remote authorization issues for the remote process group.")
     public List<String> getAuthorizationIssues() {
         return authorizationIssues;
     }
@@ -136,32 +86,49 @@ public class RemoteProcessGroupStatusDTO extends StatusDTO {
         this.authorizationIssues = authorizationIssues;
     }
 
-    /**
-     * @return Formatted description of the amount of data sent to this remote process group
-     */
-    @ApiModelProperty(
-            value = "The count/size of the flowfiles sent to the remote process group in the last 5 minutes."
-    )
-    public String getSent() {
-        return sent;
+    @ApiModelProperty("The URI of the target system.")
+    public String getTargetUri() {
+        return targetUri;
+    }
+
+    public void setTargetUri(String targetUri) {
+        this.targetUri = targetUri;
     }
 
-    public void setSent(String sent) {
-        this.sent = sent;
+    @ApiModelProperty("A status snapshot that represents the aggregate stats of all nodes in the cluster. If the NiFi instance is "
+        + "a standalone instance, rather than a cluster, this represents the stats of the single instance.")
+    public RemoteProcessGroupStatusSnapshotDTO getAggregateSnapshot() {
+        return aggregateSnapshot;
+    }
+
+    public void setAggregateSnapshot(RemoteProcessGroupStatusSnapshotDTO aggregateSnapshot) {
+        this.aggregateSnapshot = aggregateSnapshot;
+    }
+
+    @ApiModelProperty("A status snapshot for each node in the cluster. If the NiFi instance is a standalone instance, rather than "
+        + "a cluster, this may be null.")
+    public List<NodeRemoteProcessGroupStatusSnapshotDTO> getNodeSnapshots() {
+        return nodeSnapshots;
+    }
+
+    public void setNodeSnapshots(List<NodeRemoteProcessGroupStatusSnapshotDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
     }
 
     /**
-     * @return Formatted description of the amount of data received from this remote process group
+     * When the status for this process group was calculated.
+     *
+     * @return The the status was calculated
      */
+    @XmlJavaTypeAdapter(TimeAdapter.class)
     @ApiModelProperty(
-            value = "The count/size of the flowfiles received from the remote process group in the last 5 minutes."
+        value = "The time the status for the process group was last refreshed."
     )
-    public String getReceived() {
-        return received;
+    public Date getStatsLastRefreshed() {
+        return statsLastRefreshed;
     }
 
-    public void setReceived(String received) {
-        this.received = received;
+    public void setStatsLastRefreshed(Date statsLastRefreshed) {
+        this.statsLastRefreshed = statsLastRefreshed;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java
new file mode 100644
index 0000000..f0f0d7e
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto.status;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlType;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+
+/**
+ * The status of a remote process group in this NiFi.
+ */
+@XmlType(name = "remoteProcessGroupStatusSnapshot")
+public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable {
+
+    private String id;
+    private String groupId;
+    private String name;
+    private String targetUri;
+    private String transmissionStatus;
+    private Integer activeThreadCount;
+
+    private List<String> authorizationIssues;
+
+    private Integer flowFilesSent = 0;
+    private Long bytesSent = 0L;
+    private String sent;
+
+    private Integer flowFilesReceived = 0;
+    private Long bytesReceived = 0L;
+    private String received;
+
+    /**
+     * @return The id for the remote process group
+     */
+    @ApiModelProperty("The id of the remote process group.")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return id of the group this remote process group is in
+     */
+    @ApiModelProperty("The id of the parent process group the remote process group resides in.")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * @return URI of the target system
+     */
+    @ApiModelProperty("The URI of the target system.")
+    public String getTargetUri() {
+        return targetUri;
+    }
+
+    public void setTargetUri(String targetUri) {
+        this.targetUri = targetUri;
+    }
+
+    /**
+     * @return name of this remote process group
+     */
+    @ApiModelProperty("The name of the remote process group.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return transmission status of this remote process group
+     */
+    @ApiModelProperty("The transmission status of the remote process group.")
+    public String getTransmissionStatus() {
+        return transmissionStatus;
+    }
+
+    public void setTransmissionStatus(String transmissionStatus) {
+        this.transmissionStatus = transmissionStatus;
+    }
+
+    /**
+     * @return number of active threads
+     */
+    @ApiModelProperty("The number of active threads for the remote process group.")
+    public Integer getActiveThreadCount() {
+        return activeThreadCount;
+    }
+
+    public void setActiveThreadCount(Integer activeThreadCount) {
+        this.activeThreadCount = activeThreadCount;
+    }
+
+    /**
+     * @return any remote authorization issues for this remote process group
+     */
+    @ApiModelProperty("Any remote authorization issues for the remote process group.")
+    public List<String> getAuthorizationIssues() {
+        return authorizationIssues;
+    }
+
+    public void setAuthorizationIssues(List<String> authorizationIssues) {
+        this.authorizationIssues = authorizationIssues;
+    }
+
+    /**
+     * @return Formatted description of the amount of data sent to this remote process group
+     */
+    @ApiModelProperty("The count/size of the flowfiles sent to the remote process group in the last 5 minutes.")
+    public String getSent() {
+        return sent;
+    }
+
+    public void setSent(String sent) {
+        this.sent = sent;
+    }
+
+
+    /**
+     * @return Formatted description of the amount of data received from this remote process group
+     */
+    @ApiModelProperty("The count/size of the flowfiles received from the remote process group in the last 5 minutes.")
+    public String getReceived() {
+        return received;
+    }
+
+    public void setReceived(String received) {
+        this.received = received;
+    }
+
+    @ApiModelProperty("The number of FlowFiles sent to the remote process group in the last 5 minutes.")
+    public Integer getFlowFilesSent() {
+        return flowFilesSent;
+    }
+
+    public void setFlowFilesSent(Integer flowFilesSent) {
+        this.flowFilesSent = flowFilesSent;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles sent to the remote process group in the last 5 minutes.")
+    public Long getBytesSent() {
+        return bytesSent;
+    }
+
+    public void setBytesSent(Long bytesSent) {
+        this.bytesSent = bytesSent;
+    }
+
+    @ApiModelProperty("The number of FlowFiles received from the remote process group in the last 5 minutes.")
+    public Integer getFlowFilesReceived() {
+        return flowFilesReceived;
+    }
+
+    public void setFlowFilesReceived(Integer flowFilesReceived) {
+        this.flowFilesReceived = flowFilesReceived;
+    }
+
+    @ApiModelProperty("The size of the FlowFiles received from the remote process group in the last 5 minutes.")
+    public Long getBytesReceived() {
+        return bytesReceived;
+    }
+
+    public void setBytesReceived(Long bytesReceived) {
+        this.bytesReceived = bytesReceived;
+    }
+
+
+    @Override
+    public RemoteProcessGroupStatusSnapshotDTO clone() {
+        final RemoteProcessGroupStatusSnapshotDTO other = new RemoteProcessGroupStatusSnapshotDTO();
+        other.setId(getId());
+        other.setGroupId(getGroupId());
+        other.setName(getName());
+        other.setTargetUri(getTargetUri());
+        other.setTransmissionStatus(getTransmissionStatus());
+        other.setActiveThreadCount(getActiveThreadCount());
+        other.setAuthorizationIssues(getAuthorizationIssues() == null ? null : new ArrayList<String>(getAuthorizationIssues()));
+        other.setFlowFilesSent(getFlowFilesSent());
+        other.setBytesSent(getBytesSent());
+        other.setFlowFilesReceived(getFlowFilesReceived());
+        other.setBytesReceived(getBytesReceived());
+        other.setReceived(getReceived());
+        other.setSent(getSent());
+
+        return other;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusDTO.java
deleted file mode 100644
index 39b9c06..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusDTO.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.List;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.nifi.web.api.dto.BulletinDTO;
-
-/**
- * The status of a component in this NiFi.
- */
-@XmlType(name = "status")
-public abstract class StatusDTO {
-
-    private List<BulletinDTO> bulletins;
-
-    /**
-     * @return Bulletins for this component
-     */
-    @ApiModelProperty(
-            value = "The current bulletins for the component."
-    )
-    public List<BulletinDTO> getBulletins() {
-        return bulletins;
-    }
-
-    public void setBulletins(List<BulletinDTO> bulletins) {
-        this.bulletins = bulletins;
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDTO.java
index c0ef33b..3654e10 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDTO.java
@@ -17,33 +17,32 @@
 package org.apache.nifi.web.api.dto.status;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.util.Date;
 import java.util.LinkedHashMap;
 import java.util.List;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
 
 /**
- * History status for a component in this NiFi.
+ * DTO for serializing the status history of a single component across the cluster.
  */
 @XmlType(name = "statusHistory")
 public class StatusHistoryDTO {
 
     private Date generated;
 
-    private LinkedHashMap<String, String> details;
-
+    private LinkedHashMap<String, String> componentDetails;
     private List<StatusDescriptorDTO> fieldDescriptors;
-    private List<StatusSnapshotDTO> statusSnapshots;
+    private List<StatusSnapshotDTO> aggregateSnapshots;
+    private List<NodeStatusSnapshotsDTO> nodeSnapshots;
 
     /**
      * @return when this status history was generated
      */
     @XmlJavaTypeAdapter(TimeAdapter.class)
-    @ApiModelProperty(
-            value = "The timestamp when the status history was generated."
-    )
+    @ApiModelProperty("When the status history was generated.")
     public Date getGenerated() {
         return generated;
     }
@@ -53,25 +52,18 @@ public class StatusHistoryDTO {
     }
 
     /**
-     * @return The component details for this status history
+     * @return key/value pairs that describe the component that the status history belongs to
      */
-    @ApiModelProperty(
-            value = "The component details for the status history."
-    )
-    public LinkedHashMap<String, String> getDetails() {
-        return details;
+    @ApiModelProperty("A Map of key/value pairs that describe the component that the status history belongs to")
+    public LinkedHashMap<String, String> getComponentDetails() {
+        return componentDetails;
     }
 
-    public void setDetails(LinkedHashMap<String, String> details) {
-        this.details = details;
+    public void setComponentDetails(LinkedHashMap<String, String> componentDetails) {
+        this.componentDetails = componentDetails;
     }
 
-    /**
-     * @return Descriptors for each supported status field
-     */
-    @ApiModelProperty(
-            value = "The descriptor for each support status field."
-    )
+    @ApiModelProperty("The Descriptors that provide information on each of the metrics provided in the status history")
     public List<StatusDescriptorDTO> getFieldDescriptors() {
         return fieldDescriptors;
     }
@@ -80,18 +72,24 @@ public class StatusHistoryDTO {
         this.fieldDescriptors = fieldDescriptors;
     }
 
-    /**
-     * @return The status snapshots
-     */
-    @ApiModelProperty(
-            value = "The status snapshots."
-    )
-    public List<StatusSnapshotDTO> getStatusSnapshots() {
-        return statusSnapshots;
+    @ApiModelProperty("A list of StatusSnapshotDTO objects that provide the actual metric values for the component. If the NiFi instance "
+        + "is clustered, this will represent the aggregate status across all nodes. If the NiFi instance is not clustered, this will represent "
+        + "the status of the entire NiFi instance.")
+    public List<StatusSnapshotDTO> getAggregateSnapshots() {
+        return aggregateSnapshots;
     }
 
-    public void setStatusSnapshots(List<StatusSnapshotDTO> statusSnapshots) {
-        this.statusSnapshots = statusSnapshots;
+    public void setAggregateSnapshots(List<StatusSnapshotDTO> aggregateSnapshots) {
+        this.aggregateSnapshots = aggregateSnapshots;
     }
 
+    @ApiModelProperty("The NodeStatusSnapshotsDTO objects that provide the actual metric values for the component, for each node. "
+        + "If the NiFi instance is not clustered, this value will be null.")
+    public List<NodeStatusSnapshotsDTO> getNodeSnapshots() {
+        return nodeSnapshots;
+    }
+
+    public void setNodeSnapshots(List<NodeStatusSnapshotsDTO> nodeSnapshots) {
+        this.nodeSnapshots = nodeSnapshots;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDetailDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDetailDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDetailDTO.java
deleted file mode 100644
index e78641e..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/StatusHistoryDetailDTO.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.dto.status;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
-import javax.xml.bind.annotation.XmlType;
-
-/**
- * Detail of a status history metric.
- */
-@XmlType(name = "statusHistoryDetail")
-public class StatusHistoryDetailDTO {
-
-    private String label;
-    private String value;
-
-    /**
-     * @return label for this status detail
-     */
-    @ApiModelProperty(
-            value = "The label for the status detail."
-    )
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-    /**
-     * @return value for this status detail
-     */
-    @ApiModelProperty(
-            value = "The value for the status detail."
-    )
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterConnectionStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterConnectionStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterConnectionStatusEntity.java
deleted file mode 100644
index f211cc4..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterConnectionStatusEntity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.entity;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.nifi.web.api.dto.status.ClusterConnectionStatusDTO;
-
-/**
- * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ClusterConnectionStatusDTO.
- */
-@XmlRootElement(name = "clusterConnectionStatusEntity")
-public class ClusterConnectionStatusEntity extends Entity {
-
-    private ClusterConnectionStatusDTO clusterConnectionStatus;
-
-    /**
-     * The ClusterConnectionStatusDTO that is being serialized.
-     *
-     * @return The ClusterConnectionStatusDTO object
-     */
-    public ClusterConnectionStatusDTO getClusterConnectionStatus() {
-        return clusterConnectionStatus;
-    }
-
-    public void setClusterConnectionStatus(ClusterConnectionStatusDTO clusterConnectionStatus) {
-        this.clusterConnectionStatus = clusterConnectionStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessGroupStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessGroupStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessGroupStatusEntity.java
deleted file mode 100644
index f8b7e11..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessGroupStatusEntity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.entity;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.nifi.web.api.dto.status.ClusterProcessGroupStatusDTO;
-
-/**
- * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ClusterProcessGroupStatusDTO.
- */
-@XmlRootElement(name = "clusterProcessGroupStatusEntity")
-public class ClusterProcessGroupStatusEntity extends Entity {
-
-    private ClusterProcessGroupStatusDTO clusterProcessGroupStatus;
-
-    /**
-     * The ClusterProcessGroupStatusDTO that is being serialized.
-     *
-     * @return The ClusterProcessGroupStatusDTO object
-     */
-    public ClusterProcessGroupStatusDTO getClusterProcessGroupStatus() {
-        return clusterProcessGroupStatus;
-    }
-
-    public void setClusterProcessGroupStatus(ClusterProcessGroupStatusDTO clusterProcessGroupStatus) {
-        this.clusterProcessGroupStatus = clusterProcessGroupStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessorStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessorStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessorStatusEntity.java
deleted file mode 100644
index 2b8220f..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterProcessorStatusEntity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.entity;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.nifi.web.api.dto.status.ClusterProcessorStatusDTO;
-
-/**
- * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ClusterProcessorStatusDTO.
- */
-@XmlRootElement(name = "clusterProcessorStatusEntity")
-public class ClusterProcessorStatusEntity extends Entity {
-
-    private ClusterProcessorStatusDTO clusterProcessorStatus;
-
-    /**
-     * The ClusterProcessorStatusDTO that is being serialized.
-     *
-     * @return The ClusterProcessorStatusDTO object
-     */
-    public ClusterProcessorStatusDTO getClusterProcessorStatus() {
-        return clusterProcessorStatus;
-    }
-
-    public void setClusterProcessorStatus(ClusterProcessorStatusDTO clusterProcessorStatus) {
-        this.clusterProcessorStatus = clusterProcessorStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterRemoteProcessGroupStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterRemoteProcessGroupStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterRemoteProcessGroupStatusEntity.java
deleted file mode 100644
index 66569c5..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterRemoteProcessGroupStatusEntity.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.entity;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.nifi.web.api.dto.status.ClusterRemoteProcessGroupStatusDTO;
-
-/**
- * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a
- * ClusterRemoteProcessGroupStatusDTO.
- */
-@XmlRootElement(name = "clusterRemoteProcessGroupStatusEntity")
-public class ClusterRemoteProcessGroupStatusEntity extends Entity {
-
-    private ClusterRemoteProcessGroupStatusDTO clusterRemoteProcessGroupStatus;
-
-    /**
-     * The ClusterRemoteProcessGroupStatusDTO that is being serialized.
-     *
-     * @return The ClusterRemoteProcessGroupStatusDTO object
-     */
-    public ClusterRemoteProcessGroupStatusDTO getClusterRemoteProcessGroupStatus() {
-        return clusterRemoteProcessGroupStatus;
-    }
-
-    public void setClusterRemoteProcessGroupStatus(ClusterRemoteProcessGroupStatusDTO clusterRemoteProcessGroupStatus) {
-        this.clusterRemoteProcessGroupStatus = clusterRemoteProcessGroupStatus;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterStatusHistoryEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterStatusHistoryEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterStatusHistoryEntity.java
deleted file mode 100644
index b13984a..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ClusterStatusHistoryEntity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.entity;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.nifi.web.api.dto.status.ClusterStatusHistoryDTO;
-
-/**
- * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ClusterStatusHistoryDTO.
- */
-@XmlRootElement(name = "clusterStatusHistoryEntity")
-public class ClusterStatusHistoryEntity extends Entity {
-
-    private ClusterStatusHistoryDTO clusterStatusHistory;
-
-    /**
-     * The ClusterStatusHistoryDTO that is being serialized.
-     *
-     * @return The ClusterStatusHistoryDTO object
-     */
-    public ClusterStatusHistoryDTO getClusterStatusHistory() {
-        return clusterStatusHistory;
-    }
-
-    public void setClusterStatusHistory(ClusterStatusHistoryDTO clusterStatusHistory) {
-        this.clusterStatusHistory = clusterStatusHistory;
-    }
-
-}


[12/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java
new file mode 100644
index 0000000..8b62331
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionStatusEntity.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ConnectionStatusDTO.
+ */
+@XmlRootElement(name = "connectionStatusEntity")
+public class ConnectionStatusEntity extends Entity {
+
+    private ConnectionStatusDTO connectionStatus;
+
+    /**
+     * The ConnectionStatusDTO that is being serialized.
+     *
+     * @return The ConnectionStatusDTO object
+     */
+    public ConnectionStatusDTO getConnectionStatus() {
+        return connectionStatus;
+    }
+
+    public void setConnectionStatus(ConnectionStatusDTO connectionStatus) {
+        this.connectionStatus = connectionStatus;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/NodeSystemDiagnosticsEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/NodeSystemDiagnosticsEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/NodeSystemDiagnosticsEntity.java
deleted file mode 100644
index 443276c..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/NodeSystemDiagnosticsEntity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.web.api.entity;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.nifi.web.api.dto.NodeSystemDiagnosticsDTO;
-
-/**
- * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a NodeSystemDiagnosticsDTO.
- */
-@XmlRootElement(name = "nodeSystemDiagnosticsEntity")
-public class NodeSystemDiagnosticsEntity extends Entity {
-
-    private NodeSystemDiagnosticsDTO nodeSystemDiagnostics;
-
-    /**
-     * The NodeSystemDiagnosticsDTO that is being serialized.
-     *
-     * @return The NodeSystemDiagnosticsDTO object
-     */
-    public NodeSystemDiagnosticsDTO getNodeSystemDiagnostics() {
-        return nodeSystemDiagnostics;
-    }
-
-    public void setNodeSystemDiagnostics(NodeSystemDiagnosticsDTO nodeSystemDiagnostics) {
-        this.nodeSystemDiagnostics = nodeSystemDiagnostics;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java
new file mode 100644
index 0000000..e0b49c4
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/PortStatusEntity.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a PortStatusDTO.
+ */
+@XmlRootElement(name = "portStatusEntity")
+public class PortStatusEntity extends Entity {
+
+    private PortStatusDTO portStatus;
+
+    /**
+     * The PortStatusDTO that is being serialized.
+     *
+     * @return The PortStatusDTO object
+     */
+    public PortStatusDTO getPortStatus() {
+        return portStatus;
+    }
+
+    public void setPortStatus(PortStatusDTO portStatus) {
+        this.portStatus = portStatus;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java
new file mode 100644
index 0000000..0c2170c
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorStatusEntity.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessorStatusDTO.
+ */
+@XmlRootElement(name = "processorStatusEntity")
+public class ProcessorStatusEntity extends Entity {
+
+    private ProcessorStatusDTO processorStatus;
+
+    /**
+     * The ProcessorStatusDTO that is being serialized.
+     *
+     * @return The ProcessorStatusDTO object
+     */
+    public ProcessorStatusDTO getProcessorStatus() {
+        return processorStatus;
+    }
+
+    public void setProcessorStatus(ProcessorStatusDTO processorStatus) {
+        this.processorStatus = processorStatus;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java
new file mode 100644
index 0000000..a5031ab
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RemoteProcessGroupStatusEntity.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a RemoteProcessGroupStatusDTO.
+ */
+@XmlRootElement(name = "remoteProcessGroupStatusEntity")
+public class RemoteProcessGroupStatusEntity extends Entity {
+
+    private RemoteProcessGroupStatusDTO remoteProcessGroupStatus;
+
+    /**
+     * The RemoteProcessGroupStatusDTO that is being serialized.
+     *
+     * @return The RemoteProcessGroupStatusDTO object
+     */
+    public RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus() {
+        return remoteProcessGroupStatus;
+    }
+
+    public void setRemoteProcessGroupStatus(RemoteProcessGroupStatusDTO remoteProcessGroupStatus) {
+        this.remoteProcessGroupStatus = remoteProcessGroupStatus;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/NodeProtocolSender.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/NodeProtocolSender.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/NodeProtocolSender.java
index f3e5df4..be0c339 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/NodeProtocolSender.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/NodeProtocolSender.java
@@ -20,7 +20,6 @@ import org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage;
 import org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage;
 import org.apache.nifi.cluster.protocol.message.ControllerStartupFailureMessage;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
-import org.apache.nifi.cluster.protocol.message.NodeBulletinsMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionFailureMessage;
 
 /**
@@ -52,15 +51,6 @@ public interface NodeProtocolSender {
     void heartbeat(HeartbeatMessage msg) throws ProtocolException, UnknownServiceAddressException;
 
     /**
-     * Sends a bulletins message to the cluster manager.
-     *
-     * @param msg a message
-     * @throws ProtocolException pe
-     * @throws UnknownServiceAddressException ex
-     */
-    void sendBulletins(NodeBulletinsMessage msg) throws ProtocolException, UnknownServiceAddressException;
-
-    /**
      * Sends a failure notification if the controller was unable start.
      *
      * @param msg a message

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderImpl.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderImpl.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderImpl.java
index 993dea5..9ae6182 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderImpl.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderImpl.java
@@ -32,7 +32,6 @@ import org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage;
 import org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage;
 import org.apache.nifi.cluster.protocol.message.ControllerStartupFailureMessage;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
-import org.apache.nifi.cluster.protocol.message.NodeBulletinsMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage.MessageType;
 import org.apache.nifi.cluster.protocol.message.ReconnectionFailureMessage;
@@ -117,11 +116,6 @@ public class NodeProtocolSenderImpl implements NodeProtocolSender {
     }
 
     @Override
-    public void sendBulletins(NodeBulletinsMessage msg) throws ProtocolException, UnknownServiceAddressException {
-        sendProtocolMessage(msg);
-    }
-
-    @Override
     public void notifyControllerStartupFailure(final ControllerStartupFailureMessage msg) throws ProtocolException, UnknownServiceAddressException {
         sendProtocolMessage(msg);
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderListener.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderListener.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderListener.java
index 2992e38..0a9a064 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderListener.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/impl/NodeProtocolSenderListener.java
@@ -24,7 +24,6 @@ import org.apache.nifi.cluster.protocol.ProtocolException;
 import org.apache.nifi.cluster.protocol.ProtocolHandler;
 import org.apache.nifi.cluster.protocol.ProtocolListener;
 import org.apache.nifi.cluster.protocol.UnknownServiceAddressException;
-import org.apache.nifi.cluster.protocol.message.NodeBulletinsMessage;
 import org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage;
 import org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage;
 import org.apache.nifi.cluster.protocol.message.ControllerStartupFailureMessage;
@@ -104,11 +103,6 @@ public class NodeProtocolSenderListener implements NodeProtocolSender, ProtocolL
     }
 
     @Override
-    public void sendBulletins(NodeBulletinsMessage msg) throws ProtocolException, UnknownServiceAddressException {
-        sender.sendBulletins(msg);
-    }
-
-    @Override
     public void setBulletinRepository(final BulletinRepository bulletinRepository) {
         listener.setBulletinRepository(bulletinRepository);
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
index f0a9fa7..516b67e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/message/ObjectFactory.java
@@ -26,7 +26,6 @@ import org.apache.nifi.cluster.protocol.message.FlowRequestMessage;
 import org.apache.nifi.cluster.protocol.message.FlowResponseMessage;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
 import org.apache.nifi.cluster.protocol.message.MulticastProtocolMessage;
-import org.apache.nifi.cluster.protocol.message.NodeBulletinsMessage;
 import org.apache.nifi.cluster.protocol.message.PingMessage;
 import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ReconnectionFailureMessage;
@@ -97,8 +96,4 @@ public class ObjectFactory {
     public PrimaryRoleAssignmentMessage createPrimaryRoleAssignmentMessage() {
         return new PrimaryRoleAssignmentMessage();
     }
-
-    public NodeBulletinsMessage createBulletinsMessage() {
-        return new NodeBulletinsMessage();
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/NodeBulletinsMessage.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/NodeBulletinsMessage.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/NodeBulletinsMessage.java
deleted file mode 100644
index 6df3ba4..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/NodeBulletinsMessage.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.cluster.protocol.message;
-
-import org.apache.nifi.cluster.protocol.NodeBulletins;
-import javax.xml.bind.annotation.XmlRootElement;
-
-/**
- */
-@XmlRootElement(name = "nodeBulletinsMessage")
-public class NodeBulletinsMessage extends ProtocolMessage {
-
-    private NodeBulletins bulletins;
-
-    @Override
-    public MessageType getType() {
-        return MessageType.BULLETINS;
-    }
-
-    public NodeBulletins getBulletins() {
-        return bulletins;
-    }
-
-    public void setBulletins(NodeBulletins bulletins) {
-        this.bulletins = bulletins;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
index c6f7ce0..f01efd8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/message/ProtocolMessage.java
@@ -21,8 +21,6 @@ public abstract class ProtocolMessage {
     private volatile String requestorDN;
 
     public static enum MessageType {
-
-        BULLETINS,
         CONNECTION_REQUEST,
         CONNECTION_RESPONSE,
         CONTROLLER_STARTUP_FAILURE,

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
index 336d675..51de54b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/ClusterManager.java
@@ -33,8 +33,6 @@ import org.apache.nifi.cluster.protocol.ConnectionRequest;
 import org.apache.nifi.cluster.protocol.ConnectionResponse;
 import org.apache.nifi.cluster.protocol.Heartbeat;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.diagnostics.SystemDiagnostics;
 import org.apache.nifi.remote.cluster.NodeInformant;
 import org.apache.nifi.reporting.BulletinRepository;
 
@@ -168,15 +166,4 @@ public interface ClusterManager extends NodeInformant {
      * @return the bulletin repository
      */
     BulletinRepository getBulletinRepository();
-
-    /**
-     * @param groupId groupId
-     * @return a {@link ProcessGroupStatus} that represents the status of all nodes with the given {@link Status}es for the given ProcessGroup id, or null if no nodes exist with the given statuses
-     */
-    ProcessGroupStatus getProcessGroupStatus(String groupId);
-
-    /**
-     * @return a merged representation of the System Diagnostics for all nodes in the cluster
-     */
-    SystemDiagnostics getSystemDiagnostics();
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java
new file mode 100644
index 0000000..66ad494
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java
@@ -0,0 +1,646 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.cluster.manager;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.nifi.controller.status.RunStatus;
+import org.apache.nifi.controller.status.TransmissionStatus;
+import org.apache.nifi.util.FormatUtils;
+import org.apache.nifi.web.api.dto.BulletinDTO;
+import org.apache.nifi.web.api.dto.CounterDTO;
+import org.apache.nifi.web.api.dto.CountersDTO;
+import org.apache.nifi.web.api.dto.CountersSnapshotDTO;
+import org.apache.nifi.web.api.dto.NodeCountersSnapshotDTO;
+import org.apache.nifi.web.api.dto.NodeSystemDiagnosticsSnapshotDTO;
+import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
+import org.apache.nifi.web.api.dto.SystemDiagnosticsSnapshotDTO;
+import org.apache.nifi.web.api.dto.SystemDiagnosticsSnapshotDTO.GarbageCollectionDTO;
+import org.apache.nifi.web.api.dto.SystemDiagnosticsSnapshotDTO.StorageUsageDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.ControllerStatusDTO;
+import org.apache.nifi.web.api.dto.status.NodeConnectionStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodePortStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeProcessorStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeRemoteProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
+
+public class StatusMerger {
+    public static void merge(final ControllerStatusDTO target, final ControllerStatusDTO toMerge) {
+        if (target == null || toMerge == null) {
+            return;
+        }
+
+        target.setActiveRemotePortCount(target.getActiveRemotePortCount() + toMerge.getActiveRemotePortCount());
+        target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount());
+        target.setBytesQueued(target.getBytesQueued() + toMerge.getBytesQueued());
+        target.setDisabledCount(target.getDisabledCount() + toMerge.getDisabledCount());
+        target.setFlowFilesQueued(target.getFlowFilesQueued() + toMerge.getFlowFilesQueued());
+        target.setInactiveRemotePortCount(target.getInactiveRemotePortCount() + toMerge.getInactiveRemotePortCount());
+        target.setInvalidCount(target.getInvalidCount() + toMerge.getInvalidCount());
+        target.setRunningCount(target.getRunningCount() + toMerge.getRunningCount());
+        target.setStoppedCount(target.getStoppedCount() + toMerge.getStoppedCount());
+
+        target.setBulletins(mergeBulletins(target.getBulletins(), toMerge.getBulletins()));
+        target.setControllerServiceBulletins(mergeBulletins(target.getControllerServiceBulletins(), toMerge.getControllerServiceBulletins()));
+        target.setReportingTaskBulletins(mergeBulletins(target.getReportingTaskBulletins(), toMerge.getReportingTaskBulletins()));
+
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final ControllerStatusDTO target) {
+        target.setQueued(prettyPrint(target.getFlowFilesQueued(), target.getBytesQueued()));
+        target.setConnectedNodes(formatCount(target.getConnectedNodeCount()) + " / " + formatCount(target.getTotalNodeCount()));
+    }
+
+    public static List<BulletinDTO> mergeBulletins(final List<BulletinDTO> targetBulletins, final List<BulletinDTO> toMerge) {
+        final List<BulletinDTO> bulletins = new ArrayList<>();
+        if (targetBulletins != null) {
+            bulletins.addAll(targetBulletins);
+        }
+
+        if (toMerge != null) {
+            bulletins.addAll(toMerge);
+        }
+
+        return bulletins;
+    }
+
+
+    public static void merge(final ProcessGroupStatusDTO target, final ProcessGroupStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        if (target.getNodeSnapshots() != null) {
+            final NodeProcessGroupStatusSnapshotDTO nodeSnapshot = new NodeProcessGroupStatusSnapshotDTO();
+            nodeSnapshot.setStatusSnapshot(toMerge.getAggregateSnapshot());
+            nodeSnapshot.setAddress(nodeAddress);
+            nodeSnapshot.setApiPort(nodeApiPort);
+            nodeSnapshot.setNodeId(nodeId);
+
+            target.getNodeSnapshots().add(nodeSnapshot);
+        }
+    }
+
+    public static void merge(final ProcessGroupStatusSnapshotDTO target, final ProcessGroupStatusSnapshotDTO toMerge) {
+        if (target == null || toMerge == null) {
+            return;
+        }
+
+        target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());
+        target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
+
+        target.setBytesQueued(target.getBytesQueued() + toMerge.getBytesQueued());
+        target.setFlowFilesQueued(target.getFlowFilesQueued() + toMerge.getFlowFilesQueued());
+
+        target.setBytesRead(target.getBytesRead() + toMerge.getBytesRead());
+        target.setBytesWritten(target.getBytesWritten() + toMerge.getBytesWritten());
+
+        target.setBytesOut(target.getBytesOut() + toMerge.getBytesOut());
+        target.setFlowFilesOut(target.getFlowFilesOut() + toMerge.getFlowFilesOut());
+
+        target.setBytesTransferred(target.getBytesTransferred() + toMerge.getBytesTransferred());
+        target.setFlowFilesTransferred(target.getFlowFilesTransferred() + toMerge.getFlowFilesTransferred());
+
+        target.setBytesReceived(target.getBytesReceived() + toMerge.getBytesReceived());
+        target.setFlowFilesReceived(target.getFlowFilesReceived() + toMerge.getFlowFilesReceived());
+
+        target.setBytesSent(target.getBytesSent() + toMerge.getBytesSent());
+        target.setFlowFilesSent(target.getFlowFilesSent() + toMerge.getFlowFilesSent());
+
+        target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount());
+        updatePrettyPrintedFields(target);
+
+        // connection status
+        // sort by id
+        final Map<String, ConnectionStatusSnapshotDTO> mergedConnectionMap = new HashMap<>();
+        for (final ConnectionStatusSnapshotDTO status : replaceNull(target.getConnectionStatusSnapshots())) {
+            mergedConnectionMap.put(status.getId(), status);
+        }
+
+        for (final ConnectionStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getConnectionStatusSnapshots())) {
+            ConnectionStatusSnapshotDTO merged = mergedConnectionMap.get(statusToMerge.getId());
+            if (merged == null) {
+                mergedConnectionMap.put(statusToMerge.getId(), statusToMerge.clone());
+                continue;
+            }
+
+            merge(merged, statusToMerge);
+        }
+        target.setConnectionStatusSnapshots(mergedConnectionMap.values());
+
+        // processor status
+        final Map<String, ProcessorStatusSnapshotDTO> mergedProcessorMap = new HashMap<>();
+        for (final ProcessorStatusSnapshotDTO status : replaceNull(target.getProcessorStatusSnapshots())) {
+            mergedProcessorMap.put(status.getId(), status);
+        }
+
+        for (final ProcessorStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getProcessorStatusSnapshots())) {
+            ProcessorStatusSnapshotDTO merged = mergedProcessorMap.get(statusToMerge.getId());
+            if (merged == null) {
+                mergedProcessorMap.put(statusToMerge.getId(), statusToMerge.clone());
+                continue;
+            }
+
+            merge(merged, statusToMerge);
+        }
+        target.setProcessorStatusSnapshots(mergedProcessorMap.values());
+
+
+        // input ports
+        final Map<String, PortStatusSnapshotDTO> mergedInputPortMap = new HashMap<>();
+        for (final PortStatusSnapshotDTO status : replaceNull(target.getInputPortStatusSnapshots())) {
+            mergedInputPortMap.put(status.getId(), status);
+        }
+
+        for (final PortStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getInputPortStatusSnapshots())) {
+            PortStatusSnapshotDTO merged = mergedInputPortMap.get(statusToMerge.getId());
+            if (merged == null) {
+                mergedInputPortMap.put(statusToMerge.getId(), statusToMerge.clone());
+                continue;
+            }
+
+            merge(merged, statusToMerge);
+        }
+        target.setInputPortStatusSnapshots(mergedInputPortMap.values());
+
+        // output ports
+        final Map<String, PortStatusSnapshotDTO> mergedOutputPortMap = new HashMap<>();
+        for (final PortStatusSnapshotDTO status : replaceNull(target.getOutputPortStatusSnapshots())) {
+            mergedOutputPortMap.put(status.getId(), status);
+        }
+
+        for (final PortStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getOutputPortStatusSnapshots())) {
+            PortStatusSnapshotDTO merged = mergedOutputPortMap.get(statusToMerge.getId());
+            if (merged == null) {
+                mergedOutputPortMap.put(statusToMerge.getId(), statusToMerge.clone());
+                continue;
+            }
+
+            merge(merged, statusToMerge);
+        }
+        target.setOutputPortStatusSnapshots(mergedOutputPortMap.values());
+
+        // child groups
+        final Map<String, ProcessGroupStatusSnapshotDTO> mergedGroupMap = new HashMap<>();
+        for (final ProcessGroupStatusSnapshotDTO status : replaceNull(target.getProcessGroupStatusSnapshots())) {
+            mergedGroupMap.put(status.getId(), status);
+        }
+
+        for (final ProcessGroupStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getProcessGroupStatusSnapshots())) {
+            ProcessGroupStatusSnapshotDTO merged = mergedGroupMap.get(statusToMerge.getId());
+            if (merged == null) {
+                mergedGroupMap.put(statusToMerge.getId(), statusToMerge.clone());
+                continue;
+            }
+
+            merge(merged, statusToMerge);
+        }
+        target.setOutputPortStatusSnapshots(mergedOutputPortMap.values());
+
+        // remote groups
+        final Map<String, RemoteProcessGroupStatusSnapshotDTO> mergedRemoteGroupMap = new HashMap<>();
+        for (final RemoteProcessGroupStatusSnapshotDTO status : replaceNull(target.getRemoteProcessGroupStatusSnapshots())) {
+            mergedRemoteGroupMap.put(status.getId(), status);
+        }
+
+        for (final RemoteProcessGroupStatusSnapshotDTO statusToMerge : replaceNull(toMerge.getRemoteProcessGroupStatusSnapshots())) {
+            RemoteProcessGroupStatusSnapshotDTO merged = mergedRemoteGroupMap.get(statusToMerge.getId());
+            if (merged == null) {
+                mergedRemoteGroupMap.put(statusToMerge.getId(), statusToMerge.clone());
+                continue;
+            }
+
+            merge(merged, statusToMerge);
+        }
+        target.setRemoteProcessGroupStatusSnapshots(mergedRemoteGroupMap.values());
+    }
+
+    private static <T> Collection<T> replaceNull(final Collection<T> collection) {
+        return (collection == null) ? Collections.<T> emptyList() : collection;
+    }
+
+
+    /**
+     * Updates the fields that are "pretty printed" based on the raw values currently set. For example,
+     * {@link ProcessGroupStatusSnapshotDTO#setInput(String)} will be called with the pretty-printed form of the
+     * FlowFile counts and sizes retrieved via {@link ProcessGroupStatusSnapshotDTO#getFlowFilesIn()} and
+     * {@link ProcessGroupStatusSnapshotDTO#getBytesIn()}.
+     *
+     * This logic is performed here, rather than in the DTO itself because the DTO needs to be kept purely
+     * getters & setters - otherwise the automatic marshalling and unmarshalling to/from JSON becomes very
+     * complicated.
+     *
+     * @param target the DTO to update
+     */
+    public static void updatePrettyPrintedFields(final ProcessGroupStatusSnapshotDTO target) {
+        target.setQueued(prettyPrint(target.getFlowFilesQueued(), target.getBytesQueued()));
+        target.setQueuedCount(formatCount(target.getFlowFilesQueued()));
+        target.setQueuedSize(formatDataSize(target.getBytesQueued()));
+        target.setInput(prettyPrint(target.getFlowFilesIn(), target.getBytesIn()));
+        target.setRead(formatDataSize(target.getBytesRead()));
+        target.setWritten(formatDataSize(target.getBytesWritten()));
+        target.setOutput(prettyPrint(target.getFlowFilesOut(), target.getBytesOut()));
+        target.setTransferred(prettyPrint(target.getFlowFilesTransferred(), target.getBytesTransferred()));
+        target.setReceived(prettyPrint(target.getFlowFilesReceived(), target.getBytesReceived()));
+        target.setSent(prettyPrint(target.getFlowFilesSent(), target.getBytesSent()));
+    }
+
+    public static void merge(final RemoteProcessGroupStatusDTO target, final RemoteProcessGroupStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        if (target.getNodeSnapshots() != null) {
+            final NodeRemoteProcessGroupStatusSnapshotDTO nodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO();
+            nodeSnapshot.setStatusSnapshot(toMerge.getAggregateSnapshot());
+            nodeSnapshot.setAddress(nodeAddress);
+            nodeSnapshot.setApiPort(nodeApiPort);
+            nodeSnapshot.setNodeId(nodeId);
+
+            target.getNodeSnapshots().add(nodeSnapshot);
+        }
+    }
+
+    public static void merge(final PortStatusDTO target, final PortStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        if (target.getNodeSnapshots() != null) {
+            final NodePortStatusSnapshotDTO nodeSnapshot = new NodePortStatusSnapshotDTO();
+            nodeSnapshot.setStatusSnapshot(toMerge.getAggregateSnapshot());
+            nodeSnapshot.setAddress(nodeAddress);
+            nodeSnapshot.setApiPort(nodeApiPort);
+            nodeSnapshot.setNodeId(nodeId);
+
+            target.getNodeSnapshots().add(nodeSnapshot);
+        }
+    }
+
+    public static void merge(final ConnectionStatusDTO target, final ConnectionStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        if (target.getNodeSnapshots() != null) {
+            final NodeConnectionStatusSnapshotDTO nodeSnapshot = new NodeConnectionStatusSnapshotDTO();
+            nodeSnapshot.setStatusSnapshot(toMerge.getAggregateSnapshot());
+            nodeSnapshot.setAddress(nodeAddress);
+            nodeSnapshot.setApiPort(nodeApiPort);
+            nodeSnapshot.setNodeId(nodeId);
+
+            target.getNodeSnapshots().add(nodeSnapshot);
+        }
+    }
+
+    public static void merge(final ProcessorStatusDTO target, final ProcessorStatusDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        if (target.getNodeSnapshots() != null) {
+            final NodeProcessorStatusSnapshotDTO nodeSnapshot = new NodeProcessorStatusSnapshotDTO();
+            nodeSnapshot.setStatusSnapshot(toMerge.getAggregateSnapshot());
+            nodeSnapshot.setAddress(nodeAddress);
+            nodeSnapshot.setApiPort(nodeApiPort);
+            nodeSnapshot.setNodeId(nodeId);
+
+            target.getNodeSnapshots().add(nodeSnapshot);
+        }
+    }
+
+    public static void merge(final ProcessorStatusSnapshotDTO target, final ProcessorStatusSnapshotDTO toMerge) {
+        if (target == null || toMerge == null) {
+            return;
+        }
+
+        // if the status to merge is invalid allow it to take precedence. whether the
+        // processor run status is disabled/stopped/running is part of the flow configuration
+        // and should not differ amongst nodes. however, whether a processor is invalid
+        // can be driven by environmental conditions. this check allows any of those to
+        // take precedence over the configured run status.
+        if (RunStatus.Invalid.name().equals(toMerge.getRunStatus())) {
+            target.setRunStatus(RunStatus.Invalid.name());
+        }
+
+        target.setBytesRead(target.getBytesRead() + toMerge.getBytesRead());
+        target.setBytesWritten(target.getBytesWritten() + toMerge.getBytesWritten());
+        target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
+        target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());
+        target.setFlowFilesOut(target.getFlowFilesOut() + toMerge.getFlowFilesOut());
+        target.setBytesOut(target.getBytesOut() + toMerge.getBytesOut());
+        target.setTaskCount(target.getTaskCount() + toMerge.getTaskCount());
+        target.setTasksDurationNanos(target.getTasksDurationNanos() + toMerge.getTasksDurationNanos());
+        target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount());
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final ProcessorStatusSnapshotDTO target) {
+        target.setInput(prettyPrint(target.getFlowFilesIn(), target.getBytesIn()));
+        target.setRead(formatDataSize(target.getBytesRead()));
+        target.setWritten(formatDataSize(target.getBytesWritten()));
+        target.setOutput(prettyPrint(target.getFlowFilesOut(), target.getBytesOut()));
+
+        final Integer taskCount = target.getTaskCount();
+        final String tasks = (taskCount == null) ? "-" : formatCount(taskCount);
+        target.setTasks(tasks);
+
+        target.setTasksDuration(FormatUtils.formatHoursMinutesSeconds(target.getTasksDurationNanos(), TimeUnit.NANOSECONDS));
+    }
+
+
+    public static void merge(final ConnectionStatusSnapshotDTO target, final ConnectionStatusSnapshotDTO toMerge) {
+        if (target == null || toMerge == null) {
+            return;
+        }
+
+        target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
+        target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());
+        target.setFlowFilesOut(target.getFlowFilesOut() + toMerge.getFlowFilesOut());
+        target.setBytesOut(target.getBytesOut() + toMerge.getBytesOut());
+        target.setFlowFilesQueued(target.getFlowFilesQueued() + toMerge.getFlowFilesQueued());
+        target.setBytesQueued(target.getBytesQueued() + toMerge.getBytesQueued());
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final ConnectionStatusSnapshotDTO target) {
+        target.setQueued(prettyPrint(target.getFlowFilesQueued(), target.getBytesQueued()));
+        target.setQueuedCount(formatCount(target.getFlowFilesQueued()));
+        target.setQueuedSize(formatDataSize(target.getBytesQueued()));
+        target.setInput(prettyPrint(target.getFlowFilesIn(), target.getBytesIn()));
+        target.setOutput(prettyPrint(target.getFlowFilesOut(), target.getBytesOut()));
+    }
+
+
+
+    public static void merge(final RemoteProcessGroupStatusSnapshotDTO target, final RemoteProcessGroupStatusSnapshotDTO toMerge) {
+        final String transmittingValue = TransmissionStatus.Transmitting.name();
+        if (transmittingValue.equals(target.getTransmissionStatus()) || transmittingValue.equals(toMerge.getTransmissionStatus())) {
+            target.setTransmissionStatus(transmittingValue);
+        }
+
+        target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount());
+
+        final List<String> authIssues = new ArrayList<>();
+        if (target.getAuthorizationIssues() != null) {
+            authIssues.addAll(target.getAuthorizationIssues());
+        }
+        if (toMerge.getAuthorizationIssues() != null) {
+            authIssues.addAll(toMerge.getAuthorizationIssues());
+        }
+        target.setAuthorizationIssues(authIssues);
+
+        target.setFlowFilesSent(target.getFlowFilesSent() + toMerge.getFlowFilesSent());
+        target.setBytesSent(target.getBytesSent() + toMerge.getBytesSent());
+        target.setFlowFilesReceived(target.getFlowFilesReceived() + toMerge.getFlowFilesReceived());
+        target.setBytesReceived(target.getBytesReceived() + toMerge.getBytesReceived());
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final RemoteProcessGroupStatusSnapshotDTO target) {
+        target.setReceived(prettyPrint(target.getFlowFilesReceived(), target.getBytesReceived()));
+        target.setSent(prettyPrint(target.getFlowFilesSent(), target.getBytesSent()));
+    }
+
+
+
+    public static void merge(final PortStatusSnapshotDTO target, final PortStatusSnapshotDTO toMerge) {
+        if (target == null || toMerge == null) {
+            return;
+        }
+
+        target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount());
+        target.setFlowFilesIn(target.getFlowFilesIn() + toMerge.getFlowFilesIn());
+        target.setBytesIn(target.getBytesIn() + toMerge.getBytesIn());
+        target.setFlowFilesOut(target.getFlowFilesOut() + toMerge.getFlowFilesOut());
+        target.setBytesOut(target.getBytesOut() + toMerge.getBytesOut());
+        target.setTransmitting(Boolean.TRUE.equals(target.isTransmitting()) || Boolean.TRUE.equals(toMerge.isTransmitting()));
+
+        // should be unnecessary here since ports run status not should be affected by
+        // environmental conditions but doing so in case that changes
+        if (RunStatus.Invalid.name().equals(toMerge.getRunStatus())) {
+            target.setRunStatus(RunStatus.Invalid.name());
+        }
+
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final PortStatusSnapshotDTO target) {
+        target.setInput(prettyPrint(target.getFlowFilesIn(), target.getBytesIn()));
+        target.setOutput(prettyPrint(target.getFlowFilesOut(), target.getBytesOut()));
+    }
+
+
+    public static void merge(final SystemDiagnosticsDTO target, final SystemDiagnosticsDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        List<NodeSystemDiagnosticsSnapshotDTO> nodeSnapshots = target.getNodeSnapshots();
+        if (nodeSnapshots == null) {
+            nodeSnapshots = new ArrayList<>();
+        }
+
+        final NodeSystemDiagnosticsSnapshotDTO nodeSnapshot = new NodeSystemDiagnosticsSnapshotDTO();
+        nodeSnapshot.setAddress(nodeAddress);
+        nodeSnapshot.setApiPort(nodeApiPort);
+        nodeSnapshot.setNodeId(nodeId);
+        nodeSnapshot.setSnapshot(toMerge.getAggregateSnapshot());
+
+        nodeSnapshots.add(nodeSnapshot);
+        target.setNodeSnapshots(nodeSnapshots);
+    }
+
+    public static void merge(final SystemDiagnosticsSnapshotDTO target, final SystemDiagnosticsSnapshotDTO toMerge) {
+        if (target == null || toMerge == null) {
+            return;
+        }
+
+        target.setAvailableProcessors(target.getAvailableProcessors() + toMerge.getAvailableProcessors());
+        target.setDaemonThreads(target.getDaemonThreads() + toMerge.getDaemonThreads());
+        target.setFreeHeapBytes(target.getFreeHeapBytes() + toMerge.getFreeHeapBytes());
+        target.setFreeNonHeapBytes(target.getFreeNonHeapBytes() + toMerge.getFreeNonHeapBytes());
+        target.setMaxHeapBytes(target.getMaxHeapBytes() + toMerge.getMaxHeapBytes());
+        target.setMaxNonHeapBytes(target.getMaxNonHeapBytes() + toMerge.getMaxNonHeapBytes());
+        target.setProcessorLoadAverage(target.getProcessorLoadAverage() + toMerge.getProcessorLoadAverage());
+        target.setTotalHeapBytes(target.getTotalHeapBytes() + toMerge.getTotalHeapBytes());
+        target.setTotalNonHeapBytes(target.getTotalNonHeapBytes() + toMerge.getTotalNonHeapBytes());
+        target.setTotalThreads(target.getTotalThreads() + toMerge.getTotalThreads());
+        target.setUsedHeapBytes(target.getUsedHeapBytes() + toMerge.getUsedHeapBytes());
+        target.setUsedNonHeapBytes(target.getUsedNonHeapBytes() + toMerge.getUsedNonHeapBytes());
+
+        merge(target.getContentRepositoryStorageUsage(), toMerge.getContentRepositoryStorageUsage());
+        merge(target.getFlowFileRepositoryStorageUsage(), toMerge.getFlowFileRepositoryStorageUsage());
+        mergeGarbageCollection(target.getGarbageCollection(), toMerge.getGarbageCollection());
+
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final SystemDiagnosticsSnapshotDTO target) {
+        // heap
+        target.setMaxHeap(FormatUtils.formatDataSize(target.getMaxHeapBytes()));
+        target.setTotalHeap(FormatUtils.formatDataSize(target.getTotalHeapBytes()));
+        target.setUsedHeap(FormatUtils.formatDataSize(target.getUsedHeapBytes()));
+        target.setFreeHeap(FormatUtils.formatDataSize(target.getFreeHeapBytes()));
+        if (target.getMaxHeapBytes() != -1) {
+            target.setHeapUtilization(FormatUtils.formatUtilization(getUtilization(target.getUsedHeapBytes(), target.getMaxHeapBytes())));
+        }
+
+        // non heap
+        target.setMaxNonHeap(FormatUtils.formatDataSize(target.getMaxNonHeapBytes()));
+        target.setTotalNonHeap(FormatUtils.formatDataSize(target.getTotalNonHeapBytes()));
+        target.setUsedNonHeap(FormatUtils.formatDataSize(target.getUsedNonHeapBytes()));
+        target.setFreeNonHeap(FormatUtils.formatDataSize(target.getFreeNonHeapBytes()));
+        if (target.getMaxNonHeapBytes() != -1) {
+            target.setNonHeapUtilization(FormatUtils.formatUtilization(getUtilization(target.getUsedNonHeapBytes(), target.getMaxNonHeapBytes())));
+        }
+    }
+
+    public static void merge(final Set<StorageUsageDTO> targetSet, final Set<StorageUsageDTO> toMerge) {
+        final Map<String, StorageUsageDTO> storageById = new HashMap<>();
+        for (final StorageUsageDTO targetUsage : targetSet) {
+            storageById.put(targetUsage.getIdentifier(), targetUsage);
+        }
+
+        for (final StorageUsageDTO usageToMerge : toMerge) {
+            final StorageUsageDTO targetUsage = storageById.get(usageToMerge.getIdentifier());
+            if (targetUsage == null) {
+                storageById.put(usageToMerge.getIdentifier(), usageToMerge);
+            } else {
+                merge(targetUsage, usageToMerge);
+            }
+        }
+
+        targetSet.clear();
+        targetSet.addAll(storageById.values());
+    }
+
+    public static void merge(final StorageUsageDTO target, final StorageUsageDTO toMerge) {
+        target.setFreeSpaceBytes(target.getFreeSpaceBytes() + toMerge.getFreeSpaceBytes());
+        target.setTotalSpaceBytes(target.getTotalSpaceBytes() + toMerge.getTotalSpaceBytes());
+        target.setUsedSpaceBytes(target.getUsedSpaceBytes() + toMerge.getUsedSpaceBytes());
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final StorageUsageDTO target) {
+        target.setFreeSpace(FormatUtils.formatDataSize(target.getFreeSpaceBytes()));
+        target.setTotalSpace(FormatUtils.formatDataSize(target.getTotalSpaceBytes()));
+        target.setUsedSpace(FormatUtils.formatDataSize(target.getUsedSpaceBytes()));
+
+        if (target.getTotalSpaceBytes() != -1) {
+            target.setUtilization(FormatUtils.formatUtilization(getUtilization(target.getUsedSpaceBytes(), target.getTotalSpaceBytes())));
+        }
+    }
+
+
+    public static void mergeGarbageCollection(final Set<GarbageCollectionDTO> targetSet, final Set<GarbageCollectionDTO> toMerge) {
+        final Map<String, GarbageCollectionDTO> storageById = new HashMap<>();
+        for (final GarbageCollectionDTO targetUsage : targetSet) {
+            storageById.put(targetUsage.getName(), targetUsage);
+        }
+
+        for (final GarbageCollectionDTO usageToMerge : toMerge) {
+            final GarbageCollectionDTO targetUsage = storageById.get(usageToMerge.getName());
+            if (targetUsage == null) {
+                storageById.put(usageToMerge.getName(), usageToMerge);
+            } else {
+                merge(targetUsage, usageToMerge);
+            }
+        }
+
+        targetSet.clear();
+        targetSet.addAll(storageById.values());
+    }
+
+    public static void merge(final GarbageCollectionDTO target, final GarbageCollectionDTO toMerge) {
+        target.setCollectionCount(target.getCollectionCount() + toMerge.getCollectionCount());
+        target.setCollectionMillis(target.getCollectionMillis() + toMerge.getCollectionMillis());
+        updatePrettyPrintedFields(target);
+    }
+
+    public static void updatePrettyPrintedFields(final GarbageCollectionDTO target) {
+        target.setCollectionTime(FormatUtils.formatHoursMinutesSeconds(target.getCollectionMillis(), TimeUnit.MILLISECONDS));
+    }
+
+    public static void merge(final CountersDTO target, final CountersDTO toMerge, final String nodeId, final String nodeAddress, final Integer nodeApiPort) {
+        merge(target.getAggregateSnapshot(), toMerge.getAggregateSnapshot());
+
+        List<NodeCountersSnapshotDTO> nodeSnapshots = target.getNodeSnapshots();
+        if (nodeSnapshots == null) {
+            nodeSnapshots = new ArrayList<>();
+        }
+
+        final NodeCountersSnapshotDTO nodeCountersSnapshot = new NodeCountersSnapshotDTO();
+        nodeCountersSnapshot.setNodeId(nodeId);
+        nodeCountersSnapshot.setAddress(nodeAddress);
+        nodeCountersSnapshot.setApiPort(nodeApiPort);
+        nodeCountersSnapshot.setSnapshot(toMerge.getAggregateSnapshot());
+
+        nodeSnapshots.add(nodeCountersSnapshot);
+
+        target.setNodeSnapshots(nodeSnapshots);
+    }
+
+    public static void merge(final CountersSnapshotDTO target, final CountersSnapshotDTO toMerge) {
+        final Map<String, CounterDTO> counters = new HashMap<>();
+
+        for (final CounterDTO counter : target.getCounters()) {
+            counters.put(counter.getId(), counter);
+        }
+
+        for (final CounterDTO counter : toMerge.getCounters()) {
+            final CounterDTO existing = counters.get(counter.getId());
+            if (existing == null) {
+                counters.put(counter.getId(), counter);
+            } else {
+                merge(existing, counter);
+            }
+        }
+
+        target.setCounters(counters.values());
+    }
+
+    public static void merge(final CounterDTO target, final CounterDTO toMerge) {
+        target.setValueCount(target.getValueCount() + toMerge.getValueCount());
+        target.setValue(FormatUtils.formatCount(target.getValueCount()));
+    }
+
+
+    public static int getUtilization(final double used, final double total) {
+        return (int) Math.round((used / total) * 100);
+    }
+
+    public static String formatCount(final Integer intStatus) {
+        return intStatus == null ? "-" : FormatUtils.formatCount(intStatus);
+    }
+
+    public static String formatDataSize(final Long longStatus) {
+        return longStatus == null ? "-" : FormatUtils.formatDataSize(longStatus);
+    }
+
+    public static String prettyPrint(final Integer count, final Long bytes) {
+        return formatCount(count) + " / " + formatDataSize(bytes);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/ClusteredEventAccess.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/ClusteredEventAccess.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/ClusteredEventAccess.java
index d3d5559..3966a31 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/ClusteredEventAccess.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/ClusteredEventAccess.java
@@ -46,7 +46,7 @@ public class ClusteredEventAccess implements EventAccess {
 
     @Override
     public ProcessGroupStatus getControllerStatus() {
-        return clusterManager.getProcessGroupStatus(WebClusterManager.ROOT_GROUP_ID_ALIAS);
+        return new ProcessGroupStatus();
     }
 
     @Override


[10/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Heartbeater.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Heartbeater.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Heartbeater.java
deleted file mode 100644
index 1195bc9..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Heartbeater.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.controller;
-
-public interface Heartbeater {
-
-    void heartbeat();
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
index e91ba9a..0d7f3ff 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
@@ -21,7 +21,6 @@ import java.util.concurrent.ScheduledExecutorService;
 
 import org.apache.nifi.controller.ConfiguredComponent;
 import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.Heartbeater;
 
 public interface ControllerServiceNode extends ConfiguredComponent {
 
@@ -64,10 +63,8 @@ public interface ControllerServiceNode extends ConfiguredComponent {
      *            initiate service enabling task as well as its re-tries
      * @param administrativeYieldMillis
      *            the amount of milliseconds to wait for administrative yield
-     * @param heartbeater
-     *            the instance of {@link Heartbeater}
      */
-    void enable(ScheduledExecutorService scheduler, long administrativeYieldMillis, Heartbeater heartbeater);
+    void enable(ScheduledExecutorService scheduler, long administrativeYieldMillis);
 
     /**
      * Will disable this service. Disabling of the service typically means
@@ -76,10 +73,8 @@ public interface ControllerServiceNode extends ConfiguredComponent {
      * @param scheduler
      *            implementation of {@link ScheduledExecutorService} used to
      *            initiate service disabling task
-     * @param heartbeater
-     *            the instance of {@link Heartbeater}
      */
-    void disable(ScheduledExecutorService scheduler, Heartbeater heartbeater);
+    void disable(ScheduledExecutorService scheduler);
 
     /**
      * @return the ControllerServiceReference that describes which components are referencing this Controller Service
@@ -139,12 +134,12 @@ public interface ControllerServiceNode extends ConfiguredComponent {
     /**
      * Returns 'true' if this service is active. The service is considered to be
      * active if and only if it's
-     * {@link #enable(ScheduledExecutorService, long, Heartbeater)} operation
+     * {@link #enable(ScheduledExecutorService, long)} operation
      * has been invoked and the service has been transitioned to ENABLING state.
      * The service will also remain 'active' after its been transitioned to
      * ENABLED state. <br>
      * The service will be de-activated upon invocation of
-     * {@link #disable(ScheduledExecutorService, Heartbeater)}.
+     * {@link #disable(ScheduledExecutorService)}.
      */
     boolean isActive();
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/HeartbeatPayload.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/HeartbeatPayload.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/HeartbeatPayload.java
index ff3ad4e..1146a39 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/HeartbeatPayload.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/HeartbeatPayload.java
@@ -20,18 +20,14 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.List;
+
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
 import org.apache.nifi.cluster.protocol.ProtocolException;
-import org.apache.nifi.controller.Counter;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.diagnostics.SystemDiagnostics;
-import org.apache.nifi.jaxb.CounterAdapter;
 
 /**
  * The payload of the heartbeat. The payload contains status to inform the cluster manager the current workload of this node.
@@ -50,23 +46,11 @@ public class HeartbeatPayload {
         }
     }
 
-    private List<Counter> counters;
-    private ProcessGroupStatus processGroupStatus;
     private int activeThreadCount;
     private long totalFlowFileCount;
     private long totalFlowFileBytes;
-    private SystemDiagnostics systemDiagnostics;
     private long systemStartTime;
 
-    @XmlJavaTypeAdapter(CounterAdapter.class)
-    public List<Counter> getCounters() {
-        return counters;
-    }
-
-    public void setCounters(final List<Counter> counters) {
-        this.counters = counters;
-    }
-
     public int getActiveThreadCount() {
         return activeThreadCount;
     }
@@ -91,22 +75,6 @@ public class HeartbeatPayload {
         this.totalFlowFileBytes = totalFlowFileBytes;
     }
 
-    public ProcessGroupStatus getProcessGroupStatus() {
-        return processGroupStatus;
-    }
-
-    public void setProcessGroupStatus(final ProcessGroupStatus processGroupStatus) {
-        this.processGroupStatus = processGroupStatus;
-    }
-
-    public SystemDiagnostics getSystemDiagnostics() {
-        return systemDiagnostics;
-    }
-
-    public void setSystemDiagnostics(final SystemDiagnostics systemDiagnostics) {
-        this.systemDiagnostics = systemDiagnostics;
-    }
-
     public long getSystemStartTime() {
         return systemStartTime;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
index 1ef18c0..d43a3db 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
@@ -28,7 +28,6 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.nifi.controller.Heartbeater;
 import org.apache.nifi.controller.ProcessScheduler;
 import org.apache.nifi.controller.StandardFlowFileQueue;
 import org.apache.nifi.controller.queue.FlowFileQueue;
@@ -71,7 +70,7 @@ public final class StandardConnection implements Connection {
         relationships = new AtomicReference<>(Collections.unmodifiableCollection(builder.relationships));
         scheduler = builder.scheduler;
         flowFileQueue = new StandardFlowFileQueue(id, this, builder.flowFileRepository, builder.provenanceRepository, builder.resourceClaimManager,
-            scheduler, builder.swapManager, builder.eventReporter, NiFiProperties.getInstance().getQueueSwapThreshold(), builder.heartbeater);
+            scheduler, builder.swapManager, builder.eventReporter, NiFiProperties.getInstance().getQueueSwapThreshold());
         hashCode = new HashCodeBuilder(7, 67).append(id).toHashCode();
     }
 
@@ -270,7 +269,6 @@ public final class StandardConnection implements Connection {
         private FlowFileRepository flowFileRepository;
         private ProvenanceEventRepository provenanceRepository;
         private ResourceClaimManager resourceClaimManager;
-        private Heartbeater heartbeater;
 
         public Builder(final ProcessScheduler scheduler) {
             this.scheduler = scheduler;
@@ -306,11 +304,6 @@ public final class StandardConnection implements Connection {
             return this;
         }
 
-        public Builder heartbeater(final Heartbeater heartbeater) {
-            this.heartbeater = heartbeater;
-            return this;
-        }
-
         public Builder bendPoints(final List<Position> bendPoints) {
             this.bendPoints.clear();
             this.bendPoints.addAll(bendPoints);

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
index 09c4da6..632fa1a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
@@ -16,7 +16,40 @@
  */
 package org.apache.nifi.controller;
 
-import com.sun.jersey.api.client.ClientHandlerException;
+import static java.util.Objects.requireNonNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.LockSupport;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import javax.net.ssl.SSLContext;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.action.Action;
 import org.apache.nifi.admin.service.AuditService;
@@ -27,16 +60,13 @@ import org.apache.nifi.annotation.lifecycle.OnRemoved;
 import org.apache.nifi.annotation.lifecycle.OnShutdown;
 import org.apache.nifi.annotation.notification.OnPrimaryNodeStateChange;
 import org.apache.nifi.annotation.notification.PrimaryNodeState;
-import org.apache.nifi.cluster.BulletinsPayload;
 import org.apache.nifi.cluster.HeartbeatPayload;
 import org.apache.nifi.cluster.protocol.DataFlow;
 import org.apache.nifi.cluster.protocol.Heartbeat;
-import org.apache.nifi.cluster.protocol.NodeBulletins;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.cluster.protocol.NodeProtocolSender;
 import org.apache.nifi.cluster.protocol.UnknownServiceAddressException;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
-import org.apache.nifi.cluster.protocol.message.NodeBulletinsMessage;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.state.StateManagerProvider;
 import org.apache.nifi.connectable.Connectable;
@@ -109,7 +139,6 @@ import org.apache.nifi.encrypt.StringEncryptor;
 import org.apache.nifi.engine.FlowEngine;
 import org.apache.nifi.events.BulletinFactory;
 import org.apache.nifi.events.EventReporter;
-import org.apache.nifi.events.NodeBulletinProcessingStrategy;
 import org.apache.nifi.events.VolatileBulletinRepository;
 import org.apache.nifi.flowfile.FlowFilePrioritizer;
 import org.apache.nifi.flowfile.attributes.CoreAttributes;
@@ -184,41 +213,9 @@ import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.net.ssl.SSLContext;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.LockSupport;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import static java.util.Objects.requireNonNull;
+import com.sun.jersey.api.client.ClientHandlerException;
 
-public class FlowController implements EventAccess, ControllerServiceProvider, ReportingTaskProvider, Heartbeater, QueueProvider {
+public class FlowController implements EventAccess, ControllerServiceProvider, ReportingTaskProvider, QueueProvider {
 
     // default repository implementations
     public static final String DEFAULT_FLOWFILE_REPO_IMPLEMENTATION = "org.apache.nifi.controller.repository.WriteAheadFlowFileRepository";
@@ -308,7 +305,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
     /**
      * timer to periodically send heartbeats to the cluster
      */
-    private ScheduledFuture<?> bulletinFuture;
     private ScheduledFuture<?> heartbeatGeneratorFuture;
     private ScheduledFuture<?> heartbeatSenderFuture;
 
@@ -318,8 +314,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
      */
     private final AtomicReference<HeartbeatMessageGeneratorTask> heartbeatMessageGeneratorTaskRef = new AtomicReference<>(null);
 
-    private final AtomicReference<NodeBulletinProcessingStrategy> nodeBulletinSubscriber;
-
     // guarded by rwLock
     /**
      * the node identifier;
@@ -420,7 +414,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
         counterRepositoryRef = new AtomicReference<CounterRepository>(new StandardCounterRepository());
 
         bulletinRepository = new VolatileBulletinRepository();
-        nodeBulletinSubscriber = new AtomicReference<>();
 
         try {
             this.provenanceEventRepository = createProvenanceRepository(properties);
@@ -437,7 +430,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             throw new RuntimeException(e);
         }
 
-        processScheduler = new StandardProcessScheduler(this, this, encryptor, stateManagerProvider);
+        processScheduler = new StandardProcessScheduler(this, encryptor, stateManagerProvider);
         eventDrivenWorkerQueue = new EventDrivenWorkerQueue(false, false, processScheduler);
         controllerServiceProvider = new StandardControllerServiceProvider(processScheduler, bulletinRepository, stateManagerProvider);
 
@@ -833,7 +826,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             .resourceClaimManager(resourceClaimManager)
             .flowFileRepository(flowFileRepository)
             .provenanceRepository(provenanceEventRepository)
-            .heartbeater(this)
             .build();
     }
 
@@ -2122,7 +2114,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
         final ProcessGroupStatus status = new ProcessGroupStatus();
         status.setId(group.getIdentifier());
         status.setName(group.getName());
-        status.setCreationTimestamp(new Date().getTime());
         int activeGroupThreads = 0;
         long bytesRead = 0L;
         long bytesWritten = 0L;
@@ -2899,7 +2890,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
     public Counter resetCounter(final String identifier) {
         final CounterRepository counterRepo = counterRepositoryRef.get();
         final Counter resetValue = counterRepo.resetCounter(identifier);
-        heartbeat();
         return resetValue;
     }
 
@@ -2955,8 +2945,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
 
             stopHeartbeating();
 
-            bulletinFuture = clusterTaskExecutor.scheduleWithFixedDelay(new BulletinsTask(protocolSender), 250, 2000, TimeUnit.MILLISECONDS);
-
             final HeartbeatMessageGeneratorTask heartbeatMessageGeneratorTask = new HeartbeatMessageGeneratorTask();
             heartbeatMessageGeneratorTaskRef.set(heartbeatMessageGeneratorTask);
             heartbeatGeneratorFuture = clusterTaskExecutor.scheduleWithFixedDelay(heartbeatMessageGeneratorTask, 0, heartbeatDelaySeconds, TimeUnit.SECONDS);
@@ -3007,10 +2995,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             if (heartbeatSenderFuture != null) {
                 heartbeatSenderFuture.cancel(false);
             }
-
-            if (bulletinFuture != null) {
-                bulletinFuture.cancel(false);
-            }
         } finally {
             writeLock.unlock();
         }
@@ -3135,8 +3119,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
             // update the bulletin repository
             if (isChanging) {
                 if (clustered) {
-                    nodeBulletinSubscriber.set(new NodeBulletinProcessingStrategy());
-                    bulletinRepository.overrideDefaultBulletinProcessing(nodeBulletinSubscriber.get());
                     stateManagerProvider.enableClusterProvider();
 
                     if (zooKeeperStateServer != null) {
@@ -3175,7 +3157,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
                         LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1L));
                     }
                 } else {
-                    bulletinRepository.restoreDefaultBulletinProcessing();
                     if (zooKeeperStateServer != null) {
                         zooKeeperStateServer.shutdown();
                     }
@@ -3487,6 +3468,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
         return replayFlowFile(record, requestor);
     }
 
+    @SuppressWarnings("deprecation")
     public ProvenanceEventRecord replayFlowFile(final ProvenanceEventRecord event, final String requestor) throws IOException {
         if (event == null) {
             throw new NullPointerException();
@@ -3627,7 +3609,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
         }
     }
 
-    @Override
     public void heartbeat() {
         if (!isClustered()) {
             return;
@@ -3642,110 +3623,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
         }
     }
 
-    private class BulletinsTask implements Runnable {
-
-        private final NodeProtocolSender protocolSender;
-        private final DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS", Locale.US);
-
-        public BulletinsTask(final NodeProtocolSender protocolSender) {
-            if (protocolSender == null) {
-                throw new IllegalArgumentException("NodeProtocolSender may not be null.");
-            }
-            this.protocolSender = protocolSender;
-        }
-
-        @Override
-        public void run() {
-            try {
-                final NodeBulletinsMessage message = createBulletinsMessage();
-                if (message == null) {
-                    return;
-                }
-
-                protocolSender.sendBulletins(message);
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug(
-                        String.format(
-                            "Sending bulletins to cluster manager at %s",
-                            dateFormatter.format(new Date())));
-                }
-
-            } catch (final UnknownServiceAddressException usae) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug(usae.getMessage());
-                }
-            } catch (final Exception ex) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Failed to send bulletins to cluster manager due to: " + ex, ex);
-                }
-            }
-        }
-
-        private boolean isIllegalXmlChar(final char c) {
-            return c < 0x20 && c != 0x09 && c != 0x0A && c != 0x0D;
-        }
-
-        private boolean containsIllegalXmlChars(final Bulletin bulletin) {
-            final String message = bulletin.getMessage();
-            for (int i = 0; i < message.length(); i++) {
-                final char c = message.charAt(i);
-                if (isIllegalXmlChar(c)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        private String stripIllegalXmlChars(final String value) {
-            final StringBuilder sb = new StringBuilder(value.length());
-            for (int i = 0; i < value.length(); i++) {
-                final char c = value.charAt(i);
-                sb.append(isIllegalXmlChar(c) ? '?' : c);
-            }
-
-            return sb.toString();
-        }
-
-        private NodeBulletinsMessage createBulletinsMessage() {
-            final Set<Bulletin> nodeBulletins = nodeBulletinSubscriber.get().getBulletins();
-            final Set<Bulletin> escapedNodeBulletins = new HashSet<>(nodeBulletins.size());
-
-            // ensure there are some bulletins to report
-            if (nodeBulletins.isEmpty()) {
-                return null;
-            }
-
-            for (final Bulletin bulletin : nodeBulletins) {
-                final Bulletin escapedBulletin;
-                if (containsIllegalXmlChars(bulletin)) {
-                    final String escapedBulletinMessage = stripIllegalXmlChars(bulletin.getMessage());
-
-                    if (bulletin.getGroupId() == null) {
-                        escapedBulletin = BulletinFactory.createBulletin(bulletin.getCategory(), bulletin.getLevel(), escapedBulletinMessage);
-                    } else {
-                        escapedBulletin = BulletinFactory.createBulletin(bulletin.getGroupId(), bulletin.getSourceId(), bulletin.getSourceType(),
-                            bulletin.getSourceName(), bulletin.getCategory(), bulletin.getLevel(), escapedBulletinMessage);
-                    }
-                } else {
-                    escapedBulletin = bulletin;
-                }
-
-                escapedNodeBulletins.add(escapedBulletin);
-            }
-
-            // create the bulletin payload
-            final BulletinsPayload payload = new BulletinsPayload();
-            payload.setBulletins(escapedNodeBulletins);
-
-            // create bulletin message
-            final NodeBulletins bulletins = new NodeBulletins(getNodeId(), payload.marshal());
-            final NodeBulletinsMessage message = new NodeBulletinsMessage();
-            message.setBulletins(bulletins);
-
-            return message;
-        }
-    }
 
     private class HeartbeatSendTask implements Runnable {
 
@@ -3822,20 +3699,15 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
                     return null;
                 }
 
-                final ProcessGroupStatus procGroupStatus = getGroupStatus(bean.getRootGroup(), getProcessorStats());
                 // create heartbeat payload
                 final HeartbeatPayload hbPayload = new HeartbeatPayload();
                 hbPayload.setSystemStartTime(systemStartTime);
-                hbPayload.setActiveThreadCount(procGroupStatus.getActiveThreadCount());
+                hbPayload.setActiveThreadCount(getActiveThreadCount());
 
                 final QueueSize queueSize = getTotalFlowFileCount(bean.getRootGroup());
                 hbPayload.setTotalFlowFileCount(queueSize.getObjectCount());
                 hbPayload.setTotalFlowFileBytes(queueSize.getByteCount());
 
-                hbPayload.setCounters(getCounters());
-                hbPayload.setSystemDiagnostics(getSystemDiagnostics());
-                hbPayload.setProcessGroupStatus(procGroupStatus);
-
                 // create heartbeat message
                 final Heartbeat heartbeat = new Heartbeat(getNodeId(), bean.isPrimary(), bean.isConnected(), hbPayload.marshal());
                 final HeartbeatMessage message = new HeartbeatMessage();

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowFileQueue.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowFileQueue.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowFileQueue.java
index 0f3ffe0..6735959 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowFileQueue.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowFileQueue.java
@@ -111,7 +111,6 @@ public final class StandardFlowFileQueue implements FlowFileQueue {
     private final FlowFileRepository flowFileRepository;
     private final ProvenanceEventRepository provRepository;
     private final ResourceClaimManager resourceClaimManager;
-    private final Heartbeater heartbeater;
 
     private final ConcurrentMap<String, DropFlowFileRequest> dropRequestMap = new ConcurrentHashMap<>();
     private final ConcurrentMap<String, ListFlowFileRequest> listRequestMap = new ConcurrentHashMap<>();
@@ -120,8 +119,7 @@ public final class StandardFlowFileQueue implements FlowFileQueue {
     private final ProcessScheduler scheduler;
 
     public StandardFlowFileQueue(final String identifier, final Connection connection, final FlowFileRepository flowFileRepo, final ProvenanceEventRepository provRepo,
-        final ResourceClaimManager resourceClaimManager, final ProcessScheduler scheduler, final FlowFileSwapManager swapManager, final EventReporter eventReporter, final int swapThreshold,
-        final Heartbeater heartbeater) {
+        final ResourceClaimManager resourceClaimManager, final ProcessScheduler scheduler, final FlowFileSwapManager swapManager, final EventReporter eventReporter, final int swapThreshold) {
         activeQueue = new PriorityQueue<>(20, new Prioritizer(new ArrayList<FlowFilePrioritizer>()));
         priorities = new ArrayList<>();
         swapQueue = new ArrayList<>();
@@ -135,7 +133,6 @@ public final class StandardFlowFileQueue implements FlowFileQueue {
         this.swapThreshold = swapThreshold;
         this.scheduler = scheduler;
         this.connection = connection;
-        this.heartbeater = heartbeater;
 
         readLock = new TimedLock(this.lock.readLock(), identifier + " Read Lock", 100);
         writeLock = new TimedLock(this.lock.writeLock(), identifier + " Write Lock", 100);
@@ -1182,9 +1179,6 @@ public final class StandardFlowFileQueue implements FlowFileQueue {
                         logger.info("Successfully dropped {} FlowFiles ({} bytes) from Connection with ID {} on behalf of {}",
                             dropRequest.getDroppedSize().getObjectCount(), dropRequest.getDroppedSize().getByteCount(), StandardFlowFileQueue.this.getIdentifier(), requestor);
                         dropRequest.setState(DropFlowFileState.COMPLETE);
-                        if (heartbeater != null) {
-                            heartbeater.heartbeat();
-                        }
                     } catch (final Exception e) {
                         logger.error("Failed to drop FlowFiles from Connection with ID {} due to {}", StandardFlowFileQueue.this.getIdentifier(), e.toString());
                         logger.error("", e);

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/scheduling/StandardProcessScheduler.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/scheduling/StandardProcessScheduler.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/scheduling/StandardProcessScheduler.java
index f7e968e..3e4d3a3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/scheduling/StandardProcessScheduler.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/scheduling/StandardProcessScheduler.java
@@ -37,7 +37,6 @@ import org.apache.nifi.connectable.Funnel;
 import org.apache.nifi.connectable.Port;
 import org.apache.nifi.controller.AbstractPort;
 import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.Heartbeater;
 import org.apache.nifi.controller.ProcessScheduler;
 import org.apache.nifi.controller.ProcessorNode;
 import org.apache.nifi.controller.ReportingTaskNode;
@@ -70,7 +69,6 @@ public final class StandardProcessScheduler implements ProcessScheduler {
     private static final Logger LOG = LoggerFactory.getLogger(StandardProcessScheduler.class);
 
     private final ControllerServiceProvider controllerServiceProvider;
-    private final Heartbeater heartbeater;
     private final long administrativeYieldMillis;
     private final String administrativeYieldDuration;
     private final StateManagerProvider stateManagerProvider;
@@ -85,9 +83,8 @@ public final class StandardProcessScheduler implements ProcessScheduler {
 
     private final StringEncryptor encryptor;
 
-    public StandardProcessScheduler(final Heartbeater heartbeater, final ControllerServiceProvider controllerServiceProvider, final StringEncryptor encryptor,
+    public StandardProcessScheduler(final ControllerServiceProvider controllerServiceProvider, final StringEncryptor encryptor,
         final StateManagerProvider stateManagerProvider) {
-        this.heartbeater = heartbeater;
         this.controllerServiceProvider = controllerServiceProvider;
         this.encryptor = encryptor;
         this.stateManagerProvider = stateManagerProvider;
@@ -303,7 +300,6 @@ public final class StandardProcessScheduler implements ProcessScheduler {
             @Override
             public void trigger() {
                 getSchedulingAgent(procNode).schedule(procNode, scheduleState);
-                heartbeater.heartbeat();
             }
 
             @Override
@@ -441,7 +437,6 @@ public final class StandardProcessScheduler implements ProcessScheduler {
             final ConnectableProcessContext processContext = new ConnectableProcessContext(connectable, encryptor, getStateManager(connectable.getIdentifier()));
             try (final NarCloseable x = NarCloseable.withNarLoader()) {
                 ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnStopped.class, connectable, processContext);
-                heartbeater.heartbeat();
             }
         }
     }
@@ -541,12 +536,12 @@ public final class StandardProcessScheduler implements ProcessScheduler {
 
     @Override
     public void enableControllerService(final ControllerServiceNode service) {
-        service.enable(this.componentLifeCycleThreadPool, this.administrativeYieldMillis, this.heartbeater);
+        service.enable(this.componentLifeCycleThreadPool, this.administrativeYieldMillis);
     }
 
     @Override
     public void disableControllerService(final ControllerServiceNode service) {
-        service.disable(this.componentLifeCycleThreadPool, this.heartbeater);
+        service.disable(this.componentLifeCycleThreadPool);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
index 3f24ff1..bed6a35 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceNode.java
@@ -36,7 +36,6 @@ import org.apache.nifi.controller.AbstractConfiguredComponent;
 import org.apache.nifi.controller.ConfigurationContext;
 import org.apache.nifi.controller.ConfiguredComponent;
 import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.Heartbeater;
 import org.apache.nifi.controller.ValidationContextFactory;
 import org.apache.nifi.controller.annotation.OnConfigured;
 import org.apache.nifi.controller.exception.ComponentLifeCycleException;
@@ -273,8 +272,7 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
      * as it reached ENABLED state.
      */
     @Override
-    public void enable(final ScheduledExecutorService scheduler, final long administrativeYieldMillis,
-            final Heartbeater heartbeater) {
+    public void enable(final ScheduledExecutorService scheduler, final long administrativeYieldMillis) {
         if (this.stateRef.compareAndSet(ControllerServiceState.DISABLED, ControllerServiceState.ENABLING)) {
             this.active.set(true);
             final ConfigurationContext configContext = new StandardConfigurationContext(this, this.serviceProvider, null);
@@ -287,13 +285,11 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
                         synchronized (active) {
                             shouldEnable = active.get() && stateRef.compareAndSet(ControllerServiceState.ENABLING, ControllerServiceState.ENABLED);
                         }
-                        if (shouldEnable) {
-                            heartbeater.heartbeat();
-                        } else {
+                        if (!shouldEnable) {
                             LOG.debug("Disabling service " + this + " after it has been enabled due to disable action being initiated.");
                             // Can only happen if user initiated DISABLE operation before service finished enabling. It's state will be
                             // set to DISABLING (see disable() operation)
-                            invokeDisable(configContext, heartbeater);
+                            invokeDisable(configContext);
                             stateRef.set(ControllerServiceState.DISABLED);
                         }
                     } catch (Exception e) {
@@ -301,7 +297,7 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
                         final ComponentLog componentLog = new SimpleProcessLogger(getIdentifier(), StandardControllerServiceNode.this);
                         componentLog.error("Failed to invoke @OnEnabled method due to {}", cause);
                         LOG.error("Failed to invoke @OnEnabled method of {} due to {}", getControllerServiceImplementation(), cause.toString());
-                        invokeDisable(configContext, heartbeater);
+                        invokeDisable(configContext);
 
                         if (isActive()) {
                             scheduler.schedule(this, administrativeYieldMillis, TimeUnit.MILLISECONDS);
@@ -323,14 +319,14 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
      * If such transition doesn't succeed (the service is still in ENABLING state)
      * then the service will still be transitioned to DISABLING state to ensure that
      * no other transition could happen on this service. However in such event
-     * (e.g., its @OnEnabled finally succeeded), the {@link #enable(ScheduledExecutorService, long, Heartbeater)}
-     * operation will initiate service disabling javadoc for (see {@link #enable(ScheduledExecutorService, long, Heartbeater)}
+     * (e.g., its @OnEnabled finally succeeded), the {@link #enable(ScheduledExecutorService, long)}
+     * operation will initiate service disabling javadoc for (see {@link #enable(ScheduledExecutorService, long)}
      * <br>
      * Upon successful invocation of @OnDisabled this service will be transitioned to
      * DISABLED state.
      */
     @Override
-    public void disable(ScheduledExecutorService scheduler, final Heartbeater heartbeater) {
+    public void disable(ScheduledExecutorService scheduler) {
         /*
          * The reason for synchronization is to ensure consistency of the
          * service state when another thread is in the middle of enabling this
@@ -347,10 +343,9 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
                 @Override
                 public void run() {
                     try {
-                        invokeDisable(configContext, heartbeater);
+                        invokeDisable(configContext);
                     } finally {
                         stateRef.set(ControllerServiceState.DISABLED);
-                        heartbeater.heartbeat();
                     }
                 }
             });
@@ -362,7 +357,7 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
     /**
      *
      */
-    private void invokeDisable(ConfigurationContext configContext, Heartbeater heartbeater) {
+    private void invokeDisable(ConfigurationContext configContext) {
         try {
             ReflectionUtils.invokeMethodsWithAnnotation(OnDisabled.class, StandardControllerServiceNode.this.getControllerServiceImplementation(), configContext);
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ConnectionStatusDescriptor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ConnectionStatusDescriptor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ConnectionStatusDescriptor.java
new file mode 100644
index 0000000..8b9f383
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ConnectionStatusDescriptor.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.status.history;
+
+import org.apache.nifi.controller.status.ConnectionStatus;
+import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter;
+
+public enum ConnectionStatusDescriptor {
+    INPUT_BYTES(new StandardMetricDescriptor<ConnectionStatus>(
+        "inputBytes",
+        "Bytes In (5 mins)",
+        "The cumulative size of all FlowFiles that were transferred to this Connection in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ConnectionStatus>() {
+            @Override
+            public Long getValue(final ConnectionStatus status) {
+                return status.getInputBytes();
+            }
+        })),
+
+    INPUT_COUNT(new StandardMetricDescriptor<ConnectionStatus>(
+        "inputCount",
+        "FlowFiles In (5 mins)",
+        "The number of FlowFiles that were transferred to this Connection in the past 5 minutes",
+        Formatter.COUNT,
+        new ValueMapper<ConnectionStatus>() {
+            @Override
+            public Long getValue(final ConnectionStatus status) {
+                return Long.valueOf(status.getInputCount());
+            }
+        })),
+
+    OUTPUT_BYTES(new StandardMetricDescriptor<ConnectionStatus>(
+        "outputBytes",
+        "Bytes Out (5 mins)",
+        "The cumulative size of all FlowFiles that were pulled from this Connection in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ConnectionStatus>() {
+            @Override
+            public Long getValue(final ConnectionStatus status) {
+                return status.getOutputBytes();
+            }
+        })),
+
+    OUTPUT_COUNT(new StandardMetricDescriptor<ConnectionStatus>(
+        "outputCount",
+        "FlowFiles Out (5 mins)",
+        "The number of FlowFiles that were pulled from this Connection in the past 5 minutes",
+        Formatter.COUNT,
+        new ValueMapper<ConnectionStatus>() {
+            @Override
+            public Long getValue(final ConnectionStatus status) {
+                return Long.valueOf(status.getOutputCount());
+            }
+        })),
+
+    QUEUED_BYTES(new StandardMetricDescriptor<ConnectionStatus>(
+        "queuedBytes",
+        "Queued Bytes",
+        "The number of Bytes queued in this Connection",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ConnectionStatus>() {
+            @Override
+            public Long getValue(final ConnectionStatus status) {
+                return status.getQueuedBytes();
+            }
+        })),
+
+    QUEUED_COUNT(new StandardMetricDescriptor<ConnectionStatus>(
+        "queuedCount",
+        "Queued Count",
+        "The number of FlowFiles queued in this Connection",
+        Formatter.COUNT,
+        new ValueMapper<ConnectionStatus>() {
+            @Override
+            public Long getValue(final ConnectionStatus status) {
+                return Long.valueOf(status.getQueuedCount());
+            }
+        }));
+
+
+    private MetricDescriptor<ConnectionStatus> descriptor;
+
+    private ConnectionStatusDescriptor(final MetricDescriptor<ConnectionStatus> descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    public String getField() {
+        return descriptor.getField();
+    }
+
+    public MetricDescriptor<ConnectionStatus> getDescriptor() {
+        return descriptor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessGroupStatusDescriptor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessGroupStatusDescriptor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessGroupStatusDescriptor.java
new file mode 100644
index 0000000..d5325d0
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessGroupStatusDescriptor.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.status.history;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.nifi.controller.status.ProcessGroupStatus;
+import org.apache.nifi.controller.status.ProcessorStatus;
+import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter;
+
+public enum ProcessGroupStatusDescriptor {
+
+    BYTES_READ(new StandardMetricDescriptor<ProcessGroupStatus>("bytesRead", "Bytes Read (5 mins)",
+        "The total number of bytes read from Content Repository by Processors in this Process Group in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getBytesRead();
+            }
+        })),
+
+    BYTES_WRITTEN(new StandardMetricDescriptor<ProcessGroupStatus>("bytesWritten", "Bytes Written (5 mins)",
+        "The total number of bytes written to Content Repository by Processors in this Process Group in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getBytesWritten();
+            }
+        })),
+
+    BYTES_TRANSFERRED(new StandardMetricDescriptor<ProcessGroupStatus>("bytesTransferred", "Bytes Transferred (5 mins)",
+        "The total number of bytes read from or written to Content Repository by Processors in this Process Group in the past 5 minutes",
+        Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getBytesRead() + status.getBytesWritten();
+            }
+        })),
+
+    INPUT_BYTES(new StandardMetricDescriptor<ProcessGroupStatus>("inputBytes", "Bytes In (5 mins)",
+        "The cumulative size of all FlowFiles that have entered this Process Group via its Input Ports in the past 5 minutes",
+        Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getInputContentSize();
+            }
+        })),
+
+    INPUT_COUNT(new StandardMetricDescriptor<ProcessGroupStatus>("inputCount", "FlowFiles In (5 mins)",
+        "The number of FlowFiles that have entered this Process Group via its Input Ports in the past 5 minutes",
+        Formatter.COUNT, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getInputCount().longValue();
+            }
+        })),
+
+    OUTPUT_BYTES(new StandardMetricDescriptor<ProcessGroupStatus>("outputBytes", "Bytes Out (5 mins)",
+        "The cumulative size of all FlowFiles that have exited this Process Group via its Output Ports in the past 5 minutes",
+        Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getOutputContentSize();
+            }
+        })),
+
+    OUTPUT_COUNT(new StandardMetricDescriptor<ProcessGroupStatus>("outputCount", "FlowFiles Out (5 mins)",
+        "The number of FlowFiles that have exited this Process Group via its Output Ports in the past 5 minutes",
+        Formatter.COUNT, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getOutputCount().longValue();
+            }
+        })),
+
+    QUEUED_BYTES(new StandardMetricDescriptor<ProcessGroupStatus>("queuedBytes", "Queued Bytes",
+        "The cumulative size of all FlowFiles queued in all Connections of this Process Group",
+        Formatter.DATA_SIZE, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getQueuedContentSize();
+            }
+        })),
+
+    QUEUED_COUNT(new StandardMetricDescriptor<ProcessGroupStatus>("queuedCount", "Queued Count",
+        "The number of FlowFiles queued in all Connections of this Process Group", Formatter.COUNT, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return status.getQueuedCount().longValue();
+            }
+        })),
+
+    TASK_MILLIS(new StandardMetricDescriptor<ProcessGroupStatus>("taskMillis", "Total Task Duration (5 mins)",
+        "The total number of thread-milliseconds that the Processors within this ProcessGroup have used to complete their tasks in the past 5 minutes",
+        Formatter.DURATION, new ValueMapper<ProcessGroupStatus>() {
+            @Override
+            public Long getValue(final ProcessGroupStatus status) {
+                return calculateTaskMillis(status);
+            }
+        }));
+
+    private MetricDescriptor<ProcessGroupStatus> descriptor;
+
+    private ProcessGroupStatusDescriptor(final MetricDescriptor<ProcessGroupStatus> descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    public String getField() {
+        return descriptor.getField();
+    }
+
+    public MetricDescriptor<ProcessGroupStatus> getDescriptor() {
+        return descriptor;
+    }
+
+
+    private static long calculateTaskMillis(final ProcessGroupStatus status) {
+        long nanos = 0L;
+
+        for (final ProcessorStatus procStatus : status.getProcessorStatus()) {
+            nanos += procStatus.getProcessingNanos();
+        }
+
+        for (final ProcessGroupStatus childStatus : status.getProcessGroupStatus()) {
+            nanos += calculateTaskMillis(childStatus);
+        }
+
+        return TimeUnit.MILLISECONDS.convert(nanos, TimeUnit.NANOSECONDS);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessorStatusDescriptor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessorStatusDescriptor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessorStatusDescriptor.java
new file mode 100644
index 0000000..89e8aa0
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/ProcessorStatusDescriptor.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.status.history;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.nifi.controller.status.ProcessorStatus;
+import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter;
+
+public enum ProcessorStatusDescriptor {
+    BYTES_READ(new StandardMetricDescriptor<ProcessorStatus>(
+        "bytesRead",
+        "Bytes Read (5 mins)",
+        "The total number of bytes read from the Content Repository by this Processor in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getBytesRead();
+            }
+        })),
+
+    BYTES_WRITTEN(new StandardMetricDescriptor<ProcessorStatus>(
+        "bytesWritten",
+        "Bytes Written (5 mins)",
+        "The total number of bytes written to the Content Repository by this Processor in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getBytesWritten();
+            }
+        })),
+
+    BYTES_TRANSFERRED(new StandardMetricDescriptor<ProcessorStatus>(
+        "bytesTransferred",
+        "Bytes Transferred (5 mins)",
+        "The total number of bytes read from or written to the Content Repository by this Processor in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getBytesRead() + status.getBytesWritten();
+            }
+        })),
+
+    INPUT_BYTES(new StandardMetricDescriptor<ProcessorStatus>(
+        "inputBytes",
+        "Bytes In (5 mins)",
+        "The cumulative size of all FlowFiles that this Processor has pulled from its queues in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getInputBytes();
+            }
+        })),
+
+    INPUT_COUNT(new StandardMetricDescriptor<ProcessorStatus>(
+        "inputCount",
+        "FlowFiles In (5 mins)",
+        "The number of FlowFiles that this Processor has pulled from its queues in the past 5 minutes",
+        Formatter.COUNT, new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return Long.valueOf(status.getInputCount());
+            }
+        })),
+    OUTPUT_BYTES(new StandardMetricDescriptor<ProcessorStatus>(
+        "outputBytes",
+        "Bytes Out (5 mins)",
+        "The cumulative size of all FlowFiles that this Processor has transferred to downstream queues in the past 5 minutes",
+        Formatter.DATA_SIZE,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getOutputBytes();
+            }
+        })),
+
+    OUTPUT_COUNT(new StandardMetricDescriptor<ProcessorStatus>(
+        "outputCount",
+        "FlowFiles Out (5 mins)",
+        "The number of FlowFiles that this Processor has transferred to downstream queues in the past 5 minutes",
+        Formatter.COUNT,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return Long.valueOf(status.getOutputCount());
+            }
+        })),
+
+    TASK_COUNT(new StandardMetricDescriptor<ProcessorStatus>(
+        "taskCount",
+        "Tasks (5 mins)",
+        "The number of tasks that this Processor has completed in the past 5 minutes",
+        Formatter.COUNT,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return Long.valueOf(status.getInvocations());
+            }
+        })),
+
+    TASK_MILLIS(new StandardMetricDescriptor<ProcessorStatus>(
+        "taskMillis",
+        "Total Task Duration (5 mins)",
+        "The total number of thread-milliseconds that the Processor has used to complete its tasks in the past 5 minutes",
+        Formatter.DURATION,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return TimeUnit.MILLISECONDS.convert(status.getProcessingNanos(), TimeUnit.NANOSECONDS);
+            }
+        })),
+
+    FLOWFILES_REMOVED(new StandardMetricDescriptor<ProcessorStatus>(
+        "flowFilesRemoved",
+        "FlowFiles Removed (5 mins)",
+        "The total number of FlowFiles removed by this Processor in the last 5 minutes",
+        Formatter.COUNT,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return Long.valueOf(status.getFlowFilesRemoved());
+            }
+        })),
+
+    AVERAGE_LINEAGE_DURATION(new StandardMetricDescriptor<ProcessorStatus>(
+        "averageLineageDuration",
+        "Average Lineage Duration (5 mins)",
+        "The average amount of time that a FlowFile took to process (from receipt until this Processor finished processing it) in the past 5 minutes.",
+        Formatter.DURATION,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getAverageLineageDuration(TimeUnit.MILLISECONDS);
+            }
+        }, new ValueReducer<StatusSnapshot, Long>() {
+            @Override
+            public Long reduce(final List<StatusSnapshot> values) {
+                long millis = 0L;
+                int count = 0;
+
+                for (final StatusSnapshot snapshot : values) {
+                    final long removed = snapshot.getStatusMetrics().get(FLOWFILES_REMOVED.getDescriptor()).longValue();
+                    count += removed;
+
+                    count += snapshot.getStatusMetrics().get(OUTPUT_COUNT.getDescriptor()).longValue();
+
+                    final long avgMillis = snapshot.getStatusMetrics().get(AVERAGE_LINEAGE_DURATION.getDescriptor()).longValue();
+                    final long totalMillis = avgMillis * removed;
+                    millis += totalMillis;
+                }
+
+                return count == 0 ? 0 : millis / count;
+            }
+        }
+    )),
+
+    AVERAGE_TASK_MILLIS(new StandardMetricDescriptor<ProcessorStatus>(
+        "averageTaskMillis",
+        "Average Task Duration",
+        "The average duration it took this Processor to complete a task, as averaged over the past 5 minutes",
+        Formatter.DURATION,
+        new ValueMapper<ProcessorStatus>() {
+            @Override
+            public Long getValue(final ProcessorStatus status) {
+                return status.getInvocations() == 0 ? 0 : TimeUnit.MILLISECONDS.convert(status.getProcessingNanos(), TimeUnit.NANOSECONDS) / status.getInvocations();
+            }
+        },
+        new ValueReducer<StatusSnapshot, Long>() {
+            @Override
+            public Long reduce(final List<StatusSnapshot> values) {
+                long procMillis = 0L;
+                int invocations = 0;
+
+                for (final StatusSnapshot snapshot : values) {
+                    procMillis += snapshot.getStatusMetrics().get(TASK_MILLIS.getDescriptor()).longValue();
+                    invocations += snapshot.getStatusMetrics().get(TASK_COUNT.getDescriptor()).intValue();
+                }
+
+                if (invocations == 0) {
+                    return 0L;
+                }
+
+                return procMillis / invocations;
+            }
+        }));
+
+    private MetricDescriptor<ProcessorStatus> descriptor;
+
+    private ProcessorStatusDescriptor(final MetricDescriptor<ProcessorStatus> descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    public String getField() {
+        return descriptor.getField();
+    }
+
+    public MetricDescriptor<ProcessorStatus> getDescriptor() {
+        return descriptor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java
new file mode 100644
index 0000000..0499d65
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/RemoteProcessGroupStatusDescriptor.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.controller.status.history;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.nifi.controller.status.RemoteProcessGroupStatus;
+import org.apache.nifi.controller.status.history.MetricDescriptor.Formatter;
+
+public enum RemoteProcessGroupStatusDescriptor {
+    SENT_BYTES(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentBytes", "Bytes Sent (5 mins)",
+        "The cumulative size of all FlowFiles that have been successfully sent to the remote system in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return status.getSentContentSize();
+            }
+        })),
+
+    SENT_COUNT(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentCount", "FlowFiles Sent (5 mins)",
+        "The number of FlowFiles that have been successfully sent to the remote system in the past 5 minutes", Formatter.COUNT, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return Long.valueOf(status.getSentCount().longValue());
+            }
+        })),
+
+    RECEIVED_BYTES(new StandardMetricDescriptor<RemoteProcessGroupStatus>("receivedBytes", "Bytes Received (5 mins)",
+        "The cumulative size of all FlowFiles that have been received from the remote system in the past 5 minutes", Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return status.getReceivedContentSize();
+            }
+        })),
+
+    RECEIVED_COUNT(new StandardMetricDescriptor<RemoteProcessGroupStatus>("receivedCount", "FlowFiles Received (5 mins)",
+        "The number of FlowFiles that have been received from the remote system in the past 5 minutes", Formatter.COUNT, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return Long.valueOf(status.getReceivedCount().longValue());
+            }
+        })),
+
+    RECEIVED_BYTES_PER_SECOND(new StandardMetricDescriptor<RemoteProcessGroupStatus>("receivedBytesPerSecond", "Received Bytes Per Second",
+        "The data rate at which data was received from the remote system in the past 5 minutes in terms of Bytes Per Second",
+        Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return Long.valueOf(status.getReceivedContentSize().longValue() / 300L);
+            }
+        })),
+
+    SENT_BYTES_PER_SECOND(new StandardMetricDescriptor<RemoteProcessGroupStatus>("sentBytesPerSecond", "Sent Bytes Per Second",
+        "The data rate at which data was received from the remote system in the past 5 minutes in terms of Bytes Per Second", Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return Long.valueOf(status.getSentContentSize().longValue() / 300L);
+            }
+        })),
+
+    TOTAL_BYTES_PER_SECOND(new StandardMetricDescriptor<RemoteProcessGroupStatus>("totalBytesPerSecond", "Total Bytes Per Second",
+        "The sum of the send and receive data rate from the remote system in the past 5 minutes in terms of Bytes Per Second",
+        Formatter.DATA_SIZE, new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return Long.valueOf((status.getReceivedContentSize().longValue() + status.getSentContentSize().longValue()) / 300L);
+            }
+        })),
+
+    AVERAGE_LINEAGE_DURATION(new StandardMetricDescriptor<RemoteProcessGroupStatus>(
+        "averageLineageDuration",
+        "Average Lineage Duration (5 mins)",
+        "The average amount of time that a FlowFile took to process from receipt to drop in the past 5 minutes. For Processors that do not terminate FlowFiles, this value will be 0.",
+        Formatter.DURATION,
+        new ValueMapper<RemoteProcessGroupStatus>() {
+            @Override
+            public Long getValue(final RemoteProcessGroupStatus status) {
+                return status.getAverageLineageDuration(TimeUnit.MILLISECONDS);
+            }
+        }, new ValueReducer<StatusSnapshot, Long>() {
+            @Override
+            public Long reduce(final List<StatusSnapshot> values) {
+                long millis = 0L;
+                int count = 0;
+
+                for (final StatusSnapshot snapshot : values) {
+                    final long sent = snapshot.getStatusMetrics().get(SENT_COUNT.getDescriptor()).longValue();
+                    count += sent;
+
+                    final long avgMillis = snapshot.getStatusMetrics().get(AVERAGE_LINEAGE_DURATION.getDescriptor()).longValue();
+                    final long totalMillis = avgMillis * sent;
+                    millis += totalMillis;
+                }
+
+                return count == 0 ? 0 : millis / count;
+            }
+        }));
+
+    private final MetricDescriptor<RemoteProcessGroupStatus> descriptor;
+
+    private RemoteProcessGroupStatusDescriptor(final MetricDescriptor<RemoteProcessGroupStatus> descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    public String getField() {
+        return descriptor.getField();
+    }
+
+    public MetricDescriptor<RemoteProcessGroupStatus> getDescriptor() {
+        return descriptor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/StatusHistoryUtil.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/StatusHistoryUtil.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/StatusHistoryUtil.java
index 014b0a6..756e576 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/StatusHistoryUtil.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/StatusHistoryUtil.java
@@ -44,9 +44,9 @@ public class StatusHistoryUtil {
 
         final StatusHistoryDTO dto = new StatusHistoryDTO();
         dto.setGenerated(new Date());
-        dto.setDetails(componentDetails);
+        dto.setComponentDetails(componentDetails);
         dto.setFieldDescriptors(StatusHistoryUtil.createFieldDescriptorDtos(metricDescriptors));
-        dto.setStatusSnapshots(snapshotDtos);
+        dto.setAggregateSnapshots(snapshotDtos);
         return dto;
     }
 


[06/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index a67e74b..96beff5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -23,41 +23,23 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
-import org.apache.nifi.web.IllegalClusterResourceRequestException;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
 import org.apache.nifi.web.api.dto.FlowSnippetDTO;
 import org.apache.nifi.web.api.dto.PositionDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.api.entity.FlowSnippetEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
@@ -67,9 +49,33 @@ import org.apache.nifi.web.api.entity.StatusHistoryEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.DoubleParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
 /**
  * RESTful endpoint for managing a Group.
  */
@@ -979,7 +985,7 @@ public class ProcessGroupResource extends ApplicationResource {
             headersToOverride.put("content-type", MediaType.APPLICATION_JSON);
 
             // replicate put request
-            return (Response) clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(processGroupEntity), getHeaders(headersToOverride)).getResponse();
+            return clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(processGroupEntity), getHeaders(headersToOverride)).getResponse();
         }
 
         // handle expects request (usually from the cluster manager)
@@ -1251,7 +1257,7 @@ public class ProcessGroupResource extends ApplicationResource {
      * Retrieves the status report for this NiFi.
      *
      * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param recursive Optional recursive flag that defaults to false. If set to true, all descendent groups and their content will be included if the verbose flag is also set to true.
+     * @param recursive Optional recursive flag that defaults to false. If set to true, all descendant groups and the status of their content will be included.
      * @return A processGroupStatusEntity.
      */
     @GET
@@ -1281,21 +1287,69 @@ public class ProcessGroupResource extends ApplicationResource {
             }
     )
     public Response getProcessGroupStatus(
+            @ApiParam(
+                value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+                required = false
+            )
             @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @QueryParam("recursive") @DefaultValue(RECURSIVE) Boolean recursive) {
+            @ApiParam(
+                value = "Whether all descendant groups and the status of their content will be included. Optional, defaults to false",
+                required = false
+            )
+            @QueryParam("recursive") @DefaultValue(RECURSIVE) Boolean recursive,
+            @ApiParam(
+                value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+                required = false
+            )
+            @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+            @ApiParam(
+                value = "The id of the node where to get the status.",
+                required = false
+            )
+            @QueryParam("clusterNodeId") String clusterNodeId) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final ProcessGroupStatusEntity entity = (ProcessGroupStatusEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getProcessGroupStatus().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
 
         // get the status
         final ProcessGroupStatusDTO statusReport = serviceFacade.getProcessGroupStatus(groupId);
 
         // prune the response as necessary
         if (!recursive) {
-            for (final ProcessGroupStatusDTO childProcessGroupStatus : statusReport.getProcessGroupStatus()) {
-                childProcessGroupStatus.setConnectionStatus(null);
-                childProcessGroupStatus.setProcessGroupStatus(null);
-                childProcessGroupStatus.setInputPortStatus(null);
-                childProcessGroupStatus.setOutputPortStatus(null);
-                childProcessGroupStatus.setProcessorStatus(null);
-                childProcessGroupStatus.setRemoteProcessGroupStatus(null);
+            pruneChildGroups(statusReport.getAggregateSnapshot());
+            if (statusReport.getNodeSnapshots() != null) {
+                for (final NodeProcessGroupStatusSnapshotDTO nodeSnapshot : statusReport.getNodeSnapshots()) {
+                    pruneChildGroups(nodeSnapshot.getStatusSnapshot());
+                }
             }
         }
 
@@ -1312,6 +1366,17 @@ public class ProcessGroupResource extends ApplicationResource {
         return clusterContext(generateOkResponse(entity)).build();
     }
 
+    private void pruneChildGroups(final ProcessGroupStatusSnapshotDTO snapshot) {
+        for (final ProcessGroupStatusSnapshotDTO childProcessGroupStatus : snapshot.getProcessGroupStatusSnapshots()) {
+            childProcessGroupStatus.setConnectionStatusSnapshots(null);
+            childProcessGroupStatus.setProcessGroupStatusSnapshots(null);
+            childProcessGroupStatus.setInputPortStatusSnapshots(null);
+            childProcessGroupStatus.setOutputPortStatusSnapshots(null);
+            childProcessGroupStatus.setProcessorStatusSnapshots(null);
+            childProcessGroupStatus.setRemoteProcessGroupStatusSnapshots(null);
+        }
+    }
+
     /**
      * Retrieves the specified remote process groups status history.
      *
@@ -1345,7 +1410,7 @@ public class ProcessGroupResource extends ApplicationResource {
 
         // replicate if cluster manager
         if (properties.isClusterManager()) {
-            throw new IllegalClusterResourceRequestException("This request is only supported in standalone mode.");
+            return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
         }
 
         // get the specified processor status history

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index 9fb90b5..adede7b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -22,80 +22,77 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.NodeResponse;
 import org.apache.nifi.cluster.manager.exception.IllegalClusterStateException;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
 import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.scheduling.SchedulingStrategy;
+import org.apache.nifi.ui.extension.UiExtension;
+import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
-import org.apache.nifi.web.IllegalClusterResourceRequestException;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
-
+import org.apache.nifi.web.UiExtensionType;
 import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.PositionDTO;
 import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
+import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.api.entity.ComponentStateEntity;
 import org.apache.nifi.web.api.entity.ProcessorEntity;
+import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorsEntity;
+import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
 import org.apache.nifi.web.api.entity.StatusHistoryEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.DoubleParameter;
 import org.apache.nifi.web.api.request.IntegerParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.ui.extension.UiExtension;
-import org.apache.nifi.ui.extension.UiExtensionMapping;
-import org.apache.nifi.web.UiExtensionType;
-import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
-import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
 
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
 /**
  * RESTful endpoint for managing a Processor.
  */
 @Api(hidden = true)
 public class ProcessorResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(ProcessorResource.class);
-
     private static final List<Long> POSSIBLE_RUN_DURATIONS = Arrays.asList(0L, 25L, 50L, 100L, 250L, 500L, 1000L, 2000L);
 
     private NiFiServiceFacade serviceFacade;
@@ -328,7 +325,7 @@ public class ProcessorResource extends ApplicationResource {
             headersToOverride.put("content-type", MediaType.APPLICATION_JSON);
 
             // replicate put request
-            return (Response) clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(processorEntity), getHeaders(headersToOverride)).getResponse();
+            return clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(processorEntity), getHeaders(headersToOverride)).getResponse();
 
         }
 
@@ -424,6 +421,106 @@ public class ProcessorResource extends ApplicationResource {
     }
 
     /**
+     * Retrieves the specified processor status.
+     *
+     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
+     * @param id The id of the processor history to retrieve.
+     * @return A processorStatusEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{id}/status")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets status for a processor",
+        response = ProcessorStatusEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+        }
+    )
+    public Response getProcessorStatus(
+        @ApiParam(
+            value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+            required = false
+        )
+        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+        @ApiParam(
+            value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+            required = false
+        )
+        @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+        @ApiParam(
+            value = "The id of the node where to get the status.",
+            required = false
+        )
+        @QueryParam("clusterNodeId") String clusterNodeId,
+        @ApiParam(
+            value = "The processor id.",
+            required = true
+        )
+        @PathParam("id") String id) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final ProcessorStatusEntity entity = (ProcessorStatusEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getProcessorStatus().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
+
+        // get the specified processor status
+        final ProcessorStatusDTO processorStatus = serviceFacade.getProcessorStatus(groupId, id);
+
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+
+        // generate the response entity
+        final ProcessorStatusEntity entity = new ProcessorStatusEntity();
+        entity.setRevision(revision);
+        entity.setProcessorStatus(processorStatus);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
+    /**
      * Retrieves the specified processor status history.
      *
      * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
@@ -467,7 +564,7 @@ public class ProcessorResource extends ApplicationResource {
 
         // replicate if cluster manager
         if (properties.isClusterManager()) {
-            throw new IllegalClusterResourceRequestException("This request is only supported in standalone mode.");
+            return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
         }
 
         // get the specified processor status history

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
index e466666..8fc6a2c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
@@ -22,64 +22,66 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
-import org.apache.nifi.web.IllegalClusterResourceRequestException;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
-import static org.apache.nifi.web.api.ApplicationResource.VERSION;
 import org.apache.nifi.web.api.dto.PositionDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
+import org.apache.nifi.web.api.entity.ConnectionsEntity;
+import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
+import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupsEntity;
 import org.apache.nifi.web.api.entity.StatusHistoryEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.DoubleParameter;
 import org.apache.nifi.web.api.request.IntegerParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.web.api.entity.ConnectionsEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
 /**
  * RESTful endpoint for managing a Remote group.
  */
 @Api(hidden = true)
 public class RemoteProcessGroupResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(RemoteProcessGroupResource.class);
-
     private static final String VERBOSE_DEFAULT_VALUE = "false";
 
     private NiFiServiceFacade serviceFacade;
@@ -257,6 +259,106 @@ public class RemoteProcessGroupResource extends ApplicationResource {
     }
 
     /**
+     * Retrieves the specified remote process group status.
+     *
+     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
+     * @param id The id of the processor history to retrieve.
+     * @return A remoteProcessGroupStatusEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{id}/status")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets status for a remote process group",
+        response = ProcessorStatusEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+        }
+    )
+    public Response getRemoteProcessGroupStatus(
+        @ApiParam(
+            value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+            required = false
+        )
+        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+        @ApiParam(
+            value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+            required = false
+        )
+        @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+        @ApiParam(
+            value = "The id of the node where to get the status.",
+            required = false
+        )
+        @QueryParam("clusterNodeId") String clusterNodeId,
+        @ApiParam(
+            value = "The remote process group id.",
+            required = true
+        )
+        @PathParam("id") String id) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final RemoteProcessGroupStatusEntity entity = (RemoteProcessGroupStatusEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getRemoteProcessGroupStatus().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
+
+        // get the specified remote process group status
+        final RemoteProcessGroupStatusDTO remoteProcessGroupStatus = serviceFacade.getRemoteProcessGroupStatus(groupId, id);
+
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+
+        // generate the response entity
+        final RemoteProcessGroupStatusEntity entity = new RemoteProcessGroupStatusEntity();
+        entity.setRevision(revision);
+        entity.setRemoteProcessGroupStatus(remoteProcessGroupStatus);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
+    /**
      * Retrieves the specified remote process groups status history.
      *
      * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
@@ -300,7 +402,7 @@ public class RemoteProcessGroupResource extends ApplicationResource {
 
         // replicate if cluster manager
         if (properties.isClusterManager()) {
-            throw new IllegalClusterResourceRequestException("This request is only supported in standalone mode.");
+            return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
         }
 
         // get the specified processor status history
@@ -446,7 +548,7 @@ public class RemoteProcessGroupResource extends ApplicationResource {
             headersToOverride.put("content-type", MediaType.APPLICATION_JSON);
 
             // replicate put request
-            return (Response) clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(remoteProcessGroupEntity), getHeaders(headersToOverride)).getResponse();
+            return clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(remoteProcessGroupEntity), getHeaders(headersToOverride)).getResponse();
         }
 
         // handle expects request (usually from the cluster manager)

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
index d7b77b2..802f46f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
@@ -16,12 +16,6 @@
  */
 package org.apache.nifi.web.api;
 
-import com.wordnik.swagger.annotations.Api;
-import com.wordnik.swagger.annotations.ApiOperation;
-import com.wordnik.swagger.annotations.ApiParam;
-import com.wordnik.swagger.annotations.ApiResponse;
-import com.wordnik.swagger.annotations.ApiResponses;
-import com.wordnik.swagger.annotations.Authorization;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.HashMap;
@@ -30,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -49,39 +44,42 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.ui.extension.UiExtension;
+import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.api.dto.ComponentStateDTO;
-import org.apache.nifi.web.api.dto.RevisionDTO;
-import org.apache.nifi.web.api.entity.ComponentStateEntity;
-import org.apache.nifi.web.api.request.ClientIdParameter;
-import org.apache.nifi.web.api.request.LongParameter;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.ui.extension.UiExtension;
-import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.web.UiExtensionType;
-import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
+import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.entity.ComponentStateEntity;
 import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 import org.apache.nifi.web.api.entity.ReportingTasksEntity;
+import org.apache.nifi.web.api.request.ClientIdParameter;
+import org.apache.nifi.web.api.request.LongParameter;
 import org.apache.nifi.web.util.Availability;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
 
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiParam;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
+import com.wordnik.swagger.annotations.Authorization;
+
 /**
  * RESTful endpoint for managing a Reporting Task.
  */
 @Api(hidden = true)
 public class ReportingTaskResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(ReportingTaskResource.class);
-
     private NiFiServiceFacade serviceFacade;
     private WebClusterManager clusterManager;
     private NiFiProperties properties;
@@ -344,7 +342,7 @@ public class ReportingTaskResource extends ApplicationResource {
             headersToOverride.put("content-type", MediaType.APPLICATION_JSON);
 
             // replicate put request
-            return (Response) clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(reportingTaskEntity), getHeaders(headersToOverride)).getResponse();
+            return clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(reportingTaskEntity), getHeaders(headersToOverride)).getResponse();
         }
 
         // handle expects request (usually from the cluster manager)

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
index 5c3c03a..1bde7bf 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
@@ -22,25 +22,31 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
+import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.NiFiServiceFacade;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
+import org.apache.nifi.web.api.entity.SystemDiagnosticsEntity;
+import org.apache.nifi.web.api.request.ClientIdParameter;
+import org.springframework.security.access.prepost.PreAuthorize;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-
-import org.apache.nifi.web.NiFiServiceFacade;
-import org.apache.nifi.web.api.dto.RevisionDTO;
-import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
-import org.apache.nifi.web.api.entity.SystemDiagnosticsEntity;
-import org.apache.nifi.web.api.request.ClientIdParameter;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.access.prepost.PreAuthorize;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * RESTful endpoint for retrieving system diagnostics.
@@ -52,9 +58,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
 )
 public class SystemDiagnosticsResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(SystemDiagnosticsResource.class);
-
     private NiFiServiceFacade serviceFacade;
+    private WebClusterManager clusterManager;
+    private NiFiProperties properties;
+
 
     /**
      * Gets the system diagnostics for this NiFi instance.
@@ -87,7 +94,49 @@ public class SystemDiagnosticsResource extends ApplicationResource {
                     value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
                     required = false
             )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+            @ApiParam(
+                value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+                required = false
+            )
+            @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+            @ApiParam(
+                value = "The id of the node where to get the status.",
+                required = false
+            )
+            @QueryParam("clusterNodeId") String clusterNodeId) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final SystemDiagnosticsEntity entity = (SystemDiagnosticsEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getSystemDiagnostics().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
 
         final SystemDiagnosticsDTO systemDiagnosticsDto = serviceFacade.getSystemDiagnostics();
 
@@ -108,4 +157,12 @@ public class SystemDiagnosticsResource extends ApplicationResource {
     public void setServiceFacade(NiFiServiceFacade serviceFacade) {
         this.serviceFacade = serviceFacade;
     }
+
+    public void setClusterManager(WebClusterManager clusterManager) {
+        this.clusterManager = clusterManager;
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 6157285..5e7a902 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -39,7 +39,6 @@ import java.util.concurrent.TimeUnit;
 
 import javax.ws.rs.WebApplicationException;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.action.Action;
 import org.apache.nifi.action.component.details.ComponentDetails;
 import org.apache.nifi.action.component.details.ExtensionDetails;
@@ -61,6 +60,7 @@ import org.apache.nifi.annotation.documentation.Tags;
 import org.apache.nifi.authorization.Authority;
 import org.apache.nifi.cluster.HeartbeatPayload;
 import org.apache.nifi.cluster.event.Event;
+import org.apache.nifi.cluster.manager.StatusMerger;
 import org.apache.nifi.cluster.node.Node;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.components.AllowableValue;
@@ -145,11 +145,15 @@ import org.apache.nifi.web.api.dto.provenance.lineage.LineageResultsDTO;
 import org.apache.nifi.web.api.dto.provenance.lineage.ProvenanceLinkDTO;
 import org.apache.nifi.web.api.dto.provenance.lineage.ProvenanceNodeDTO;
 import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.PortStatusDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.StatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
 
 public final class DtoFactory {
 
@@ -161,8 +165,6 @@ public final class DtoFactory {
         }
     };
 
-    final static int MAX_BULLETINS_PER_COMPONENT = 5;
-
     private ControllerServiceLookup controllerServiceLookup;
 
     /**
@@ -323,7 +325,7 @@ public final class DtoFactory {
         final StateMapDTO dto = new StateMapDTO();
         dto.setScope(scope.toString());
 
-        final TreeMap<String, String> sortedState = new TreeMap(SortedStateUtils.getKeyComparator());
+        final TreeMap<String, String> sortedState = new TreeMap<>(SortedStateUtils.getKeyComparator());
         final Map<String, String> state = stateMap.toMap();
         sortedState.putAll(state);
 
@@ -349,8 +351,8 @@ public final class DtoFactory {
      * @param counterDtos dtos
      * @return dto
      */
-    public CountersDTO createCountersDto(final Collection<CounterDTO> counterDtos) {
-        final CountersDTO dto = new CountersDTO();
+    public CountersSnapshotDTO createCountersDto(final Collection<CounterDTO> counterDtos) {
+        final CountersSnapshotDTO dto = new CountersSnapshotDTO();
         dto.setCounters(counterDtos);
         dto.setGenerated(new Date());
         return dto;
@@ -709,13 +711,6 @@ public final class DtoFactory {
         return copy;
     }
 
-    private String formatCount(final Integer intStatus) {
-        return intStatus == null ? "-" : FormatUtils.formatCount(intStatus);
-    }
-
-    private String formatDataSize(final Long longStatus) {
-        return longStatus == null ? "-" : FormatUtils.formatDataSize(longStatus);
-    }
 
     public RemoteProcessGroupStatusDTO createRemoteProcessGroupStatusDto(final RemoteProcessGroupStatus remoteProcessGroupStatus) {
         final RemoteProcessGroupStatusDTO dto = new RemoteProcessGroupStatusDTO();
@@ -724,172 +719,120 @@ public final class DtoFactory {
         dto.setTargetUri(remoteProcessGroupStatus.getTargetUri());
         dto.setName(remoteProcessGroupStatus.getName());
         dto.setTransmissionStatus(remoteProcessGroupStatus.getTransmissionStatus().toString());
-        dto.setActiveThreadCount(remoteProcessGroupStatus.getActiveThreadCount());
-        dto.setSent(formatCount(remoteProcessGroupStatus.getSentCount()) + " / " + formatDataSize(remoteProcessGroupStatus.getSentContentSize()));
-        dto.setReceived(formatCount(remoteProcessGroupStatus.getReceivedCount()) + " / " + formatDataSize(remoteProcessGroupStatus.getReceivedContentSize()));
-        dto.setAuthorizationIssues(remoteProcessGroupStatus.getAuthorizationIssues());
+        dto.setStatsLastRefreshed(new Date());
+
+        final RemoteProcessGroupStatusSnapshotDTO snapshot = new RemoteProcessGroupStatusSnapshotDTO();
+        dto.setAggregateSnapshot(snapshot);
 
+        snapshot.setId(remoteProcessGroupStatus.getId());
+        snapshot.setGroupId(remoteProcessGroupStatus.getGroupId());
+        snapshot.setName(remoteProcessGroupStatus.getName());
+        snapshot.setTargetUri(remoteProcessGroupStatus.getTargetUri());
+        snapshot.setTransmissionStatus(remoteProcessGroupStatus.getTransmissionStatus().toString());
+
+        snapshot.setActiveThreadCount(remoteProcessGroupStatus.getActiveThreadCount());
+        snapshot.setFlowFilesSent(remoteProcessGroupStatus.getSentCount());
+        snapshot.setBytesSent(remoteProcessGroupStatus.getSentContentSize());
+        snapshot.setFlowFilesReceived(remoteProcessGroupStatus.getReceivedCount());
+        snapshot.setBytesReceived(remoteProcessGroupStatus.getReceivedContentSize());
+        snapshot.setAuthorizationIssues(remoteProcessGroupStatus.getAuthorizationIssues());
+
+        StatusMerger.updatePrettyPrintedFields(snapshot);
         return dto;
     }
 
     public ProcessGroupStatusDTO createProcessGroupStatusDto(final BulletinRepository bulletinRepository, final ProcessGroupStatus processGroupStatus) {
-
         final ProcessGroupStatusDTO processGroupStatusDto = new ProcessGroupStatusDTO();
         processGroupStatusDto.setId(processGroupStatus.getId());
         processGroupStatusDto.setName(processGroupStatus.getName());
-        processGroupStatusDto.setStatsLastRefreshed(new Date(processGroupStatus.getCreationTimestamp()));
-        processGroupStatusDto.setRead(formatDataSize(processGroupStatus.getBytesRead()));
-        processGroupStatusDto.setWritten(formatDataSize(processGroupStatus.getBytesWritten()));
-        processGroupStatusDto.setInput(formatCount(processGroupStatus.getInputCount()) + " / " + formatDataSize(processGroupStatus.getInputContentSize()));
-        processGroupStatusDto.setOutput(formatCount(processGroupStatus.getOutputCount()) + " / " + formatDataSize(processGroupStatus.getOutputContentSize()));
-        processGroupStatusDto.setTransferred(formatCount(processGroupStatus.getFlowFilesTransferred()) + " / " + formatDataSize(processGroupStatus.getBytesTransferred()));
-        processGroupStatusDto.setSent(formatCount(processGroupStatus.getFlowFilesSent()) + " / " + formatDataSize(processGroupStatus.getBytesSent()));
-        processGroupStatusDto.setReceived(formatCount(processGroupStatus.getFlowFilesReceived()) + " / " + formatDataSize(processGroupStatus.getBytesReceived()));
-        processGroupStatusDto.setActiveThreadCount(processGroupStatus.getActiveThreadCount());
-
-        final String queuedCount = FormatUtils.formatCount(processGroupStatus.getQueuedCount());
-        final String queuedSize = FormatUtils.formatDataSize(processGroupStatus.getQueuedContentSize());
-        processGroupStatusDto.setQueuedCount(queuedCount);
-        processGroupStatusDto.setQueuedSize(queuedSize);
-        processGroupStatusDto.setQueued(queuedCount + " / " + queuedSize);
-
-        final Map<String, StatusDTO> componentStatusDtoMap = new HashMap<>();
+        processGroupStatusDto.setStatsLastRefreshed(new Date());
+
+        final ProcessGroupStatusSnapshotDTO snapshot = new ProcessGroupStatusSnapshotDTO();
+        processGroupStatusDto.setAggregateSnapshot(snapshot);
+
+        snapshot.setId(processGroupStatus.getId());
+        snapshot.setName(processGroupStatus.getName());
+
+        snapshot.setFlowFilesQueued(processGroupStatus.getQueuedCount());
+        snapshot.setBytesQueued(processGroupStatus.getQueuedContentSize());
+        snapshot.setBytesRead(processGroupStatus.getBytesRead());
+        snapshot.setBytesWritten(processGroupStatus.getBytesWritten());
+        snapshot.setFlowFilesIn(processGroupStatus.getInputCount());
+        snapshot.setBytesIn(processGroupStatus.getInputContentSize());
+        snapshot.setFlowFilesOut(processGroupStatus.getOutputCount());
+        snapshot.setBytesOut(processGroupStatus.getOutputContentSize());
+        snapshot.setFlowFilesTransferred(processGroupStatus.getFlowFilesTransferred());
+        snapshot.setBytesTransferred(processGroupStatus.getBytesTransferred());
+        snapshot.setFlowFilesSent(processGroupStatus.getFlowFilesSent());
+        snapshot.setBytesSent(processGroupStatus.getBytesSent());
+        snapshot.setFlowFilesReceived(processGroupStatus.getFlowFilesReceived());
+        snapshot.setBytesReceived(processGroupStatus.getBytesReceived());
+        snapshot.setActiveThreadCount(processGroupStatus.getActiveThreadCount());
+        StatusMerger.updatePrettyPrintedFields(snapshot);
 
         // processor status
-        final Collection<ProcessorStatusDTO> processorStatDtoCollection = new ArrayList<>();
-        processGroupStatusDto.setProcessorStatus(processorStatDtoCollection);
+        final Collection<ProcessorStatusSnapshotDTO> processorStatDtoCollection = new ArrayList<>();
+        snapshot.setProcessorStatusSnapshots(processorStatDtoCollection);
         final Collection<ProcessorStatus> processorStatusCollection = processGroupStatus.getProcessorStatus();
         if (processorStatusCollection != null) {
             for (final ProcessorStatus processorStatus : processorStatusCollection) {
                 final ProcessorStatusDTO processorStatusDto = createProcessorStatusDto(processorStatus);
-                processorStatDtoCollection.add(processorStatusDto);
-                componentStatusDtoMap.put(processorStatusDto.getId(), processorStatusDto);
+                processorStatDtoCollection.add(processorStatusDto.getAggregateSnapshot());
             }
         }
 
         // connection status
-        final Collection<ConnectionStatusDTO> connectionStatusDtoCollection = new ArrayList<>();
-        processGroupStatusDto.setConnectionStatus(connectionStatusDtoCollection);
+        final Collection<ConnectionStatusSnapshotDTO> connectionStatusDtoCollection = new ArrayList<>();
+        snapshot.setConnectionStatusSnapshots(connectionStatusDtoCollection);
         final Collection<ConnectionStatus> connectionStatusCollection = processGroupStatus.getConnectionStatus();
         if (connectionStatusCollection != null) {
             for (final ConnectionStatus connectionStatus : connectionStatusCollection) {
                 final ConnectionStatusDTO connectionStatusDto = createConnectionStatusDto(connectionStatus);
-                connectionStatusDtoCollection.add(connectionStatusDto);
+                connectionStatusDtoCollection.add(connectionStatusDto.getAggregateSnapshot());
             }
         }
 
         // local child process groups
-        final Collection<ProcessGroupStatusDTO> childProcessGroupStatusDtoCollection = new ArrayList<>();
-        processGroupStatusDto.setProcessGroupStatus(childProcessGroupStatusDtoCollection);
+        final Collection<ProcessGroupStatusSnapshotDTO> childProcessGroupStatusDtoCollection = new ArrayList<>();
+        snapshot.setProcessGroupStatusSnapshots(childProcessGroupStatusDtoCollection);
         final Collection<ProcessGroupStatus> childProcessGroupStatusCollection = processGroupStatus.getProcessGroupStatus();
         if (childProcessGroupStatusCollection != null) {
             for (final ProcessGroupStatus childProcessGroupStatus : childProcessGroupStatusCollection) {
                 final ProcessGroupStatusDTO childProcessGroupStatusDto = createProcessGroupStatusDto(bulletinRepository, childProcessGroupStatus);
-                childProcessGroupStatusDtoCollection.add(childProcessGroupStatusDto);
+                childProcessGroupStatusDtoCollection.add(childProcessGroupStatusDto.getAggregateSnapshot());
             }
         }
 
         // remote child process groups
-        final Collection<RemoteProcessGroupStatusDTO> childRemoteProcessGroupStatusDtoCollection = new ArrayList<>();
-        processGroupStatusDto.setRemoteProcessGroupStatus(childRemoteProcessGroupStatusDtoCollection);
+        final Collection<RemoteProcessGroupStatusSnapshotDTO> childRemoteProcessGroupStatusDtoCollection = new ArrayList<>();
+        snapshot.setRemoteProcessGroupStatusSnapshots(childRemoteProcessGroupStatusDtoCollection);
         final Collection<RemoteProcessGroupStatus> childRemoteProcessGroupStatusCollection = processGroupStatus.getRemoteProcessGroupStatus();
         if (childRemoteProcessGroupStatusCollection != null) {
             for (final RemoteProcessGroupStatus childRemoteProcessGroupStatus : childRemoteProcessGroupStatusCollection) {
                 final RemoteProcessGroupStatusDTO childRemoteProcessGroupStatusDto = createRemoteProcessGroupStatusDto(childRemoteProcessGroupStatus);
-                childRemoteProcessGroupStatusDtoCollection.add(childRemoteProcessGroupStatusDto);
-                componentStatusDtoMap.put(childRemoteProcessGroupStatusDto.getId(), childRemoteProcessGroupStatusDto);
+                childRemoteProcessGroupStatusDtoCollection.add(childRemoteProcessGroupStatusDto.getAggregateSnapshot());
             }
         }
 
         // input ports
-        final Collection<PortStatusDTO> inputPortStatusDtoCollection = new ArrayList<>();
-        processGroupStatusDto.setInputPortStatus(inputPortStatusDtoCollection);
+        final Collection<PortStatusSnapshotDTO> inputPortStatusDtoCollection = new ArrayList<>();
+        snapshot.setInputPortStatusSnapshots(inputPortStatusDtoCollection);
         final Collection<PortStatus> inputPortStatusCollection = processGroupStatus.getInputPortStatus();
         if (inputPortStatusCollection != null) {
             for (final PortStatus portStatus : inputPortStatusCollection) {
                 final PortStatusDTO portStatusDto = createPortStatusDto(portStatus);
-                inputPortStatusDtoCollection.add(portStatusDto);
-                componentStatusDtoMap.put(portStatusDto.getId(), portStatusDto);
+                inputPortStatusDtoCollection.add(portStatusDto.getAggregateSnapshot());
             }
         }
 
         // output ports
-        final Collection<PortStatusDTO> outputPortStatusDtoCollection = new ArrayList<>();
-        processGroupStatusDto.setOutputPortStatus(outputPortStatusDtoCollection);
+        final Collection<PortStatusSnapshotDTO> outputPortStatusDtoCollection = new ArrayList<>();
+        snapshot.setOutputPortStatusSnapshots(outputPortStatusDtoCollection);
         final Collection<PortStatus> outputPortStatusCollection = processGroupStatus.getOutputPortStatus();
         if (outputPortStatusCollection != null) {
             for (final PortStatus portStatus : outputPortStatusCollection) {
                 final PortStatusDTO portStatusDto = createPortStatusDto(portStatus);
-                outputPortStatusDtoCollection.add(portStatusDto);
-                componentStatusDtoMap.put(portStatusDto.getId(), portStatusDto);
-            }
-        }
-
-        // get the bulletins for this group and associate with the specific child component
-        if (bulletinRepository != null) {
-            if (processGroupStatusDto.getBulletins() == null) {
-                processGroupStatusDto.setBulletins(new ArrayList<BulletinDTO>());
-            }
-
-            // locate bulletins for this process group
-            final List<Bulletin> results = bulletinRepository.findBulletinsForGroupBySource(processGroupStatus.getId(), MAX_BULLETINS_PER_COMPONENT);
-            for (final Bulletin bulletin : results) {
-                final StatusDTO status = componentStatusDtoMap.get(bulletin.getSourceId());
-
-                // ensure this connectable is still in the flow
-                if (status != null) {
-                    if (status.getBulletins() == null) {
-                        status.setBulletins(new ArrayList<BulletinDTO>());
-                    }
-
-                    // convert the result into a dto
-                    final BulletinDTO bulletinDto = createBulletinDto(bulletin);
-                    status.getBulletins().add(bulletinDto);
-
-                    // create a copy for the parent group
-                    final BulletinDTO copy = copy(bulletinDto);
-                    copy.setGroupId(StringUtils.EMPTY);
-                    copy.setSourceId(processGroupStatus.getId());
-                    copy.setSourceName(processGroupStatus.getName());
-                    processGroupStatusDto.getBulletins().add(copy);
-                }
-            }
-
-            // copy over descendant bulletins
-            for (final ProcessGroupStatusDTO childProcessGroupStatusDto : processGroupStatusDto.getProcessGroupStatus()) {
-                if (childProcessGroupStatusDto.getBulletins() != null) {
-                    for (final BulletinDTO descendantBulletinDto : childProcessGroupStatusDto.getBulletins()) {
-                        // create a copy for the parent group
-                        final BulletinDTO copy = copy(descendantBulletinDto);
-                        copy.setGroupId(StringUtils.EMPTY);
-                        copy.setSourceId(processGroupStatus.getId());
-                        copy.setSourceName(processGroupStatus.getName());
-                        processGroupStatusDto.getBulletins().add(copy);
-                    }
-                }
-            }
-
-            // sort the bulletins
-            Collections.sort(processGroupStatusDto.getBulletins(), new Comparator<BulletinDTO>() {
-                @Override
-                public int compare(BulletinDTO o1, BulletinDTO o2) {
-                    if (o1 == null && o2 == null) {
-                        return 0;
-                    }
-                    if (o1 == null) {
-                        return 1;
-                    }
-                    if (o2 == null) {
-                        return -1;
-                    }
-
-                    return -Long.compare(o1.getId(), o2.getId());
-                }
-            });
-
-            // prune the response to only include the max number of bulletins
-            if (processGroupStatusDto.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) {
-                processGroupStatusDto.setBulletins(processGroupStatusDto.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT));
+                outputPortStatusDtoCollection.add(portStatusDto.getAggregateSnapshot());
             }
         }
 
@@ -897,7 +840,6 @@ public final class DtoFactory {
     }
 
     public ConnectionStatusDTO createConnectionStatusDto(final ConnectionStatus connectionStatus) {
-
         final ConnectionStatusDTO connectionStatusDto = new ConnectionStatusDTO();
         connectionStatusDto.setGroupId(connectionStatus.getGroupId());
         connectionStatusDto.setId(connectionStatus.getId());
@@ -906,54 +848,64 @@ public final class DtoFactory {
         connectionStatusDto.setSourceName(connectionStatus.getSourceName());
         connectionStatusDto.setDestinationId(connectionStatus.getDestinationId());
         connectionStatusDto.setDestinationName(connectionStatus.getDestinationName());
+        connectionStatusDto.setStatsLastRefreshed(new Date());
+
+        final ConnectionStatusSnapshotDTO snapshot = new ConnectionStatusSnapshotDTO();
+        connectionStatusDto.setAggregateSnapshot(snapshot);
+
+        snapshot.setId(connectionStatus.getId());
+        snapshot.setGroupId(connectionStatus.getGroupId());
+        snapshot.setName(connectionStatus.getName());
+        snapshot.setSourceName(connectionStatus.getSourceName());
+        snapshot.setDestinationName(connectionStatus.getDestinationName());
 
-        final String queuedCount = FormatUtils.formatCount(connectionStatus.getQueuedCount());
-        final String queuedSize = FormatUtils.formatDataSize(connectionStatus.getQueuedBytes());
-        connectionStatusDto.setQueuedCount(queuedCount);
-        connectionStatusDto.setQueuedSize(queuedSize);
-        connectionStatusDto.setQueued(queuedCount + " / " + queuedSize);
+        snapshot.setFlowFilesQueued(connectionStatus.getQueuedCount());
+        snapshot.setBytesQueued(connectionStatus.getQueuedBytes());
 
-        final int inputCount = connectionStatus.getInputCount();
-        final long inputBytes = connectionStatus.getInputBytes();
-        connectionStatusDto.setInput(FormatUtils.formatCount(inputCount) + " / " + FormatUtils.formatDataSize(inputBytes));
+        snapshot.setFlowFilesIn(connectionStatus.getInputCount());
+        snapshot.setBytesIn(connectionStatus.getInputBytes());
 
-        final int outputCount = connectionStatus.getOutputCount();
-        final long outputBytes = connectionStatus.getOutputBytes();
-        connectionStatusDto.setOutput(FormatUtils.formatCount(outputCount) + " / " + FormatUtils.formatDataSize(outputBytes));
+        snapshot.setFlowFilesOut(connectionStatus.getOutputCount());
+        snapshot.setBytesOut(connectionStatus.getOutputBytes());
+        StatusMerger.updatePrettyPrintedFields(snapshot);
 
         return connectionStatusDto;
     }
 
     public ProcessorStatusDTO createProcessorStatusDto(final ProcessorStatus procStatus) {
-
         final ProcessorStatusDTO dto = new ProcessorStatusDTO();
         dto.setId(procStatus.getId());
         dto.setGroupId(procStatus.getGroupId());
         dto.setName(procStatus.getName());
+        dto.setStatsLastRefreshed(new Date());
+
+        final ProcessorStatusSnapshotDTO snapshot = new ProcessorStatusSnapshotDTO();
+        dto.setAggregateSnapshot(snapshot);
 
-        final int processedCount = procStatus.getOutputCount();
-        final long numProcessedBytes = procStatus.getOutputBytes();
-        dto.setOutput(FormatUtils.formatCount(processedCount) + " / " + FormatUtils.formatDataSize(numProcessedBytes));
+        snapshot.setId(procStatus.getId());
+        snapshot.setGroupId(procStatus.getGroupId());
+        snapshot.setName(procStatus.getName());
 
-        final int inputCount = procStatus.getInputCount();
-        final long inputBytes = procStatus.getInputBytes();
-        dto.setInput(FormatUtils.formatCount(inputCount) + " / " + FormatUtils.formatDataSize(inputBytes));
+        snapshot.setFlowFilesOut(procStatus.getOutputCount());
+        snapshot.setBytesOut(procStatus.getOutputBytes());
 
-        final long readBytes = procStatus.getBytesRead();
-        dto.setRead(FormatUtils.formatDataSize(readBytes));
+        snapshot.setFlowFilesIn(procStatus.getInputCount());
+        snapshot.setBytesIn(procStatus.getInputBytes());
 
-        final long writtenBytes = procStatus.getBytesWritten();
-        dto.setWritten(FormatUtils.formatDataSize(writtenBytes));
+        snapshot.setBytesRead(procStatus.getBytesRead());
+        snapshot.setBytesWritten(procStatus.getBytesWritten());
 
-        dto.setTasksDuration(FormatUtils.formatHoursMinutesSeconds(procStatus.getProcessingNanos(), TimeUnit.NANOSECONDS));
-        dto.setTasks(FormatUtils.formatCount(procStatus.getInvocations()));
+        snapshot.setTaskCount(procStatus.getInvocations());
+        snapshot.setTasksDurationNanos(procStatus.getProcessingNanos());
+        snapshot.setTasksDuration(FormatUtils.formatHoursMinutesSeconds(procStatus.getProcessingNanos(), TimeUnit.NANOSECONDS));
 
         // determine the run status
-        dto.setRunStatus(procStatus.getRunStatus().toString());
+        snapshot.setRunStatus(procStatus.getRunStatus().toString());
 
-        dto.setActiveThreadCount(procStatus.getActiveThreadCount());
-        dto.setType(procStatus.getType());
+        snapshot.setActiveThreadCount(procStatus.getActiveThreadCount());
+        snapshot.setType(procStatus.getType());
 
+        StatusMerger.updatePrettyPrintedFields(snapshot);
         return dto;
     }
 
@@ -968,17 +920,25 @@ public final class DtoFactory {
         dto.setId(portStatus.getId());
         dto.setGroupId(portStatus.getGroupId());
         dto.setName(portStatus.getName());
-        dto.setActiveThreadCount(portStatus.getActiveThreadCount());
         dto.setRunStatus(portStatus.getRunStatus().toString());
         dto.setTransmitting(portStatus.isTransmitting());
+        dto.setStatsLastRefreshed(new Date());
 
-        final int processedCount = portStatus.getOutputCount();
-        final long numProcessedBytes = portStatus.getOutputBytes();
-        dto.setOutput(FormatUtils.formatCount(processedCount) + " / " + FormatUtils.formatDataSize(numProcessedBytes));
+        final PortStatusSnapshotDTO snapshot = new PortStatusSnapshotDTO();
+        dto.setAggregateSnapshot(snapshot);
 
-        final int inputCount = portStatus.getInputCount();
-        final long inputBytes = portStatus.getInputBytes();
-        dto.setInput(FormatUtils.formatCount(inputCount) + " / " + FormatUtils.formatDataSize(inputBytes));
+        snapshot.setId(portStatus.getId());
+        snapshot.setGroupId(portStatus.getGroupId());
+        snapshot.setName(portStatus.getName());
+        snapshot.setRunStatus(portStatus.getRunStatus().toString());
+
+        snapshot.setActiveThreadCount(portStatus.getActiveThreadCount());
+        snapshot.setFlowFilesOut(portStatus.getOutputCount());
+        snapshot.setBytesOut(portStatus.getOutputBytes());
+
+        snapshot.setFlowFilesIn(portStatus.getInputCount());
+        snapshot.setBytesIn(portStatus.getInputBytes());
+        StatusMerger.updatePrettyPrintedFields(snapshot);
 
         return dto;
     }
@@ -1766,6 +1726,7 @@ public final class DtoFactory {
      * @param node node
      * @return dto
      */
+    @SuppressWarnings("deprecation")
     public ProvenanceNodeDTO createProvenanceEventNodeDTO(final ProvenanceEventLineageNode node) {
         final ProvenanceNodeDTO dto = new ProvenanceNodeDTO();
         dto.setId(node.getIdentifier());
@@ -1786,6 +1747,7 @@ public final class DtoFactory {
      * @param node node
      * @return dto
      */
+    @SuppressWarnings("deprecation")
     public ProvenanceNodeDTO createFlowFileNodeDTO(final LineageNode node) {
         final ProvenanceNodeDTO dto = new ProvenanceNodeDTO();
         dto.setId(node.getIdentifier());
@@ -1906,48 +1868,59 @@ public final class DtoFactory {
     public SystemDiagnosticsDTO createSystemDiagnosticsDto(final SystemDiagnostics sysDiagnostics) {
 
         final SystemDiagnosticsDTO dto = new SystemDiagnosticsDTO();
-        dto.setStatsLastRefreshed(new Date(sysDiagnostics.getCreationTimestamp()));
+        final SystemDiagnosticsSnapshotDTO snapshot = new SystemDiagnosticsSnapshotDTO();
+        dto.setAggregateSnapshot(snapshot);
+
+        snapshot.setStatsLastRefreshed(new Date(sysDiagnostics.getCreationTimestamp()));
 
         // processors
-        dto.setAvailableProcessors(sysDiagnostics.getAvailableProcessors());
-        dto.setProcessorLoadAverage(sysDiagnostics.getProcessorLoadAverage());
+        snapshot.setAvailableProcessors(sysDiagnostics.getAvailableProcessors());
+        snapshot.setProcessorLoadAverage(sysDiagnostics.getProcessorLoadAverage());
 
         // threads
-        dto.setDaemonThreads(sysDiagnostics.getDaemonThreads());
-        dto.setTotalThreads(sysDiagnostics.getTotalThreads());
+        snapshot.setDaemonThreads(sysDiagnostics.getDaemonThreads());
+        snapshot.setTotalThreads(sysDiagnostics.getTotalThreads());
 
         // heap
-        dto.setMaxHeap(FormatUtils.formatDataSize(sysDiagnostics.getMaxHeap()));
-        dto.setTotalHeap(FormatUtils.formatDataSize(sysDiagnostics.getTotalHeap()));
-        dto.setUsedHeap(FormatUtils.formatDataSize(sysDiagnostics.getUsedHeap()));
-        dto.setFreeHeap(FormatUtils.formatDataSize(sysDiagnostics.getFreeHeap()));
+        snapshot.setMaxHeap(FormatUtils.formatDataSize(sysDiagnostics.getMaxHeap()));
+        snapshot.setMaxHeapBytes(sysDiagnostics.getMaxHeap());
+        snapshot.setTotalHeap(FormatUtils.formatDataSize(sysDiagnostics.getTotalHeap()));
+        snapshot.setTotalHeapBytes(sysDiagnostics.getTotalHeap());
+        snapshot.setUsedHeap(FormatUtils.formatDataSize(sysDiagnostics.getUsedHeap()));
+        snapshot.setUsedHeapBytes(sysDiagnostics.getUsedHeap());
+        snapshot.setFreeHeap(FormatUtils.formatDataSize(sysDiagnostics.getFreeHeap()));
+        snapshot.setFreeHeapBytes(sysDiagnostics.getFreeHeap());
         if (sysDiagnostics.getHeapUtilization() != -1) {
-            dto.setHeapUtilization(FormatUtils.formatUtilization(sysDiagnostics.getHeapUtilization()));
+            snapshot.setHeapUtilization(FormatUtils.formatUtilization(sysDiagnostics.getHeapUtilization()));
         }
 
         // non heap
-        dto.setMaxNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getMaxNonHeap()));
-        dto.setTotalNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getTotalNonHeap()));
-        dto.setUsedNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getUsedNonHeap()));
-        dto.setFreeNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getFreeNonHeap()));
+        snapshot.setMaxNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getMaxNonHeap()));
+        snapshot.setMaxNonHeapBytes(sysDiagnostics.getMaxNonHeap());
+        snapshot.setTotalNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getTotalNonHeap()));
+        snapshot.setTotalNonHeapBytes(sysDiagnostics.getTotalNonHeap());
+        snapshot.setUsedNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getUsedNonHeap()));
+        snapshot.setUsedNonHeapBytes(sysDiagnostics.getUsedNonHeap());
+        snapshot.setFreeNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getFreeNonHeap()));
+        snapshot.setFreeNonHeapBytes(sysDiagnostics.getFreeNonHeap());
         if (sysDiagnostics.getNonHeapUtilization() != -1) {
-            dto.setNonHeapUtilization(FormatUtils.formatUtilization(sysDiagnostics.getNonHeapUtilization()));
+            snapshot.setNonHeapUtilization(FormatUtils.formatUtilization(sysDiagnostics.getNonHeapUtilization()));
         }
 
         // flow file disk usage
-        final SystemDiagnosticsDTO.StorageUsageDTO flowFileRepositoryStorageUsageDto = createStorageUsageDTO(null, sysDiagnostics.getFlowFileRepositoryStorageUsage());
-        dto.setFlowFileRepositoryStorageUsage(flowFileRepositoryStorageUsageDto);
+        final SystemDiagnosticsSnapshotDTO.StorageUsageDTO flowFileRepositoryStorageUsageDto = createStorageUsageDTO(null, sysDiagnostics.getFlowFileRepositoryStorageUsage());
+        snapshot.setFlowFileRepositoryStorageUsage(flowFileRepositoryStorageUsageDto);
 
         // content disk usage
-        final Set<SystemDiagnosticsDTO.StorageUsageDTO> contentRepositoryStorageUsageDtos = new LinkedHashSet<>();
-        dto.setContentRepositoryStorageUsage(contentRepositoryStorageUsageDtos);
+        final Set<SystemDiagnosticsSnapshotDTO.StorageUsageDTO> contentRepositoryStorageUsageDtos = new LinkedHashSet<>();
+        snapshot.setContentRepositoryStorageUsage(contentRepositoryStorageUsageDtos);
         for (final Map.Entry<String, StorageUsage> entry : sysDiagnostics.getContentRepositoryStorageUsage().entrySet()) {
             contentRepositoryStorageUsageDtos.add(createStorageUsageDTO(entry.getKey(), entry.getValue()));
         }
 
         // garbage collection
-        final Set<SystemDiagnosticsDTO.GarbageCollectionDTO> garbageCollectionDtos = new LinkedHashSet<>();
-        dto.setGarbageCollection(garbageCollectionDtos);
+        final Set<SystemDiagnosticsSnapshotDTO.GarbageCollectionDTO> garbageCollectionDtos = new LinkedHashSet<>();
+        snapshot.setGarbageCollection(garbageCollectionDtos);
         for (final Map.Entry<String, GarbageCollection> entry : sysDiagnostics.getGarbageCollection().entrySet()) {
             garbageCollectionDtos.add(createGarbageCollectionDTO(entry.getKey(), entry.getValue()));
         }
@@ -1962,8 +1935,8 @@ public final class DtoFactory {
      * @param storageUsage usage
      * @return dto
      */
-    public SystemDiagnosticsDTO.StorageUsageDTO createStorageUsageDTO(final String identifier, final StorageUsage storageUsage) {
-        final SystemDiagnosticsDTO.StorageUsageDTO dto = new SystemDiagnosticsDTO.StorageUsageDTO();
+    public SystemDiagnosticsSnapshotDTO.StorageUsageDTO createStorageUsageDTO(final String identifier, final StorageUsage storageUsage) {
+        final SystemDiagnosticsSnapshotDTO.StorageUsageDTO dto = new SystemDiagnosticsSnapshotDTO.StorageUsageDTO();
         dto.setIdentifier(identifier);
         dto.setFreeSpace(FormatUtils.formatDataSize(storageUsage.getFreeSpace()));
         dto.setTotalSpace(FormatUtils.formatDataSize(storageUsage.getTotalSpace()));
@@ -1982,11 +1955,12 @@ public final class DtoFactory {
      * @param garbageCollection gc
      * @return dto
      */
-    public SystemDiagnosticsDTO.GarbageCollectionDTO createGarbageCollectionDTO(final String name, final GarbageCollection garbageCollection) {
-        final SystemDiagnosticsDTO.GarbageCollectionDTO dto = new SystemDiagnosticsDTO.GarbageCollectionDTO();
+    public SystemDiagnosticsSnapshotDTO.GarbageCollectionDTO createGarbageCollectionDTO(final String name, final GarbageCollection garbageCollection) {
+        final SystemDiagnosticsSnapshotDTO.GarbageCollectionDTO dto = new SystemDiagnosticsSnapshotDTO.GarbageCollectionDTO();
         dto.setName(name);
         dto.setCollectionCount(garbageCollection.getCollectionCount());
         dto.setCollectionTime(FormatUtils.formatHoursMinutesSeconds(garbageCollection.getCollectionTime(), TimeUnit.MILLISECONDS));
+        dto.setCollectionMillis(garbageCollection.getCollectionTime());
         return dto;
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index a349f2a..68d0dbe 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -37,7 +37,11 @@ import org.apache.nifi.controller.queue.FlowFileQueue;
 import org.apache.nifi.controller.queue.QueueSize;
 import org.apache.nifi.controller.repository.ContentNotFoundException;
 import org.apache.nifi.controller.repository.claim.ContentDirection;
+import org.apache.nifi.controller.status.ConnectionStatus;
+import org.apache.nifi.controller.status.PortStatus;
 import org.apache.nifi.controller.status.ProcessGroupStatus;
+import org.apache.nifi.controller.status.ProcessorStatus;
+import org.apache.nifi.controller.status.RemoteProcessGroupStatus;
 import org.apache.nifi.diagnostics.SystemDiagnostics;
 import org.apache.nifi.flowfile.FlowFilePrioritizer;
 import org.apache.nifi.flowfile.attributes.CoreAttributes;
@@ -89,8 +93,12 @@ import org.apache.nifi.web.api.dto.provenance.lineage.LineageRequestDTO;
 import org.apache.nifi.web.api.dto.provenance.lineage.LineageRequestDTO.LineageRequestType;
 import org.apache.nifi.web.api.dto.search.ComponentSearchResultDTO;
 import org.apache.nifi.web.api.dto.search.SearchResultsDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
 import org.apache.nifi.web.api.dto.status.ControllerStatusDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
 import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.security.ProxiedEntitiesUtils;
 import org.apache.nifi.web.security.user.NiFiUserUtils;
@@ -439,6 +447,8 @@ public class ControllerFacade {
         final ControllerStatusDTO controllerStatus = new ControllerStatusDTO();
         controllerStatus.setActiveThreadCount(flowController.getActiveThreadCount());
         controllerStatus.setQueued(FormatUtils.formatCount(controllerQueueSize.getObjectCount()) + " / " + FormatUtils.formatDataSize(controllerQueueSize.getByteCount()));
+        controllerStatus.setBytesQueued(controllerQueueSize.getByteCount());
+        controllerStatus.setFlowFilesQueued(controllerQueueSize.getObjectCount());
 
         final BulletinRepository bulletinRepository = getBulletinRepository();
         controllerStatus.setBulletins(dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForController()));
@@ -477,6 +487,116 @@ public class ControllerFacade {
     }
 
     /**
+     * Gets the status for the specified processor.
+     *
+     * @param groupId group id
+     * @param processorId processor id
+     * @return the status for the specified processor
+     */
+    public ProcessorStatusDTO getProcessorStatus(final String groupId, final String processorId) {
+        final ProcessGroupStatus processGroupStatus = flowController.getGroupStatus(groupId);
+        if (processGroupStatus == null) {
+            throw new ResourceNotFoundException(String.format("Unable to locate group with id '%s'.", groupId));
+        }
+
+        for (final ProcessorStatus processorStatus : processGroupStatus.getProcessorStatus()) {
+            if (processorId.equals(processorStatus.getId())) {
+                return dtoFactory.createProcessorStatusDto(processorStatus);
+            }
+        }
+
+        throw new ResourceNotFoundException(String.format("Unable to locate processor with id '%s'.", processorId));
+    }
+
+    /**
+     * Gets the status for the specified connection.
+     *
+     * @param groupId group id
+     * @param connectionId connection id
+     * @return the status for the specified connection
+     */
+    public ConnectionStatusDTO getConnectionStatus(final String groupId, final String connectionId) {
+        final ProcessGroupStatus processGroupStatus = flowController.getGroupStatus(groupId);
+        if (processGroupStatus == null) {
+            throw new ResourceNotFoundException(String.format("Unable to locate group with id '%s'.", groupId));
+        }
+
+        for (final ConnectionStatus connectionStatus : processGroupStatus.getConnectionStatus()) {
+            if (connectionId.equals(connectionStatus.getId())) {
+                return dtoFactory.createConnectionStatusDto(connectionStatus);
+            }
+        }
+
+        throw new ResourceNotFoundException(String.format("Unable to locate connection with id '%s'.", connectionId));
+    }
+
+    /**
+     * Gets the status for the specified input port.
+     *
+     * @param groupId group id
+     * @param portId input port id
+     * @return the status for the specified input port
+     */
+    public PortStatusDTO getInputPortStatus(final String groupId, final String portId) {
+        final ProcessGroupStatus processGroupStatus = flowController.getGroupStatus(groupId);
+        if (processGroupStatus == null) {
+            throw new ResourceNotFoundException(String.format("Unable to locate group with id '%s'.", groupId));
+        }
+
+        for (final PortStatus portStatus : processGroupStatus.getInputPortStatus()) {
+            if (portId.equals(portStatus.getId())) {
+                return dtoFactory.createPortStatusDto(portStatus);
+            }
+        }
+
+        throw new ResourceNotFoundException(String.format("Unable to locate input port with id '%s'.", portId));
+    }
+
+    /**
+     * Gets the status for the specified output port.
+     *
+     * @param groupId group id
+     * @param portId output port id
+     * @return the status for the specified output port
+     */
+    public PortStatusDTO getOutputPortStatus(final String groupId, final String portId) {
+        final ProcessGroupStatus processGroupStatus = flowController.getGroupStatus(groupId);
+        if (processGroupStatus == null) {
+            throw new ResourceNotFoundException(String.format("Unable to locate group with id '%s'.", groupId));
+        }
+
+        for (final PortStatus portStatus : processGroupStatus.getOutputPortStatus()) {
+            if (portId.equals(portStatus.getId())) {
+                return dtoFactory.createPortStatusDto(portStatus);
+            }
+        }
+
+        throw new ResourceNotFoundException(String.format("Unable to locate output port with id '%s'.", portId));
+    }
+
+    /**
+     * Gets the status for the specified remote process group.
+     *
+     * @param groupId group id
+     * @param remoteProcessGroupId remote process group id
+     * @return the status for the specified remote process group
+     */
+    public RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(final String groupId, final String remoteProcessGroupId) {
+        final ProcessGroupStatus processGroupStatus = flowController.getGroupStatus(groupId);
+        if (processGroupStatus == null) {
+            throw new ResourceNotFoundException(String.format("Unable to locate group with id '%s'.", groupId));
+        }
+
+        for (final RemoteProcessGroupStatus remoteProcessGroupStatus : processGroupStatus.getRemoteProcessGroupStatus()) {
+            if (remoteProcessGroupId.equals(remoteProcessGroupStatus.getId())) {
+                return dtoFactory.createRemoteProcessGroupStatusDto(remoteProcessGroupStatus);
+            }
+        }
+
+        throw new ResourceNotFoundException(String.format("Unable to locate remote process group with id '%s'.", remoteProcessGroupId));
+    }
+
+    /**
      * Gets the BulletinRepository.
      *
      * @return the BulletinRepository


[02/18] nifi git commit: Updating versions to 1.0.0-SNAPSHOT.

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-framework-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/pom.xml
index d13d43c..d1b1422 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-framework-bundle</artifactId>
     <packaging>pom</packaging>
@@ -31,92 +31,92 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-framework-cluster-protocol</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-framework-cluster-web</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-file-authorization-provider</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-cluster-authorization-provider</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-framework-cluster</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-runtime</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-client-dto</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-content-access</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-security</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-framework-core-api</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-site-to-site</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-framework-core</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-user-actions</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-administration</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-jetty</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-optimistic-locking</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-security</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-documentation</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-nar/pom.xml b/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-nar/pom.xml
index 03b7706..0f4768f 100644
--- a/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-nar/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-geo-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-geo-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-processors/pom.xml b/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-processors/pom.xml
index ec75ca1..ae397a8 100644
--- a/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-geo-bundle/nifi-geo-processors/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-geo-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-geo-processors</artifactId>
     <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-geo-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-geo-bundle/pom.xml b/nifi-nar-bundles/nifi-geo-bundle/pom.xml
index 0baa13e..ad0e7f6 100644
--- a/nifi-nar-bundles/nifi-geo-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-geo-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-geo-bundle</artifactId>
@@ -35,7 +35,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-geo-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hadoop-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hadoop-nar/pom.xml b/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hadoop-nar/pom.xml
index 174daf3..54e0aa9 100644
--- a/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hadoop-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hadoop-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hadoop-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hadoop-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/pom.xml b/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/pom.xml
index 05a33bd..77d2be2 100644
--- a/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hadoop-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hdfs-processors</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hadoop-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hadoop-bundle/pom.xml b/nifi-nar-bundles/nifi-hadoop-bundle/pom.xml
index 5239f84..8f938d7 100644
--- a/nifi-nar-bundles/nifi-hadoop-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-hadoop-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hadoop-bundle</artifactId>
     <packaging>pom</packaging>
@@ -31,7 +31,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hdfs-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hadoop-libraries-bundle/nifi-hadoop-libraries-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hadoop-libraries-bundle/nifi-hadoop-libraries-nar/pom.xml b/nifi-nar-bundles/nifi-hadoop-libraries-bundle/nifi-hadoop-libraries-nar/pom.xml
index 7dabbb3..ec724b8 100644
--- a/nifi-nar-bundles/nifi-hadoop-libraries-bundle/nifi-hadoop-libraries-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-hadoop-libraries-bundle/nifi-hadoop-libraries-nar/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hadoop-libraries-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hadoop-libraries-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hadoop-libraries-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hadoop-libraries-bundle/pom.xml b/nifi-nar-bundles/nifi-hadoop-libraries-bundle/pom.xml
index b9a195f..b30ccf4 100644
--- a/nifi-nar-bundles/nifi-hadoop-libraries-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-hadoop-libraries-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-hadoop-libraries-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-nar/pom.xml b/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-nar/pom.xml
index 49c4b4d..afd74b4 100644
--- a/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-nar/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hbase-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hbase-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-processors/pom.xml b/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-processors/pom.xml
index 89b8458..ed24a36 100644
--- a/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-hbase-bundle/nifi-hbase-processors/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hbase-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-hbase-processors</artifactId>
     <description>Support for interacting with HBase</description>
@@ -27,13 +27,13 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-hbase-client-service-api</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-distributed-cache-client-service-api</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hbase-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hbase-bundle/pom.xml b/nifi-nar-bundles/nifi-hbase-bundle/pom.xml
index ed2bfb2..db30b57 100644
--- a/nifi-nar-bundles/nifi-hbase-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-hbase-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hbase-bundle</artifactId>
@@ -35,7 +35,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-hbase-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.hbase</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-nar/pom.xml b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-nar/pom.xml
index d07a259..93f8c78 100644
--- a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hl7-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hl7-nar</artifactId>
@@ -33,7 +33,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-hl7-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/pom.xml b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/pom.xml
index ee37107..a6d19d1 100644
--- a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hl7-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hl7-processors</artifactId>
@@ -52,7 +52,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-hl7-query-language</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
         
         <dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-hl7-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hl7-bundle/pom.xml b/nifi-nar-bundles/nifi-hl7-bundle/pom.xml
index fd37ed3..4f3bcb0 100644
--- a/nifi-nar-bundles/nifi-hl7-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-hl7-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hl7-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-html-bundle/nifi-html-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-nar/pom.xml b/nifi-nar-bundles/nifi-html-bundle/nifi-html-nar/pom.xml
index e74fed5..20a9ee5 100644
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-html-bundle/nifi-html-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-html-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-html-nar</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/pom.xml b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/pom.xml
index 3c95f8a..4f0f19c 100644
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-html-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-html-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-html-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-html-bundle/pom.xml b/nifi-nar-bundles/nifi-html-bundle/pom.xml
index 5d12a96..c178007 100644
--- a/nifi-nar-bundles/nifi-html-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-html-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-html-bundle</artifactId>
@@ -35,7 +35,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-html-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-image-bundle/nifi-image-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-image-bundle/nifi-image-nar/pom.xml b/nifi-nar-bundles/nifi-image-bundle/nifi-image-nar/pom.xml
index 153c92b..fb9dd71 100644
--- a/nifi-nar-bundles/nifi-image-bundle/nifi-image-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-image-bundle/nifi-image-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-image-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-image-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -34,12 +34,12 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-image-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-image-viewer</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
             <type>war</type>
         </dependency>
     </dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-image-bundle/nifi-image-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-image-bundle/nifi-image-processors/pom.xml b/nifi-nar-bundles/nifi-image-bundle/nifi-image-processors/pom.xml
index 3b43066..125d50a 100644
--- a/nifi-nar-bundles/nifi-image-bundle/nifi-image-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-image-bundle/nifi-image-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-image-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-image-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-image-bundle/nifi-image-viewer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-image-bundle/nifi-image-viewer/pom.xml b/nifi-nar-bundles/nifi-image-bundle/nifi-image-viewer/pom.xml
index 7f3ba18..83fd2cb 100755
--- a/nifi-nar-bundles/nifi-image-bundle/nifi-image-viewer/pom.xml
+++ b/nifi-nar-bundles/nifi-image-bundle/nifi-image-viewer/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-image-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-image-viewer</artifactId>
     <description>NiFi image viewer</description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-image-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-image-bundle/pom.xml b/nifi-nar-bundles/nifi-image-bundle/pom.xml
index 324622a..c4b9a05 100644
--- a/nifi-nar-bundles/nifi-image-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-image-bundle/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-image-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jetty-bundle/pom.xml b/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
index 1373cee..1d2d3cb 100644
--- a/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-jetty-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-jetty-bundle</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service-nar/pom.xml b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service-nar/pom.xml
index 67cdf13..3c34d64 100644
--- a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-jms-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-jms-cf-service-nar</artifactId>
     <packaging>nar</packaging>
@@ -35,7 +35,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-jms-cf-service</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service/pom.xml b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service/pom.xml
index 7564b0e..170ca50 100644
--- a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service/pom.xml
+++ b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service/pom.xml
@@ -12,7 +12,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi-jms-bundle</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 	<artifactId>nifi-jms-cf-service</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors-nar/pom.xml b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors-nar/pom.xml
index 1de689f..29bb1be 100644
--- a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-jms-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-jms-processors-nar</artifactId>
     <packaging>nar</packaging>
@@ -35,7 +35,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-jms-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/pom.xml b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/pom.xml
index fe68451..47b67bd 100644
--- a/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/pom.xml
@@ -12,7 +12,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi-jms-bundle</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 	<artifactId>nifi-jms-processors</artifactId>
@@ -29,7 +29,7 @@
 		<dependency>
 			<groupId>org.apache.nifi</groupId>
 			<artifactId>nifi-jms-cf-service</artifactId>
-			<version>0.7.0-SNAPSHOT</version>
+			<version>1.0.0-SNAPSHOT</version>
 		</dependency>
 		<dependency>
 			<groupId>org.springframework</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-jms-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-jms-bundle/pom.xml b/nifi-nar-bundles/nifi-jms-bundle/pom.xml
index fc94e91..a5aea26 100644
--- a/nifi-nar-bundles/nifi-jms-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-jms-bundle/pom.xml
@@ -17,10 +17,10 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-jms-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <description>A bundle of processors that publish to and consume messages from JMS.</description>
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-nar/pom.xml b/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-nar/pom.xml
index 91cca1b..1b98f6a 100644
--- a/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-kafka-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-kafka-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-processors/pom.xml b/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-processors/pom.xml
index 3dad4e2..98da7b2 100644
--- a/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-kafka-bundle/nifi-kafka-processors/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-kafka-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>nifi-kafka-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kafka-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kafka-bundle/pom.xml b/nifi-nar-bundles/nifi-kafka-bundle/pom.xml
index 9a5287a..79a4ac6 100644
--- a/nifi-nar-bundles/nifi-kafka-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-kafka-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-kafka-bundle</artifactId>
     <packaging>pom</packaging>
@@ -30,7 +30,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-kafka-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement> 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers-nar/pom.xml b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers-nar/pom.xml
index 060d21d..dc7cc4b 100644
--- a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers-nar/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-kerberos-iaa-providers-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-kerberos-iaa-providers-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/pom.xml b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/pom.xml
index 72709f9..04ef8f0 100644
--- a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/pom.xml
+++ b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-kerberos-iaa-providers-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-kerberos-iaa-providers</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/pom.xml b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/pom.xml
index ec97a23..1f930e5 100644
--- a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-kerberos-iaa-providers-bundle</artifactId>
     <packaging>pom</packaging>
@@ -31,7 +31,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-kerberos-iaa-providers</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-nar/pom.xml b/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-nar/pom.xml
index ba09b72..dec6900 100644
--- a/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-nar/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-kite-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-kite-nar</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-processors/pom.xml b/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-processors/pom.xml
index 8513548..311ad89 100644
--- a/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-kite-bundle/nifi-kite-processors/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-kite-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-kite-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-kite-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-kite-bundle/pom.xml b/nifi-nar-bundles/nifi-kite-bundle/pom.xml
index 11fa49e..ca726da 100644
--- a/nifi-nar-bundles/nifi-kite-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-kite-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-kite-bundle</artifactId>
@@ -36,7 +36,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-kite-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-language-translation-bundle/nifi-language-translation-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-language-translation-bundle/nifi-language-translation-nar/pom.xml b/nifi-nar-bundles/nifi-language-translation-bundle/nifi-language-translation-nar/pom.xml
index fe5998f..6d463bd 100644
--- a/nifi-nar-bundles/nifi-language-translation-bundle/nifi-language-translation-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-language-translation-bundle/nifi-language-translation-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-language-translation-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-language-translation-nar</artifactId>
@@ -33,7 +33,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-yandex-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-language-translation-bundle/nifi-yandex-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-language-translation-bundle/nifi-yandex-processors/pom.xml b/nifi-nar-bundles/nifi-language-translation-bundle/nifi-yandex-processors/pom.xml
index f9e9b55..157e7d4 100644
--- a/nifi-nar-bundles/nifi-language-translation-bundle/nifi-yandex-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-language-translation-bundle/nifi-yandex-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-language-translation-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-yandex-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-language-translation-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-language-translation-bundle/pom.xml b/nifi-nar-bundles/nifi-language-translation-bundle/pom.xml
index ccff93e..1a482b3 100644
--- a/nifi-nar-bundles/nifi-language-translation-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-language-translation-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-language-translation-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
index 48a1648..b621f90 100644
--- a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-ldap-iaa-providers-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ldap-iaa-providers-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
index 7cfcd1b..aafb4e3 100644
--- a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-ldap-iaa-providers-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ldap-iaa-providers</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
index 46a396c..008240b 100644
--- a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-ldap-iaa-providers-bundle</artifactId>
     <packaging>pom</packaging>
@@ -31,7 +31,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-ldap-iaa-providers</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-nar/pom.xml b/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-nar/pom.xml
index 26706a0..a17b05f 100644
--- a/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-mongodb-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-mongodb-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -34,7 +34,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-mongodb-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/pom.xml b/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/pom.xml
index 09b55f1..ff67f79 100644
--- a/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-mongodb-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-mongodb-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-mongodb-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-mongodb-bundle/pom.xml b/nifi-nar-bundles/nifi-mongodb-bundle/pom.xml
index 43e3ee0..db9e87d 100644
--- a/nifi-nar-bundles/nifi-mongodb-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-mongodb-bundle/pom.xml
@@ -19,12 +19,12 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-mongodb-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/pom.xml b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/pom.xml
index 4a5d9d9..a02f071 100644
--- a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/pom.xml
+++ b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-provenance-repository-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-persistent-provenance-repository</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-provenance-repository-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-provenance-repository-nar/pom.xml b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-provenance-repository-nar/pom.xml
index ed9347c..9b58ed5 100644
--- a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-provenance-repository-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-provenance-repository-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-provenance-repository-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-provenance-repository-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/pom.xml b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/pom.xml
index 3cff8e4..f58f522 100644
--- a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/pom.xml
+++ b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-provenance-repository-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-volatile-provenance-repository</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-provenance-repository-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-provenance-repository-bundle/pom.xml b/nifi-nar-bundles/nifi-provenance-repository-bundle/pom.xml
index 97b4e93..37cb5c6 100644
--- a/nifi-nar-bundles/nifi-provenance-repository-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-provenance-repository-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-provenance-repository-bundle</artifactId>
     <packaging>pom</packaging>
@@ -31,12 +31,12 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-persistent-provenance-repository</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-volatile-provenance-repository</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml
index b3b0bc2..ad9801a 100644
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <artifactId>nifi-riemann-bundle</artifactId>
         <groupId>org.apache.nifi</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml
index 219ef3a..5846f74 100644
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-riemann-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-riemann-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-riemann-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/pom.xml b/nifi-nar-bundles/nifi-riemann-bundle/pom.xml
index fb38d8b..806b226 100644
--- a/nifi-nar-bundles/nifi-riemann-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-riemann-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <artifactId>nifi-nar-bundles</artifactId>
         <groupId>org.apache.nifi</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-riemann-bundle</artifactId>
     <packaging>pom</packaging>
@@ -42,7 +42,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-riemann-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-nar/pom.xml b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-nar/pom.xml
index a4dd802..75a1d24 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-scripting-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-scripting-nar</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
index 39b99a6..4e85485 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-scripting-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-scripting-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-scripting-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/pom.xml b/nifi-nar-bundles/nifi-scripting-bundle/pom.xml
index e0794c2..64a4ba6 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-scripting-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-scripting-bundle</artifactId>
@@ -35,7 +35,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-scripting-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.codehaus.groovy</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-social-media-bundle/nifi-social-media-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-social-media-bundle/nifi-social-media-nar/pom.xml b/nifi-nar-bundles/nifi-social-media-bundle/nifi-social-media-nar/pom.xml
index 76d2917..1d11620 100644
--- a/nifi-nar-bundles/nifi-social-media-bundle/nifi-social-media-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-social-media-bundle/nifi-social-media-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-social-media-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-social-media-nar</artifactId>
@@ -33,7 +33,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-twitter-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-social-media-bundle/nifi-twitter-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-social-media-bundle/nifi-twitter-processors/pom.xml b/nifi-nar-bundles/nifi-social-media-bundle/nifi-twitter-processors/pom.xml
index 8c1a355..2248ad8 100644
--- a/nifi-nar-bundles/nifi-social-media-bundle/nifi-twitter-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-social-media-bundle/nifi-twitter-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-social-media-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-twitter-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-social-media-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-social-media-bundle/pom.xml b/nifi-nar-bundles/nifi-social-media-bundle/pom.xml
index d4cf151..27cb69c 100644
--- a/nifi-nar-bundles/nifi-social-media-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-social-media-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-social-media-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-nar/pom.xml b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-nar/pom.xml
index 401426e..93c44e8 100644
--- a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-nar/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-solr-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-solr-nar</artifactId>
@@ -33,7 +33,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-solr-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/pom.xml b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/pom.xml
index ee045df..f0dcbc9 100644
--- a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-solr-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-solr-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-solr-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-solr-bundle/pom.xml b/nifi-nar-bundles/nifi-solr-bundle/pom.xml
index f7af9d5..a566faf 100644
--- a/nifi-nar-bundles/nifi-solr-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-solr-bundle/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-solr-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-nar/pom.xml b/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-nar/pom.xml
index c2bc7e4..18e4261 100644
--- a/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-splunk-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-splunk-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -34,7 +34,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-splunk-processors</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/pom.xml b/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/pom.xml
index b6e9ee7..989affc 100644
--- a/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-splunk-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-splunk-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-splunk-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-splunk-bundle/pom.xml b/nifi-nar-bundles/nifi-splunk-bundle/pom.xml
index 7e3c44e..7d444b2 100644
--- a/nifi-nar-bundles/nifi-splunk-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-splunk-bundle/pom.xml
@@ -19,12 +19,12 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-splunk-bundle</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-nar/pom.xml b/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-nar/pom.xml
index 02418b3..8774b04 100644
--- a/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-spring-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-spring-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-processors/pom.xml b/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-processors/pom.xml
index 60ad03e..c6de051 100644
--- a/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-spring-bundle/nifi-spring-processors/pom.xml
@@ -12,7 +12,7 @@
 	<parent>
 		<groupId>org.apache.nifi</groupId>
 		<artifactId>nifi-spring-bundle</artifactId>
-		<version>0.7.0-SNAPSHOT</version>
+		<version>1.0.0-SNAPSHOT</version>
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 	<artifactId>nifi-spring-processors</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-spring-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-spring-bundle/pom.xml b/nifi-nar-bundles/nifi-spring-bundle/pom.xml
index 69ed3d5..6451fda 100644
--- a/nifi-nar-bundles/nifi-spring-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-spring-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-spring-bundle</artifactId>
     <packaging>pom</packaging>
@@ -30,7 +30,7 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-spring-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
index f87af95..819d2b2 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-standard-content-viewer</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
index 6a0dce4..e95b071 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-standard-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-prioritizers/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-prioritizers/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-prioritizers/pom.xml
index 835504e..068e97e 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-prioritizers/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-prioritizers/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <groupId>org.apache.nifi</groupId>
     <artifactId>nifi-standard-prioritizers</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/pom.xml
index eed056e..96ecdf5 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/pom.xml
@@ -14,7 +14,7 @@ language governing permissions and limitations under the License. -->
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-standard-processors</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-reporting-tasks/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-reporting-tasks/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-reporting-tasks/pom.xml
index ed98717..5d5d0c8 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-reporting-tasks/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-reporting-tasks/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-standard-reporting-tasks</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/pom.xml b/nifi-nar-bundles/nifi-standard-bundle/pom.xml
index 9e6f374..04ab2f8 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-nar-bundles</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-standard-bundle</artifactId>
     <packaging>pom</packaging>
@@ -35,23 +35,23 @@
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-standard-processors</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-standard-prioritizers</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-standard-reporting-tasks</artifactId>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-standard-content-viewer</artifactId>
                 <type>war</type>
-                <version>0.7.0-SNAPSHOT</version>
+                <version>1.0.0-SNAPSHOT</version>
             </dependency>
         </dependencies>
     </dependencyManagement>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
index 2e12069..7ab4289 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     
     <artifactId>nifi-dbcp-service-api</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
index 0f27751..35728f4 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-dbcp-service-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     
     <artifactId>nifi-dbcp-service-nar</artifactId>
@@ -35,7 +35,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-dbcp-service</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
index 3959732..66a5bc3 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-dbcp-service-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-dbcp-service</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
index 5b12b55..7d0d24d 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     
     <artifactId>nifi-dbcp-service-bundle</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-client-service-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-client-service-api/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-client-service-api/pom.xml
index 3e2065a..5373c29 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-client-service-api/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-client-service-api/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-distributed-cache-client-service-api</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/pom.xml
index 986ccf0..cb0a7a0 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-distributed-cache-services-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-distributed-cache-client-service</artifactId>
     <packaging>jar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-protocol/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-protocol/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-protocol/pom.xml
index ab829a3..4d6fd4d 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-protocol/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-protocol/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-distributed-cache-services-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-distributed-cache-protocol</artifactId>
     <description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-server/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-server/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-server/pom.xml
index 89d1b97..35ca48c 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-server/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-server/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-distributed-cache-services-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-distributed-cache-server</artifactId>
     <description>Provides a Controller Service for hosting Distributed Caches</description>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-services-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-services-nar/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-services-nar/pom.xml
index a32ef0a..a9f15cb 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-services-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-services-nar/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-distributed-cache-services-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-distributed-cache-services-nar</artifactId>
     <packaging>nar</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/pom.xml
index 0845ba0..3b673aa 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>nifi-distributed-cache-services-bundle</artifactId>
     <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-hbase-client-service-api/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-hbase-client-service-api/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-hbase-client-service-api/pom.xml
index 119069d..02620ab 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-hbase-client-service-api/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-hbase-client-service-api/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-standard-services</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hbase-client-service-api</artifactId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service-nar/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service-nar/pom.xml
index 649246a..8006695 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service-nar/pom.xml
@@ -19,11 +19,11 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hbase_1_1_2-client-service-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hbase_1_1_2-client-service-nar</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>nar</packaging>
     <properties>
         <maven.javadoc.skip>true</maven.javadoc.skip>
@@ -39,7 +39,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-hbase_1_1_2-client-service</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/2de7f3f8/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service/pom.xml b/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service/pom.xml
index d03b6ba..0196b1d 100644
--- a/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-services/nifi-hbase_1_1_2-client-service-bundle/nifi-hbase_1_1_2-client-service/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <groupId>org.apache.nifi</groupId>
         <artifactId>nifi-hbase_1_1_2-client-service-bundle</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>1.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>nifi-hbase_1_1_2-client-service</artifactId>
@@ -29,7 +29,7 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-hbase-client-service-api</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
+            <version>1.0.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>


[07/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ClusterResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ClusterResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ClusterResource.java
index 857df56..ec4c69e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ClusterResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ClusterResource.java
@@ -16,24 +16,14 @@
  */
 package org.apache.nifi.web.api;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.HEAD;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
+import com.sun.jersey.api.core.ResourceContext;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiParam;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
+import com.wordnik.swagger.annotations.Authorization;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
 import org.apache.nifi.cluster.node.Node;
 import org.apache.nifi.util.NiFiProperties;
@@ -47,36 +37,29 @@ import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.dto.search.NodeSearchResultDTO;
-import org.apache.nifi.web.api.dto.status.ClusterConnectionStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterPortStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterProcessorStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterRemoteProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusHistoryDTO;
-import org.apache.nifi.web.api.entity.ClusterConnectionStatusEntity;
 import org.apache.nifi.web.api.entity.ClusterEntity;
-import org.apache.nifi.web.api.entity.ClusterPortStatusEntity;
-import org.apache.nifi.web.api.entity.ClusterProcessorStatusEntity;
-import org.apache.nifi.web.api.entity.ClusterRemoteProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ClusterSearchResultsEntity;
-import org.apache.nifi.web.api.entity.ClusterStatusEntity;
-import org.apache.nifi.web.api.entity.ClusterStatusHistoryEntity;
 import org.apache.nifi.web.api.entity.ProcessorEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 
-import com.sun.jersey.api.core.ResourceContext;
-import com.wordnik.swagger.annotations.Api;
-import com.wordnik.swagger.annotations.ApiOperation;
-import com.wordnik.swagger.annotations.ApiParam;
-import com.wordnik.swagger.annotations.ApiResponse;
-import com.wordnik.swagger.annotations.ApiResponses;
-import com.wordnik.swagger.annotations.Authorization;
-import org.apache.nifi.web.api.dto.status.ClusterProcessGroupStatusDTO;
-import org.apache.nifi.web.api.entity.ClusterProcessGroupStatusEntity;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * RESTful endpoint for managing a cluster.
@@ -108,62 +91,6 @@ public class ClusterResource extends ApplicationResource {
     }
 
     /**
-     * Gets the status of this NiFi cluster.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @return A clusterStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets the status of the cluster",
-            response = ClusterStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getClusterStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
-
-        if (properties.isClusterManager()) {
-
-            ClusterStatusDTO dto = serviceFacade.getClusterStatus();
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterStatusEntity entity = new ClusterStatusEntity();
-            entity.setClusterStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-
-    }
-
-    /**
      * Returns a 200 OK response to indicate this is a valid cluster endpoint.
      *
      * @return An OK response with an empty entity body.
@@ -519,622 +446,6 @@ public class ClusterResource extends ApplicationResource {
         throw new IllegalClusterResourceRequestException("Only a node can process the request.");
     }
 
-    /**
-     * Gets the processor status for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the processor
-     * @return A clusterProcessorStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/processors/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets the processor status across the cluster",
-            response = ClusterProcessorStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getProcessorStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The processor id",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-
-            final ClusterProcessorStatusDTO dto = serviceFacade.getClusterProcessorStatus(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterProcessorStatusEntity entity = new ClusterProcessorStatusEntity();
-            entity.setClusterProcessorStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the processor status history for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the processor
-     * @return A clusterProcessorStatusHistoryEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/processors/{id}/status/history")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets processor status history across the cluster",
-            response = ClusterStatusHistoryEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getProcessorStatusHistory(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The processor id",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-            final ClusterStatusHistoryDTO dto = serviceFacade.getClusterProcessorStatusHistory(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterStatusHistoryEntity entity = new ClusterStatusHistoryEntity();
-            entity.setClusterStatusHistory(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the connection status for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the processor
-     * @return A clusterProcessorStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/connections/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets connection status across the cluster",
-            response = ClusterConnectionStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getConnectionStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The connection id",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-
-            final ClusterConnectionStatusDTO dto = serviceFacade.getClusterConnectionStatus(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterConnectionStatusEntity entity = new ClusterConnectionStatusEntity();
-            entity.setClusterConnectionStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the connections status history for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the processor
-     * @return A clusterProcessorStatusHistoryEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/connections/{id}/status/history")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets connection status history across the cluster",
-            response = ClusterStatusHistoryEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getConnectionStatusHistory(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The connection id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-            final ClusterStatusHistoryDTO dto = serviceFacade.getClusterConnectionStatusHistory(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterStatusHistoryEntity entity = new ClusterStatusHistoryEntity();
-            entity.setClusterStatusHistory(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the process group status for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the process group
-     * @return A clusterProcessGroupStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/process-groups/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets process group status across the cluster",
-            response = ClusterProcessGroupStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getProcessGroupStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The process group id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-
-            final ClusterProcessGroupStatusDTO dto = serviceFacade.getClusterProcessGroupStatus(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterProcessGroupStatusEntity entity = new ClusterProcessGroupStatusEntity();
-            entity.setClusterProcessGroupStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the process group status history for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the process group
-     * @return A clusterProcessGroupStatusHistoryEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/process-groups/{id}/status/history")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets process group status history across the cluster",
-            response = ClusterStatusHistoryEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getProcessGroupStatusHistory(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The process group id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-            final ClusterStatusHistoryDTO dto = serviceFacade.getClusterProcessGroupStatusHistory(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterStatusHistoryEntity entity = new ClusterStatusHistoryEntity();
-            entity.setClusterStatusHistory(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the remote process group status for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the remote process group
-     * @return A clusterRemoteProcessGroupStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/remote-process-groups/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets remote process group status across the cluster",
-            response = ClusterRemoteProcessGroupStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getRemoteProcessGroupStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The remote process group id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-
-            final ClusterRemoteProcessGroupStatusDTO dto = serviceFacade.getClusterRemoteProcessGroupStatus(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterRemoteProcessGroupStatusEntity entity = new ClusterRemoteProcessGroupStatusEntity();
-            entity.setClusterRemoteProcessGroupStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the input port status for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the input port
-     * @return A clusterPortStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/input-ports/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets input port status across the cluster",
-            response = ClusterPortStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getInputPortStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The input port id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-
-            final ClusterPortStatusDTO dto = serviceFacade.getClusterInputPortStatus(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterPortStatusEntity entity = new ClusterPortStatusEntity();
-            entity.setClusterPortStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the output port status for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the output port
-     * @return A clusterPortStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/output-ports/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets output port status across the cluster",
-            response = ClusterPortStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getOutputPortStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The output port id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-
-            final ClusterPortStatusDTO dto = serviceFacade.getClusterOutputPortStatus(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterPortStatusEntity entity = new ClusterPortStatusEntity();
-            entity.setClusterPortStatus(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the remote process group status history for every node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the processor
-     * @return A clusterRemoteProcessGroupStatusHistoryEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-    @Path("/remote-process-groups/{id}/status/history")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets the remote process group status history across the cluster",
-            response = ClusterStatusHistoryEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "DFM", type = "ROLE_DFM"),
-                @Authorization(value = "Admin", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getRemoteProcessGroupStatusHistory(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The remote process group id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-            final ClusterStatusHistoryDTO dto = serviceFacade.getClusterRemoteProcessGroupStatusHistory(id);
-
-            // create the revision
-            RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create entity
-            final ClusterStatusHistoryEntity entity = new ClusterStatusHistoryEntity();
-            entity.setClusterStatusHistory(dto);
-            entity.setRevision(revision);
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
     // setters
     public void setServiceFacade(NiFiServiceFacade serviceFacade) {
         this.serviceFacade = serviceFacade;

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
index 738da04..712233f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java
@@ -25,6 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.cluster.context.ClusterContext;
 import org.apache.nifi.cluster.context.ClusterContextThreadLocal;
+import org.apache.nifi.cluster.manager.NodeResponse;
 import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
 import org.apache.nifi.cluster.node.Node;
@@ -33,7 +34,6 @@ import org.apache.nifi.stream.io.StreamUtils;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
 import org.apache.nifi.web.DownloadableContent;
-import org.apache.nifi.web.IllegalClusterResourceRequestException;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.api.dto.ConnectableDTO;
@@ -44,8 +44,10 @@ import org.apache.nifi.web.api.dto.FlowFileSummaryDTO;
 import org.apache.nifi.web.api.dto.ListingRequestDTO;
 import org.apache.nifi.web.api.dto.PositionDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
+import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
 import org.apache.nifi.web.api.entity.ConnectionsEntity;
 import org.apache.nifi.web.api.entity.DropRequestEntity;
 import org.apache.nifi.web.api.entity.FlowFileEntity;
@@ -55,8 +57,6 @@ import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.ConnectableTypeParameter;
 import org.apache.nifi.web.api.request.IntegerParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
 
 import javax.servlet.http.HttpServletRequest;
@@ -99,8 +99,6 @@ import java.util.UUID;
 @Api(hidden = true)
 public class ConnectionResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(ConnectionResource.class);
-
     private NiFiServiceFacade serviceFacade;
     private WebClusterManager clusterManager;
     private NiFiProperties properties;
@@ -284,6 +282,106 @@ public class ConnectionResource extends ApplicationResource {
     }
 
     /**
+     * Retrieves the specified connection status.
+     *
+     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
+     * @param id The id of the connection history to retrieve.
+     * @return A connectionStatusEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{id}/status")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets status for a connection",
+        response = ConnectionStatusEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+        }
+    )
+    public Response getConnectionStatus(
+        @ApiParam(
+            value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+            required = false
+        )
+        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+        @ApiParam(
+            value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+            required = false
+        )
+        @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+        @ApiParam(
+            value = "The id of the node where to get the status.",
+            required = false
+        )
+        @QueryParam("clusterNodeId") String clusterNodeId,
+        @ApiParam(
+            value = "The connection id.",
+            required = true
+        )
+        @PathParam("id") String id) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final ConnectionStatusEntity entity = (ConnectionStatusEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getConnectionStatus().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
+
+        // get the specified connection status
+        final ConnectionStatusDTO connectionStatus = serviceFacade.getConnectionStatus(groupId, id);
+
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+
+        // generate the response entity
+        final ConnectionStatusEntity entity = new ConnectionStatusEntity();
+        entity.setRevision(revision);
+        entity.setConnectionStatus(connectionStatus);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
+    /**
      * Retrieves the specified connection status history.
      *
      * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
@@ -327,7 +425,7 @@ public class ConnectionResource extends ApplicationResource {
 
         // replicate if cluster manager
         if (properties.isClusterManager()) {
-            throw new IllegalClusterResourceRequestException("This request is only supported in standalone mode.");
+            return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
         }
 
         // get the specified processor status history
@@ -565,7 +663,7 @@ public class ConnectionResource extends ApplicationResource {
             headersToOverride.put("content-type", MediaType.APPLICATION_JSON);
 
             // replicate put request
-            return (Response) clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(connectionEntity), getHeaders(headersToOverride)).getResponse();
+            return clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(connectionEntity), getHeaders(headersToOverride)).getResponse();
         }
 
         // get the connection

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
index ef62a62..a3d0dc1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
@@ -23,34 +23,17 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
-
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.HEAD;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
-import org.apache.nifi.web.security.user.NiFiUserUtils;
+import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.user.NiFiUser;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
-import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.IllegalClusterResourceRequestException;
+import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.api.dto.AboutDTO;
 import org.apache.nifi.web.api.dto.BannerDTO;
@@ -66,23 +49,46 @@ import org.apache.nifi.web.api.entity.AuthorityEntity;
 import org.apache.nifi.web.api.entity.BannerEntity;
 import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
 import org.apache.nifi.web.api.entity.ControllerEntity;
+import org.apache.nifi.web.api.entity.ControllerServiceTypesEntity;
 import org.apache.nifi.web.api.entity.ControllerStatusEntity;
 import org.apache.nifi.web.api.entity.CounterEntity;
 import org.apache.nifi.web.api.entity.CountersEntity;
 import org.apache.nifi.web.api.entity.Entity;
+import org.apache.nifi.web.api.entity.IdentityEntity;
 import org.apache.nifi.web.api.entity.PrioritizerTypesEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
 import org.apache.nifi.web.api.entity.ProcessorTypesEntity;
+import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity;
 import org.apache.nifi.web.api.entity.SearchResultsEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.IntegerParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.web.api.entity.ControllerServiceTypesEntity;
-import org.apache.nifi.web.api.entity.IdentityEntity;
-import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity;
+import org.apache.nifi.web.security.user.NiFiUserUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * RESTful endpoint for managing a Flow Controller.
  */
@@ -524,6 +530,10 @@ public class ControllerResource extends ApplicationResource {
             )
             @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
 
+        if (properties.isClusterManager()) {
+            return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+
         final ControllerStatusDTO controllerStatus = serviceFacade.getControllerStatus();
 
         // create the revision
@@ -572,7 +582,50 @@ public class ControllerResource extends ApplicationResource {
                     value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
                     required = false
             )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+            @ApiParam(
+                value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+                required = false
+            )
+            @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+            @ApiParam(
+                value = "The id of the node where to get the status.",
+                required = false
+            )
+            @QueryParam("clusterNodeId") String clusterNodeId) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        // replicate if cluster manager
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final CountersEntity entity = (CountersEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getCounters().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
 
         final CountersDTO countersReport = serviceFacade.getCounters();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
index d2be69d..2f7eed6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java
@@ -22,12 +22,29 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
+import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.ConfigurationSnapshot;
+import org.apache.nifi.web.NiFiServiceFacade;
+import org.apache.nifi.web.Revision;
+import org.apache.nifi.web.api.dto.PortDTO;
+import org.apache.nifi.web.api.dto.PositionDTO;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
+import org.apache.nifi.web.api.entity.InputPortEntity;
+import org.apache.nifi.web.api.entity.InputPortsEntity;
+import org.apache.nifi.web.api.entity.PortStatusEntity;
+import org.apache.nifi.web.api.request.ClientIdParameter;
+import org.apache.nifi.web.api.request.DoubleParameter;
+import org.apache.nifi.web.api.request.IntegerParameter;
+import org.apache.nifi.web.api.request.LongParameter;
+import org.springframework.security.access.prepost.PreAuthorize;
+
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -46,24 +63,13 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
-import org.apache.nifi.cluster.manager.impl.WebClusterManager;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.web.ConfigurationSnapshot;
-import org.apache.nifi.web.NiFiServiceFacade;
-import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.api.dto.PortDTO;
-import org.apache.nifi.web.api.dto.PositionDTO;
-import org.apache.nifi.web.api.dto.RevisionDTO;
-import org.apache.nifi.web.api.entity.InputPortEntity;
-import org.apache.nifi.web.api.entity.InputPortsEntity;
-import org.apache.nifi.web.api.request.ClientIdParameter;
-import org.apache.nifi.web.api.request.DoubleParameter;
-import org.apache.nifi.web.api.request.IntegerParameter;
-import org.apache.nifi.web.api.request.LongParameter;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.access.prepost.PreAuthorize;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
 
 /**
  * RESTful endpoint for managing an Input Port.
@@ -71,8 +77,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
 @Api(hidden = true)
 public class InputPortResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(InputPortResource.class);
-
     private NiFiServiceFacade serviceFacade;
     private WebClusterManager clusterManager;
     private NiFiProperties properties;
@@ -276,7 +280,7 @@ public class InputPortResource extends ApplicationResource {
             headersToOverride.put("content-type", MediaType.APPLICATION_JSON);
 
             // replicate put request
-            return (Response) clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(portEntity), getHeaders(headersToOverride)).getResponse();
+            return clusterManager.applyRequest(HttpMethod.PUT, putUri, updateClientId(portEntity), getHeaders(headersToOverride)).getResponse();
 
         }
 
@@ -370,6 +374,106 @@ public class InputPortResource extends ApplicationResource {
     }
 
     /**
+     * Retrieves the specified input port status.
+     *
+     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
+     * @param id The id of the processor history to retrieve.
+     * @return A portStatusEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{id}/status")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets status for an input port",
+        response = PortStatusEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+        }
+    )
+    public Response getInputPortStatus(
+        @ApiParam(
+            value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+            required = false
+        )
+        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+        @ApiParam(
+            value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+            required = false
+        )
+        @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+        @ApiParam(
+            value = "The id of the node where to get the status.",
+            required = false
+        )
+        @QueryParam("clusterNodeId") String clusterNodeId,
+        @ApiParam(
+            value = "The input port id.",
+            required = true
+        )
+        @PathParam("id") String id) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final PortStatusEntity entity = (PortStatusEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getPortStatus().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
+
+        // get the specified input port status
+        final PortStatusDTO portStatus = serviceFacade.getInputPortStatus(groupId, id);
+
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+
+        // generate the response entity
+        final PortStatusEntity entity = new PortStatusEntity();
+        entity.setRevision(revision);
+        entity.setPortStatus(portStatus);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
+    /**
      * Updates the specified input port.
      *
      * @param httpServletRequest request

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/NodeResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/NodeResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/NodeResource.java
index c88cc68..d3eb77a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/NodeResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/NodeResource.java
@@ -22,6 +22,16 @@ import com.wordnik.swagger.annotations.ApiParam;
 import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.IllegalClusterResourceRequestException;
+import org.apache.nifi.web.NiFiServiceFacade;
+import org.apache.nifi.web.api.dto.NodeDTO;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.entity.NodeEntity;
+import org.apache.nifi.web.api.request.ClientIdParameter;
+import org.springframework.security.access.prepost.PreAuthorize;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -34,19 +44,6 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.web.api.dto.NodeDTO;
-import org.apache.nifi.web.api.entity.NodeEntity;
-import org.apache.nifi.web.api.request.ClientIdParameter;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.web.IllegalClusterResourceRequestException;
-import org.apache.nifi.web.NiFiServiceFacade;
-import org.apache.nifi.web.api.dto.NodeSystemDiagnosticsDTO;
-import org.apache.nifi.web.api.dto.RevisionDTO;
-import org.apache.nifi.web.api.dto.status.NodeStatusDTO;
-import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
-import org.apache.nifi.web.api.entity.SystemDiagnosticsEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
 
 /**
  * RESTful endpoint for managing a cluster connection.
@@ -121,129 +118,6 @@ public class NodeResource extends ApplicationResource {
         throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
     }
 
-    /**
-     * Gets the status for the specified node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the node.
-     * @return A processGroupStatusEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("/{id}/status")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets process group status for a node in the cluster",
-            response = ProcessGroupStatusEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
-                @Authorization(value = "Administrator", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getNodeStatus(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The node id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-            // get the node statistics
-            final NodeStatusDTO nodeStatus = serviceFacade.getNodeStatus(id);
-
-            // create the revision
-            final RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create the node statics entity
-            final ProcessGroupStatusEntity entity = new ProcessGroupStatusEntity();
-            entity.setRevision(revision);
-            entity.setProcessGroupStatus(nodeStatus.getControllerStatus());
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
-
-    /**
-     * Gets the system diagnositics for the specified node.
-     *
-     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
-     * @param id The id of the node.
-     * @return A systemDiagnosticsEntity
-     */
-    @GET
-    @Consumes(MediaType.WILDCARD)
-    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("/{id}/system-diagnostics")
-    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
-    @ApiOperation(
-            value = "Gets system diagnostics for a node in the cluester",
-            response = SystemDiagnosticsEntity.class,
-            authorizations = {
-                @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-                @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
-                @Authorization(value = "Administrator", type = "ROLE_ADMIN")
-            }
-    )
-    @ApiResponses(
-            value = {
-                @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
-                @ApiResponse(code = 401, message = "Client could not be authenticated."),
-                @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
-                @ApiResponse(code = 404, message = "The specified resource could not be found."),
-                @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
-            }
-    )
-    public Response getNodeSystemDiagnostics(
-            @ApiParam(
-                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
-                    required = false
-            )
-            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
-            @ApiParam(
-                    value = "The node id.",
-                    required = true
-            )
-            @PathParam("id") String id) {
-
-        if (properties.isClusterManager()) {
-            // get the node statistics
-            final NodeSystemDiagnosticsDTO nodeSystemDiagnostics = serviceFacade.getNodeSystemDiagnostics(id);
-
-            // create the revision
-            final RevisionDTO revision = new RevisionDTO();
-            revision.setClientId(clientId.getClientId());
-
-            // create the node statics entity
-            final SystemDiagnosticsEntity entity = new SystemDiagnosticsEntity();
-            entity.setRevision(revision);
-            entity.setSystemDiagnostics(nodeSystemDiagnostics.getSystemDiagnostics());
-
-            // generate the response
-            return generateOkResponse(entity).build();
-        }
-
-        throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
-    }
 
     /**
      * Updates the contents of the specified node in this NiFi cluster.

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
index ccd08db..e76fcf0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java
@@ -25,6 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -46,7 +47,12 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.cluster.node.Node;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.ConfigurationSnapshot;
 import org.apache.nifi.web.NiFiServiceFacade;
@@ -54,8 +60,10 @@ import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.api.dto.PortDTO;
 import org.apache.nifi.web.api.dto.PositionDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
 import org.apache.nifi.web.api.entity.OutputPortEntity;
 import org.apache.nifi.web.api.entity.OutputPortsEntity;
+import org.apache.nifi.web.api.entity.PortStatusEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.DoubleParameter;
 import org.apache.nifi.web.api.request.IntegerParameter;
@@ -370,6 +378,106 @@ public class OutputPortResource extends ApplicationResource {
     }
 
     /**
+     * Retrieves the specified output port status.
+     *
+     * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response.
+     * @param id The id of the processor history to retrieve.
+     * @return A portStatusEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{id}/status")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets status for an output port",
+        response = PortStatusEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+        }
+    )
+    public Response getOutputPortStatus(
+        @ApiParam(
+            value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+            required = false
+        )
+        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+        @ApiParam(
+            value = "Whether or not to include the breakdown per node. Optional, defaults to false",
+            required = false
+        )
+        @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise,
+        @ApiParam(
+            value = "The id of the node where to get the status.",
+            required = false
+        )
+        @QueryParam("clusterNodeId") String clusterNodeId,
+        @ApiParam(
+            value = "The output port id.",
+            required = true
+        )
+        @PathParam("id") String id) {
+
+        // ensure a valid request
+        if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
+            throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
+        }
+
+        if (properties.isClusterManager()) {
+            // determine where this request should be sent
+            if (clusterNodeId == null) {
+                final NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders());
+                final PortStatusEntity entity = (PortStatusEntity) nodeResponse.getUpdatedEntity();
+
+                // ensure there is an updated entity (result of merging) and prune the response as necessary
+                if (entity != null && !nodewise) {
+                    entity.getPortStatus().setNodeSnapshots(null);
+                }
+
+                return nodeResponse.getResponse();
+            } else {
+                // get the target node and ensure it exists
+                final Node targetNode = clusterManager.getNode(clusterNodeId);
+                if (targetNode == null) {
+                    throw new UnknownNodeException("The specified cluster node does not exist.");
+                }
+
+                final Set<NodeIdentifier> targetNodes = new HashSet<>();
+                targetNodes.add(targetNode.getNodeId());
+
+                // replicate the request to the specific node
+                return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders(), targetNodes).getResponse();
+            }
+        }
+
+        // get the specified output port status
+        final PortStatusDTO portStatus = serviceFacade.getOutputPortStatus(groupId, id);
+
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+
+        // generate the response entity
+        final PortStatusEntity entity = new PortStatusEntity();
+        entity.setRevision(revision);
+        entity.setPortStatus(portStatus);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
+    /**
      * Updates the specified output port.
      *
      * @param httpServletRequest request


[11/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
index c0f4c63..303e98e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
@@ -29,8 +29,6 @@ import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
@@ -73,7 +71,6 @@ import org.apache.nifi.admin.service.AuditService;
 import org.apache.nifi.annotation.lifecycle.OnAdded;
 import org.apache.nifi.annotation.lifecycle.OnConfigurationRestored;
 import org.apache.nifi.annotation.lifecycle.OnRemoved;
-import org.apache.nifi.cluster.BulletinsPayload;
 import org.apache.nifi.cluster.HeartbeatPayload;
 import org.apache.nifi.cluster.context.ClusterContext;
 import org.apache.nifi.cluster.context.ClusterContextImpl;
@@ -88,6 +85,7 @@ import org.apache.nifi.cluster.manager.HttpClusterManager;
 import org.apache.nifi.cluster.manager.HttpRequestReplicator;
 import org.apache.nifi.cluster.manager.HttpResponseMapper;
 import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.StatusMerger;
 import org.apache.nifi.cluster.manager.exception.ConflictingNodeIdException;
 import org.apache.nifi.cluster.manager.exception.ConnectingNodeMutableRequestException;
 import org.apache.nifi.cluster.manager.exception.DisconnectedNodeMutableRequestException;
@@ -109,7 +107,6 @@ import org.apache.nifi.cluster.node.Node.Status;
 import org.apache.nifi.cluster.protocol.ConnectionRequest;
 import org.apache.nifi.cluster.protocol.ConnectionResponse;
 import org.apache.nifi.cluster.protocol.Heartbeat;
-import org.apache.nifi.cluster.protocol.NodeBulletins;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
 import org.apache.nifi.cluster.protocol.ProtocolException;
 import org.apache.nifi.cluster.protocol.ProtocolHandler;
@@ -121,7 +118,6 @@ import org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage;
 import org.apache.nifi.cluster.protocol.message.ControllerStartupFailureMessage;
 import org.apache.nifi.cluster.protocol.message.DisconnectMessage;
 import org.apache.nifi.cluster.protocol.message.HeartbeatMessage;
-import org.apache.nifi.cluster.protocol.message.NodeBulletinsMessage;
 import org.apache.nifi.cluster.protocol.message.PrimaryRoleAssignmentMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage;
 import org.apache.nifi.cluster.protocol.message.ProtocolMessage.MessageType;
@@ -130,7 +126,6 @@ import org.apache.nifi.cluster.protocol.message.ReconnectionRequestMessage;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.state.StateManagerProvider;
 import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.Heartbeater;
 import org.apache.nifi.controller.ReportingTaskNode;
 import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.controller.StandardFlowSerializer;
@@ -153,16 +148,14 @@ import org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.controller.service.StandardControllerServiceProvider;
 import org.apache.nifi.controller.state.SortedStateUtils;
 import org.apache.nifi.controller.state.manager.StandardStateManagerProvider;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.controller.status.RemoteProcessGroupStatus;
-import org.apache.nifi.controller.status.history.ComponentStatusRepository;
+import org.apache.nifi.controller.status.history.ConnectionStatusDescriptor;
 import org.apache.nifi.controller.status.history.MetricDescriptor;
-import org.apache.nifi.controller.status.history.StatusHistory;
+import org.apache.nifi.controller.status.history.ProcessGroupStatusDescriptor;
+import org.apache.nifi.controller.status.history.ProcessorStatusDescriptor;
+import org.apache.nifi.controller.status.history.RemoteProcessGroupStatusDescriptor;
+import org.apache.nifi.controller.status.history.StandardStatusSnapshot;
 import org.apache.nifi.controller.status.history.StatusHistoryUtil;
 import org.apache.nifi.controller.status.history.StatusSnapshot;
-import org.apache.nifi.diagnostics.GarbageCollection;
-import org.apache.nifi.diagnostics.StorageUsage;
-import org.apache.nifi.diagnostics.SystemDiagnostics;
 import org.apache.nifi.encrypt.StringEncryptor;
 import org.apache.nifi.engine.FlowEngine;
 import org.apache.nifi.events.BulletinFactory;
@@ -178,7 +171,6 @@ import org.apache.nifi.logging.NiFiLog;
 import org.apache.nifi.logging.ReportingTaskLogObserver;
 import org.apache.nifi.nar.ExtensionManager;
 import org.apache.nifi.nar.NarCloseable;
-import org.apache.nifi.nar.NarThreadContextClassLoader;
 import org.apache.nifi.processor.SimpleProcessLogger;
 import org.apache.nifi.processor.StandardValidationContextFactory;
 import org.apache.nifi.remote.RemoteResourceManager;
@@ -188,7 +180,9 @@ import org.apache.nifi.remote.cluster.ClusterNodeInformation;
 import org.apache.nifi.remote.cluster.NodeInformation;
 import org.apache.nifi.remote.protocol.socket.ClusterManagerServerProtocol;
 import org.apache.nifi.reporting.Bulletin;
+import org.apache.nifi.reporting.BulletinQuery;
 import org.apache.nifi.reporting.BulletinRepository;
+import org.apache.nifi.reporting.ComponentType;
 import org.apache.nifi.reporting.InitializationException;
 import org.apache.nifi.reporting.ReportingInitializationContext;
 import org.apache.nifi.reporting.ReportingTask;
@@ -202,14 +196,18 @@ import org.apache.nifi.util.ReflectionUtils;
 import org.apache.nifi.web.OptimisticLockingManager;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.UpdateRevision;
+import org.apache.nifi.web.api.dto.BulletinBoardDTO;
+import org.apache.nifi.web.api.dto.BulletinDTO;
 import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
+import org.apache.nifi.web.api.dto.CountersDTO;
 import org.apache.nifi.web.api.dto.DropRequestDTO;
 import org.apache.nifi.web.api.dto.FlowFileSummaryDTO;
 import org.apache.nifi.web.api.dto.FlowSnippetDTO;
 import org.apache.nifi.web.api.dto.ListingRequestDTO;
-import org.apache.nifi.web.api.dto.NodeDTO;
+import org.apache.nifi.web.api.dto.NodeCountersSnapshotDTO;
+import org.apache.nifi.web.api.dto.NodeSystemDiagnosticsSnapshotDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
 import org.apache.nifi.web.api.dto.QueueSizeDTO;
@@ -219,30 +217,53 @@ import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
 import org.apache.nifi.web.api.dto.StateEntryDTO;
 import org.apache.nifi.web.api.dto.StateMapDTO;
+import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceRequestDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceResultsDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusHistoryDTO;
-import org.apache.nifi.web.api.dto.status.NodeStatusHistoryDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
+import org.apache.nifi.web.api.dto.status.ControllerStatusDTO;
+import org.apache.nifi.web.api.dto.status.NodeConnectionStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodePortStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeProcessorStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeRemoteProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.NodeStatusSnapshotsDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.api.dto.status.StatusSnapshotDTO;
+import org.apache.nifi.web.api.entity.BulletinBoardEntity;
 import org.apache.nifi.web.api.entity.ComponentStateEntity;
+import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
 import org.apache.nifi.web.api.entity.ControllerServicesEntity;
+import org.apache.nifi.web.api.entity.ControllerStatusEntity;
+import org.apache.nifi.web.api.entity.CountersEntity;
 import org.apache.nifi.web.api.entity.DropRequestEntity;
 import org.apache.nifi.web.api.entity.FlowSnippetEntity;
 import org.apache.nifi.web.api.entity.ListingRequestEntity;
+import org.apache.nifi.web.api.entity.PortStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorEntity;
+import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorsEntity;
 import org.apache.nifi.web.api.entity.ProvenanceEntity;
 import org.apache.nifi.web.api.entity.ProvenanceEventEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
+import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupsEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 import org.apache.nifi.web.api.entity.ReportingTasksEntity;
+import org.apache.nifi.web.api.entity.StatusHistoryEntity;
+import org.apache.nifi.web.api.entity.SystemDiagnosticsEntity;
 import org.apache.nifi.web.util.WebUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -310,10 +331,10 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
      */
     private static final int DEFAULT_CONNECTION_REQUEST_TRY_AGAIN_SECONDS = 5;
 
-    public static final String DEFAULT_COMPONENT_STATUS_REPO_IMPLEMENTATION = "org.apache.nifi.controller.status.history.VolatileComponentStatusRepository";
 
     public static final Pattern PROCESSORS_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/processors");
     public static final Pattern PROCESSOR_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/processors/[a-f0-9\\-]{36}");
+    public static final Pattern PROCESSOR_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/processors/[a-f0-9\\-]{36}/status");
     public static final Pattern PROCESSOR_STATE_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/processors/[a-f0-9\\-]{36}/state");
     public static final Pattern CLUSTER_PROCESSOR_URI_PATTERN = Pattern.compile("/nifi-api/cluster/processors/[a-f0-9\\-]{36}");
 
@@ -321,6 +342,8 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
     public static final Pattern REMOTE_PROCESS_GROUP_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/remote-process-groups/[a-f0-9\\-]{36}");
 
     public static final Pattern PROCESS_GROUP_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))");
+    public static final Pattern GROUP_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/status");
+    public static final Pattern CONTROLLER_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/controller/status");
     public static final Pattern TEMPLATE_INSTANCE_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/template-instance");
     public static final Pattern FLOW_SNIPPET_INSTANCE_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/snippet-instance");
 
@@ -328,7 +351,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
     public static final Pattern PROVENANCE_QUERY_URI = Pattern.compile("/nifi-api/controller/provenance/[a-f0-9\\-]{36}");
     public static final Pattern PROVENANCE_EVENT_URI = Pattern.compile("/nifi-api/controller/provenance/events/[0-9]+");
 
-    public static final Pattern COUNTERS_URI = Pattern.compile("/nifi-api/controller/counters/[a-f0-9\\-]{36}");
     public static final String CONTROLLER_SERVICES_URI = "/nifi-api/controller/controller-services/node";
     public static final Pattern CONTROLLER_SERVICE_URI_PATTERN = Pattern.compile("/nifi-api/controller/controller-services/node/[a-f0-9\\-]{36}");
     public static final Pattern CONTROLLER_SERVICE_STATE_URI_PATTERN = Pattern.compile("/nifi-api/controller/controller-services/node/[a-f0-9\\-]{36}/state");
@@ -336,6 +358,24 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
     public static final String REPORTING_TASKS_URI = "/nifi-api/controller/reporting-tasks/node";
     public static final Pattern REPORTING_TASK_URI_PATTERN = Pattern.compile("/nifi-api/controller/reporting-tasks/node/[a-f0-9\\-]{36}");
     public static final Pattern REPORTING_TASK_STATE_URI_PATTERN = Pattern.compile("/nifi-api/controller/reporting-tasks/node/[a-f0-9\\-]{36}/state");
+    public static final Pattern BULLETIN_BOARD_URI_PATTERN = Pattern.compile("/nifi-api/controller/bulletin-board");
+    public static final Pattern SYSTEM_DIAGNOSTICS_URI_PATTERN = Pattern.compile("/nifi-api/system-diagnostics");
+    public static final Pattern COUNTERS_URI_PATTERN = Pattern.compile("/nifi-api/controller/counters");
+    public static final Pattern COUNTER_URI_PATTERN = Pattern.compile("/nifi-api/controller/counters/[a-f0-9\\-]{36}");
+
+    public static final Pattern PROCESSOR_STATUS_HISTORY_URI_PATTERN =
+        Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/processors/[a-f0-9\\-]{36}/status/history");
+    public static final Pattern PROCESS_GROUP_STATUS_HISTORY_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/status/history");
+    public static final Pattern REMOTE_PROCESS_GROUP_STATUS_HISTORY_URI_PATTERN = Pattern
+        .compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/remote-process-groups/[a-f0-9\\-]{36}/status/history");
+    public static final Pattern CONNECTION_STATUS_HISTORY_URI_PATTERN = Pattern
+        .compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/connections/[a-f0-9\\-]{36}/status/history");
+
+    public static final Pattern CONNECTION_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/connections/[a-f0-9\\-]{36}/status");
+    public static final Pattern INPUT_PORT_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/input-ports/[a-f0-9\\-]{36}/status");
+    public static final Pattern OUTPUT_PORT_STATUS_URI_PATTERN = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/output-ports/[a-f0-9\\-]{36}/status");
+    public static final Pattern REMOTE_PROCESS_GROUP_STATUS_URI_PATTERN =
+        Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/remote-process-groups/[a-f0-9\\-]{36}/status");
 
     @Deprecated
     public static final Pattern QUEUE_CONTENTS_URI = Pattern.compile("/nifi-api/controller/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/connections/[a-f0-9\\-]{36}/contents");
@@ -378,7 +418,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
     private final BulletinRepository bulletinRepository;
     private final String instanceId;
     private final FlowEngine reportingTaskEngine;
-    private final Map<NodeIdentifier, ComponentStatusRepository> componentMetricsRepositoryMap = new HashMap<>();
     private final StandardProcessScheduler processScheduler;
     private final StateManagerProvider stateManagerProvider;
     private final long componentStatusSnapshotMillis;
@@ -451,11 +490,7 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
             throw new RuntimeException(e);
         }
 
-        processScheduler = new StandardProcessScheduler(new Heartbeater() {
-            @Override
-            public void heartbeat() {
-            }
-        }, this, encryptor, stateManagerProvider);
+        processScheduler = new StandardProcessScheduler(this, encryptor, stateManagerProvider);
 
         // When we construct the scheduling agents, we can pass null for a lot of the arguments because we are only
         // going to be scheduling Reporting Tasks. Otherwise, it would not be okay.
@@ -463,7 +498,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         processScheduler.setSchedulingAgent(SchedulingStrategy.CRON_DRIVEN, new QuartzSchedulingAgent(null, reportingTaskEngine, null, encryptor));
         processScheduler.setMaxThreadCount(SchedulingStrategy.TIMER_DRIVEN, 10);
         processScheduler.setMaxThreadCount(SchedulingStrategy.CRON_DRIVEN, 10);
-        processScheduler.scheduleFrameworkTask(new CaptureComponentMetrics(), "Capture Component Metrics", componentStatusSnapshotMillis, componentStatusSnapshotMillis, TimeUnit.MILLISECONDS);
 
         controllerServiceProvider = new StandardControllerServiceProvider(processScheduler, bulletinRepository, stateManagerProvider);
     }
@@ -620,7 +654,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return MessageType.CONNECTION_REQUEST == msg.getType()
                 || MessageType.HEARTBEAT == msg.getType()
                 || MessageType.CONTROLLER_STARTUP_FAILURE == msg.getType()
-                || MessageType.BULLETINS == msg.getType()
                 || MessageType.RECONNECTION_FAILURE == msg.getType();
     }
 
@@ -654,10 +687,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
                     }
                 }, "Handle Reconnection Failure Message from " + ((ReconnectionFailureMessage) protocolMessage).getNodeId()).start();
                 return null;
-            case BULLETINS:
-                final NodeBulletinsMessage bulletinsMessage = (NodeBulletinsMessage) protocolMessage;
-                handleBulletins(bulletinsMessage.getBulletins());
-                return null;
             default:
                 throw new ProtocolException("No handler defined for message type: " + protocolMessage.getType());
         }
@@ -1686,22 +1715,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         processScheduler.enableReportingTask(reportingTask);
     }
 
-    /**
-     * Handle a bulletins message.
-     *
-     * @param bulletins bulletins
-     */
-    public void handleBulletins(final NodeBulletins bulletins) {
-        final NodeIdentifier nodeIdentifier = bulletins.getNodeIdentifier();
-        final String nodeAddress = nodeIdentifier.getApiAddress() + ":" + nodeIdentifier.getApiPort();
-
-        // unmarshal the message
-        final BulletinsPayload payload = BulletinsPayload.unmarshal(bulletins.getPayload());
-        for (final Bulletin bulletin : payload.getBulletins()) {
-            bulletin.setNodeAddress(nodeAddress);
-            bulletinRepository.addBulletin(bulletin);
-        }
-    }
 
     /**
      * Handles a node's heartbeat. If this heartbeat is a node's first heartbeat since its connection request, then the manager will mark the node as connected. If the node was previously disconnected
@@ -1875,20 +1888,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
     }
 
 
-    private ComponentStatusRepository createComponentStatusRepository() {
-        final String implementationClassName = properties.getProperty(NiFiProperties.COMPONENT_STATUS_REPOSITORY_IMPLEMENTATION, DEFAULT_COMPONENT_STATUS_REPO_IMPLEMENTATION);
-        if (implementationClassName == null) {
-            throw new RuntimeException("Cannot create Component Status Repository because the NiFi Properties is missing the following property: "
-                    + NiFiProperties.COMPONENT_STATUS_REPOSITORY_IMPLEMENTATION);
-        }
-
-        try {
-            return NarThreadContextClassLoader.createInstance(implementationClassName, ComponentStatusRepository.class);
-        } catch (final Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     @Override
     public Set<Node> getNodes(final Status... statuses) {
         final Set<Status> desiredStatusSet = new HashSet<>();
@@ -2434,6 +2433,10 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return false;
     }
 
+    private static boolean isProcessorStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && PROCESSOR_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
     private static boolean isProcessorStateEndpoint(final URI uri, final String method) {
         return "GET".equalsIgnoreCase(method) && PROCESSOR_STATE_URI_PATTERN.matcher(uri.getPath()).matches();
     }
@@ -2442,6 +2445,30 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && PROCESS_GROUP_URI_PATTERN.matcher(uri.getPath()).matches();
     }
 
+    private static boolean isConnectionStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && CONNECTION_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isInputPortStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && INPUT_PORT_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isOutputPortStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && OUTPUT_PORT_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isRemoteProcessGroupStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && REMOTE_PROCESS_GROUP_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isGroupStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && GROUP_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isControllerStatusEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && CONTROLLER_STATUS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
     private static boolean isTemplateEndpoint(final URI uri, final String method) {
         return "POST".equalsIgnoreCase(method) && TEMPLATE_INSTANCE_URI_PATTERN.matcher(uri.getPath()).matches();
     }
@@ -2454,6 +2481,35 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return "GET".equalsIgnoreCase(method) && REMOTE_PROCESS_GROUPS_URI_PATTERN.matcher(uri.getPath()).matches();
     }
 
+    private static boolean isProcessorStatusHistoryEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && PROCESSOR_STATUS_HISTORY_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isProcessGroupStatusHistoryEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && PROCESS_GROUP_STATUS_HISTORY_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isRemoteProcessGroupStatusHistoryEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && REMOTE_PROCESS_GROUP_STATUS_HISTORY_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isConnectionStatusHistoryEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && CONNECTION_STATUS_HISTORY_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isBulletinBoardEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && BULLETIN_BOARD_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isSystemDiagnosticsEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && SYSTEM_DIAGNOSTICS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+    private static boolean isCountersEndpoint(final URI uri, final String method) {
+        return "GET".equalsIgnoreCase(method) && COUNTERS_URI_PATTERN.matcher(uri.getPath()).matches();
+    }
+
+
     private static boolean isRemoteProcessGroupEndpoint(final URI uri, final String method) {
         if (("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && REMOTE_PROCESS_GROUP_URI_PATTERN.matcher(uri.getPath()).matches()) {
             return true;
@@ -2487,8 +2543,8 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return false;
     }
 
-    private static boolean isCountersEndpoint(final URI uri) {
-        return COUNTERS_URI.matcher(uri.getPath()).matches();
+    private static boolean isCounterEndpoint(final URI uri) {
+        return COUNTER_URI_PATTERN.matcher(uri.getPath()).matches();
     }
 
     private static boolean isControllerServicesEndpoint(final URI uri, final String method) {
@@ -2556,7 +2612,14 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
                 || isControllerServicesEndpoint(uri, method) || isControllerServiceEndpoint(uri, method)
                 || isControllerServiceReferenceEndpoint(uri, method) || isControllerServiceStateEndpoint(uri, method)
                 || isReportingTasksEndpoint(uri, method) || isReportingTaskEndpoint(uri, method) || isReportingTaskStateEndpoint(uri, method)
-                || isDropRequestEndpoint(uri, method) || isListFlowFilesEndpoint(uri, method);
+                || isDropRequestEndpoint(uri, method) || isListFlowFilesEndpoint(uri, method)
+                || isGroupStatusEndpoint(uri, method) || isProcessorStatusEndpoint(uri, method) || isControllerStatusEndpoint(uri, method)
+                || isConnectionStatusEndpoint(uri, method) || isRemoteProcessGroupStatusEndpoint(uri, method)
+                || isInputPortStatusEndpoint(uri, method) || isOutputPortStatusEndpoint(uri, method)
+                || isProcessorStatusHistoryEndpoint(uri, method) || isProcessGroupStatusHistoryEndpoint(uri, method)
+                || isRemoteProcessGroupStatusHistoryEndpoint(uri, method) || isConnectionStatusHistoryEndpoint(uri, method)
+                || isBulletinBoardEndpoint(uri, method) || isSystemDiagnosticsEndpoint(uri, method)
+                || isCountersEndpoint(uri, method);
     }
 
     private void mergeProcessorValidationErrors(final ProcessorDTO processor, Map<NodeIdentifier, ProcessorDTO> processorMap) {
@@ -2608,6 +2671,303 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         componentState.getLocalState().setState(localStateEntries);
     }
 
+
+    private void mergeSystemDiagnostics(final SystemDiagnosticsDTO target, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, SystemDiagnosticsDTO> resultMap) {
+        final SystemDiagnosticsDTO mergedSystemDiagnostics = target;
+        mergedSystemDiagnostics.setNodeSnapshots(new ArrayList<NodeSystemDiagnosticsSnapshotDTO>());
+
+        final NodeSystemDiagnosticsSnapshotDTO selectedNodeSnapshot = new NodeSystemDiagnosticsSnapshotDTO();
+        selectedNodeSnapshot.setSnapshot(target.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedSystemDiagnostics.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        for (final Map.Entry<NodeIdentifier, SystemDiagnosticsDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final SystemDiagnosticsDTO toMerge = entry.getValue();
+            if (toMerge == target) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedSystemDiagnostics, toMerge, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+    private void mergeCounters(final CountersDTO target, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, CountersDTO> resultMap) {
+        final CountersDTO mergedCounters = target;
+        mergedCounters.setNodeSnapshots(new ArrayList<NodeCountersSnapshotDTO>());
+
+        final NodeCountersSnapshotDTO selectedNodeSnapshot = new NodeCountersSnapshotDTO();
+        selectedNodeSnapshot.setSnapshot(target.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedCounters.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        for (final Map.Entry<NodeIdentifier, CountersDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final CountersDTO toMerge = entry.getValue();
+            if (toMerge == target) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedCounters, toMerge, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+    private void mergeGroupStatus(final ProcessGroupStatusDTO statusDto, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, ProcessGroupStatusDTO> resultMap) {
+        final ProcessGroupStatusDTO mergedProcessGroupStatus = statusDto;
+        mergedProcessGroupStatus.setNodeSnapshots(new ArrayList<NodeProcessGroupStatusSnapshotDTO>());
+
+        final NodeProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessGroupStatusSnapshotDTO();
+        selectedNodeSnapshot.setStatusSnapshot(statusDto.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        for (final Map.Entry<NodeIdentifier, ProcessGroupStatusDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final ProcessGroupStatusDTO nodeProcessGroupStatus = entry.getValue();
+            if (nodeProcessGroupStatus == mergedProcessGroupStatus) {
+                continue;
+            }
+
+            final ProcessGroupStatusSnapshotDTO nodeSnapshot = nodeProcessGroupStatus.getAggregateSnapshot();
+            for (final RemoteProcessGroupStatusSnapshotDTO remoteProcessGroupStatus : nodeSnapshot.getRemoteProcessGroupStatusSnapshots()) {
+                final List<String> nodeAuthorizationIssues = remoteProcessGroupStatus.getAuthorizationIssues();
+                if (!nodeAuthorizationIssues.isEmpty()) {
+                    for (final ListIterator<String> iter = nodeAuthorizationIssues.listIterator(); iter.hasNext();) {
+                        final String Issue = iter.next();
+                        iter.set("[" + nodeId.getApiAddress() + ":" + nodeId.getApiPort() + "] -- " + Issue);
+                    }
+                    remoteProcessGroupStatus.setAuthorizationIssues(nodeAuthorizationIssues);
+                }
+            }
+
+            StatusMerger.merge(mergedProcessGroupStatus, nodeProcessGroupStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+
+    private void mergeProcessorStatus(final ProcessorStatusDTO statusDto, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, ProcessorStatusDTO> resultMap) {
+        final ProcessorStatusDTO mergedProcessorStatus = statusDto;
+        mergedProcessorStatus.setNodeSnapshots(new ArrayList<NodeProcessorStatusSnapshotDTO>());
+
+        final NodeProcessorStatusSnapshotDTO selectedNodeSnapshot = new NodeProcessorStatusSnapshotDTO();
+        selectedNodeSnapshot.setStatusSnapshot(statusDto.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedProcessorStatus.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        // merge the other nodes
+        for (final Map.Entry<NodeIdentifier, ProcessorStatusDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final ProcessorStatusDTO nodeProcessorStatus = entry.getValue();
+            if (nodeProcessorStatus == statusDto) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedProcessorStatus, nodeProcessorStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+    private void mergeConnectionStatus(final ConnectionStatusDTO statusDto, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, ConnectionStatusDTO> resultMap) {
+        final ConnectionStatusDTO mergedConnectionStatus = statusDto;
+        mergedConnectionStatus.setNodeSnapshots(new ArrayList<NodeConnectionStatusSnapshotDTO>());
+
+        final NodeConnectionStatusSnapshotDTO selectedNodeSnapshot = new NodeConnectionStatusSnapshotDTO();
+        selectedNodeSnapshot.setStatusSnapshot(statusDto.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedConnectionStatus.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        // merge the other nodes
+        for (final Map.Entry<NodeIdentifier, ConnectionStatusDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final ConnectionStatusDTO nodeConnectionStatus = entry.getValue();
+            if (nodeConnectionStatus == statusDto) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedConnectionStatus, nodeConnectionStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+    private void mergePortStatus(final PortStatusDTO statusDto, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, PortStatusDTO> resultMap) {
+        final PortStatusDTO mergedPortStatus = statusDto;
+        mergedPortStatus.setNodeSnapshots(new ArrayList<NodePortStatusSnapshotDTO>());
+
+        final NodePortStatusSnapshotDTO selectedNodeSnapshot = new NodePortStatusSnapshotDTO();
+        selectedNodeSnapshot.setStatusSnapshot(statusDto.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedPortStatus.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        // merge the other nodes
+        for (final Map.Entry<NodeIdentifier, PortStatusDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final PortStatusDTO nodePortStatus = entry.getValue();
+            if (nodePortStatus == statusDto) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedPortStatus, nodePortStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+    private void mergeRemoteProcessGroupStatus(final RemoteProcessGroupStatusDTO statusDto, final NodeIdentifier selectedNodeId, final Map<NodeIdentifier, RemoteProcessGroupStatusDTO> resultMap) {
+        final RemoteProcessGroupStatusDTO mergedRemoteProcessGroupStatus = statusDto;
+        mergedRemoteProcessGroupStatus.setNodeSnapshots(new ArrayList<NodeRemoteProcessGroupStatusSnapshotDTO>());
+
+        final NodeRemoteProcessGroupStatusSnapshotDTO selectedNodeSnapshot = new NodeRemoteProcessGroupStatusSnapshotDTO();
+        selectedNodeSnapshot.setStatusSnapshot(statusDto.getAggregateSnapshot().clone());
+        selectedNodeSnapshot.setAddress(selectedNodeId.getApiAddress());
+        selectedNodeSnapshot.setApiPort(selectedNodeId.getApiPort());
+        selectedNodeSnapshot.setNodeId(selectedNodeId.getId());
+
+        mergedRemoteProcessGroupStatus.getNodeSnapshots().add(selectedNodeSnapshot);
+
+        // merge the other nodes
+        for (final Map.Entry<NodeIdentifier, RemoteProcessGroupStatusDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final RemoteProcessGroupStatusDTO nodeRemoteProcessGroupStatus = entry.getValue();
+            if (nodeRemoteProcessGroupStatus == statusDto) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedRemoteProcessGroupStatus, nodeRemoteProcessGroupStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort());
+        }
+    }
+
+    private void mergeControllerStatus(final ControllerStatusDTO statusDto, final Map<NodeIdentifier, ControllerStatusDTO> resultMap) {
+        ControllerStatusDTO mergedStatus = statusDto;
+        for (final Map.Entry<NodeIdentifier, ControllerStatusDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final ControllerStatusDTO nodeStatus = entry.getValue();
+
+            final String nodeAddress = nodeId.getApiAddress() + ":" + nodeId.getApiPort();
+            for (final BulletinDTO bulletin : nodeStatus.getBulletins()) {
+                bulletin.setNodeAddress(nodeAddress);
+            }
+            for (final BulletinDTO bulletin : nodeStatus.getControllerServiceBulletins()) {
+                bulletin.setNodeAddress(nodeAddress);
+            }
+            for (final BulletinDTO bulletin : nodeStatus.getReportingTaskBulletins()) {
+                bulletin.setNodeAddress(nodeAddress);
+            }
+
+            if (nodeStatus == mergedStatus) {
+                continue;
+            }
+
+            StatusMerger.merge(mergedStatus, nodeStatus);
+        }
+
+        final int totalNodeCount = getNodeIds().size();
+        final int connectedNodeCount = getNodeIds(Status.CONNECTED).size();
+
+        final List<Bulletin> ncmControllerBulletins = getBulletinRepository().findBulletinsForController();
+        mergedStatus.setBulletins(mergeNCMBulletins(mergedStatus.getBulletins(), ncmControllerBulletins));
+
+        // get the controller service bulletins
+        final BulletinQuery controllerServiceQuery = new BulletinQuery.Builder().sourceType(ComponentType.CONTROLLER_SERVICE).build();
+        final List<Bulletin> ncmServiceBulletins = getBulletinRepository().findBulletins(controllerServiceQuery);
+        mergedStatus.setControllerServiceBulletins(mergeNCMBulletins(mergedStatus.getControllerServiceBulletins(), ncmServiceBulletins));
+
+        // get the reporting task bulletins
+        final BulletinQuery reportingTaskQuery = new BulletinQuery.Builder().sourceType(ComponentType.REPORTING_TASK).build();
+        final List<Bulletin> ncmReportingTaskBulletins = getBulletinRepository().findBulletins(reportingTaskQuery);
+        mergedStatus.setReportingTaskBulletins(mergeNCMBulletins(mergedStatus.getReportingTaskBulletins(), ncmReportingTaskBulletins));
+
+        mergedStatus.setConnectedNodeCount(connectedNodeCount);
+        mergedStatus.setTotalNodeCount(totalNodeCount);
+        StatusMerger.updatePrettyPrintedFields(mergedStatus);
+    }
+
+    private List<BulletinDTO> mergeNCMBulletins(final List<BulletinDTO> nodeBulletins, final List<Bulletin> ncmBulletins) {
+        if (ncmBulletins == null || ncmBulletins.isEmpty()) {
+            return nodeBulletins;
+        }
+
+        final List<BulletinDTO> mergedBulletins = new ArrayList<>(nodeBulletins.size() + ncmBulletins.size());
+        mergedBulletins.addAll(nodeBulletins);
+        mergedBulletins.addAll(createBulletinDtos(ncmBulletins));
+        return mergedBulletins;
+    }
+
+    private void mergeBulletinBoard(final BulletinBoardDTO nodeBulletinBoard, final Map<NodeIdentifier, BulletinBoardDTO> resultMap) {
+        final List<BulletinDTO> bulletinDtos = new ArrayList<>();
+        for (final Map.Entry<NodeIdentifier, BulletinBoardDTO> entry : resultMap.entrySet()) {
+            final NodeIdentifier nodeId = entry.getKey();
+            final BulletinBoardDTO boardDto = entry.getValue();
+            final String nodeAddress = nodeId.getApiAddress() + ":" + nodeId.getApiPort();
+
+            for (final BulletinDTO bulletin : boardDto.getBulletins()) {
+                bulletin.setNodeAddress(nodeAddress);
+                bulletinDtos.add(bulletin);
+            }
+        }
+
+        Collections.sort(bulletinDtos, new Comparator<BulletinDTO>() {
+            @Override
+            public int compare(final BulletinDTO o1, final BulletinDTO o2) {
+                final int timeComparison = o1.getTimestamp().compareTo(o2.getTimestamp());
+                if (timeComparison != 0) {
+                    return timeComparison;
+                }
+
+                return o1.getNodeAddress().compareTo(o2.getNodeAddress());
+            }
+        });
+
+        nodeBulletinBoard.setBulletins(bulletinDtos);
+    }
+
+    /**
+     * Creates BulletinDTOs for the specified Bulletins.
+     *
+     * @param bulletins bulletin
+     * @return dto
+     */
+    public List<BulletinDTO> createBulletinDtos(final List<Bulletin> bulletins) {
+        final List<BulletinDTO> bulletinDtos = new ArrayList<>(bulletins.size());
+        for (final Bulletin bulletin : bulletins) {
+            bulletinDtos.add(createBulletinDto(bulletin));
+        }
+        return bulletinDtos;
+    }
+
+    /**
+     * Creates a BulletinDTO for the specified Bulletin.
+     *
+     * @param bulletin bulletin
+     * @return dto
+     */
+    public BulletinDTO createBulletinDto(final Bulletin bulletin) {
+        final BulletinDTO dto = new BulletinDTO();
+        dto.setId(bulletin.getId());
+        dto.setNodeAddress(bulletin.getNodeAddress());
+        dto.setTimestamp(bulletin.getTimestamp());
+        dto.setGroupId(bulletin.getGroupId());
+        dto.setSourceId(bulletin.getSourceId());
+        dto.setSourceName(bulletin.getSourceName());
+        dto.setCategory(bulletin.getCategory());
+        dto.setLevel(bulletin.getLevel());
+        dto.setMessage(bulletin.getMessage());
+        return dto;
+    }
+
     private void mergeProvenanceQueryResults(final ProvenanceDTO provenanceDto, final Map<NodeIdentifier, ProvenanceDTO> resultMap, final Set<NodeResponse> problematicResponses) {
         final ProvenanceResultsDTO results = provenanceDto.getResults();
         final ProvenanceRequestDTO request = provenanceDto.getRequest();
@@ -3545,6 +3905,252 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
             mergeComponentState(componentState, resultsMap);
 
             clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isGroupStatusEndpoint(uri, method)) {
+            final ProcessGroupStatusEntity responseEntity = clientResponse.getClientResponse().getEntity(ProcessGroupStatusEntity.class);
+            final ProcessGroupStatusDTO statusRequest = responseEntity.getProcessGroupStatus();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, ProcessGroupStatusDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final ProcessGroupStatusEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(ProcessGroupStatusEntity.class);
+                }
+
+                final ProcessGroupStatusDTO nodeStatus = nodeResponseEntity.getProcessGroupStatus();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeGroupStatus(statusRequest, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isProcessorStatusEndpoint(uri, method)) {
+            final ProcessorStatusEntity responseEntity = clientResponse.getClientResponse().getEntity(ProcessorStatusEntity.class);
+            final ProcessorStatusDTO statusRequest = responseEntity.getProcessorStatus();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, ProcessorStatusDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final ProcessorStatusEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(ProcessorStatusEntity.class);
+                }
+
+                final ProcessorStatusDTO nodeStatus = nodeResponseEntity.getProcessorStatus();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeProcessorStatus(statusRequest, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isConnectionStatusEndpoint(uri, method)) {
+            final ConnectionStatusEntity responseEntity = clientResponse.getClientResponse().getEntity(ConnectionStatusEntity.class);
+            final ConnectionStatusDTO statusRequest = responseEntity.getConnectionStatus();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, ConnectionStatusDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final ConnectionStatusEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(ConnectionStatusEntity.class);
+                }
+
+                final ConnectionStatusDTO nodeStatus = nodeResponseEntity.getConnectionStatus();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeConnectionStatus(statusRequest, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && (isInputPortStatusEndpoint(uri, method) || isOutputPortStatusEndpoint(uri, method))) {
+            final PortStatusEntity responseEntity = clientResponse.getClientResponse().getEntity(PortStatusEntity.class);
+            final PortStatusDTO statusRequest = responseEntity.getPortStatus();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, PortStatusDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final PortStatusEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(PortStatusEntity.class);
+                }
+
+                final PortStatusDTO nodeStatus = nodeResponseEntity.getPortStatus();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergePortStatus(statusRequest, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isRemoteProcessGroupStatusEndpoint(uri, method)) {
+            final RemoteProcessGroupStatusEntity responseEntity = clientResponse.getClientResponse().getEntity(RemoteProcessGroupStatusEntity.class);
+            final RemoteProcessGroupStatusDTO statusRequest = responseEntity.getRemoteProcessGroupStatus();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, RemoteProcessGroupStatusDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final RemoteProcessGroupStatusEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(RemoteProcessGroupStatusEntity.class);
+                }
+
+                final RemoteProcessGroupStatusDTO nodeStatus = nodeResponseEntity.getRemoteProcessGroupStatus();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeRemoteProcessGroupStatus(statusRequest, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isControllerStatusEndpoint(uri, method)) {
+            final ControllerStatusEntity responseEntity = clientResponse.getClientResponse().getEntity(ControllerStatusEntity.class);
+            final ControllerStatusDTO statusRequest = responseEntity.getControllerStatus();
+
+            final Map<NodeIdentifier, ControllerStatusDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final ControllerStatusEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(ControllerStatusEntity.class);
+                final ControllerStatusDTO nodeStatus = nodeResponseEntity.getControllerStatus();
+
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeControllerStatus(statusRequest, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isBulletinBoardEndpoint(uri, method)) {
+            final BulletinBoardEntity responseEntity = clientResponse.getClientResponse().getEntity(BulletinBoardEntity.class);
+            final BulletinBoardDTO responseDto = responseEntity.getBulletinBoard();
+
+            final Map<NodeIdentifier, BulletinBoardDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final BulletinBoardEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(BulletinBoardEntity.class);
+                final BulletinBoardDTO nodeStatus = nodeResponseEntity.getBulletinBoard();
+
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeBulletinBoard(responseDto, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isProcessorStatusHistoryEndpoint(uri, method)) {
+            final Map<String, MetricDescriptor<?>> metricDescriptors = new HashMap<>();
+            for (final ProcessorStatusDescriptor descriptor : ProcessorStatusDescriptor.values()) {
+                metricDescriptors.put(descriptor.getField(), descriptor.getDescriptor());
+            }
+
+            clientResponse = mergeStatusHistoryResponses(clientResponse, updatedNodesMap, problematicNodeResponses, metricDescriptors);
+        } else if (hasSuccessfulClientResponse && isConnectionStatusHistoryEndpoint(uri, method)) {
+            final Map<String, MetricDescriptor<?>> metricDescriptors = new HashMap<>();
+            for (final ConnectionStatusDescriptor descriptor : ConnectionStatusDescriptor.values()) {
+                metricDescriptors.put(descriptor.getField(), descriptor.getDescriptor());
+            }
+
+            clientResponse = mergeStatusHistoryResponses(clientResponse, updatedNodesMap, problematicNodeResponses, metricDescriptors);
+        } else if (hasSuccessfulClientResponse && isProcessGroupStatusHistoryEndpoint(uri, method)) {
+            final Map<String, MetricDescriptor<?>> metricDescriptors = new HashMap<>();
+            for (final ProcessGroupStatusDescriptor descriptor : ProcessGroupStatusDescriptor.values()) {
+                metricDescriptors.put(descriptor.getField(), descriptor.getDescriptor());
+            }
+
+            clientResponse = mergeStatusHistoryResponses(clientResponse, updatedNodesMap, problematicNodeResponses, metricDescriptors);
+        } else if (hasSuccessfulClientResponse && isRemoteProcessGroupStatusHistoryEndpoint(uri, method)) {
+            final Map<String, MetricDescriptor<?>> metricDescriptors = new HashMap<>();
+            for (final RemoteProcessGroupStatusDescriptor descriptor : RemoteProcessGroupStatusDescriptor.values()) {
+                metricDescriptors.put(descriptor.getField(), descriptor.getDescriptor());
+            }
+
+            clientResponse = mergeStatusHistoryResponses(clientResponse, updatedNodesMap, problematicNodeResponses, metricDescriptors);
+        } else if (hasSuccessfulClientResponse && isSystemDiagnosticsEndpoint(uri, method)) {
+            final SystemDiagnosticsEntity responseEntity = clientResponse.getClientResponse().getEntity(SystemDiagnosticsEntity.class);
+            final SystemDiagnosticsDTO responseDto = responseEntity.getSystemDiagnostics();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, SystemDiagnosticsDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final SystemDiagnosticsEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(SystemDiagnosticsEntity.class);
+                }
+
+                final SystemDiagnosticsDTO nodeStatus = nodeResponseEntity.getSystemDiagnostics();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeSystemDiagnostics(responseDto, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
+        } else if (hasSuccessfulClientResponse && isCountersEndpoint(uri, method)) {
+            final CountersEntity responseEntity = clientResponse.getClientResponse().getEntity(CountersEntity.class);
+            final CountersDTO responseDto = responseEntity.getCounters();
+
+            NodeIdentifier nodeIdentifier = null;
+
+            final Map<NodeIdentifier, CountersDTO> resultsMap = new HashMap<>();
+            for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+                if (problematicNodeResponses.contains(nodeResponse)) {
+                    continue;
+                }
+
+                final CountersEntity nodeResponseEntity;
+                if (nodeResponse == clientResponse) {
+                    nodeIdentifier = nodeResponse.getNodeId();
+                    nodeResponseEntity = responseEntity;
+                } else {
+                    nodeResponseEntity = nodeResponse.getClientResponse().getEntity(CountersEntity.class);
+                }
+
+                final CountersDTO nodeStatus = nodeResponseEntity.getCounters();
+                resultsMap.put(nodeResponse.getNodeId(), nodeStatus);
+            }
+            mergeCounters(responseDto, nodeIdentifier, resultsMap);
+
+            clientResponse = new NodeResponse(clientResponse, responseEntity);
         } else {
             if (!nodeResponsesToDrain.isEmpty()) {
                 drainResponses(nodeResponsesToDrain);
@@ -3603,6 +4209,49 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return clientResponse;
     }
 
+
+    private NodeResponse mergeStatusHistoryResponses(NodeResponse clientResponse, Map<Node, NodeResponse> updatedNodesMap, Set<NodeResponse> problematicNodeResponses,
+        Map<String, MetricDescriptor<?>> metricDescriptors) {
+        final StatusHistoryEntity responseEntity = clientResponse.getClientResponse().getEntity(StatusHistoryEntity.class);
+
+        StatusHistoryDTO lastStatusHistory = null;
+        final List<NodeStatusSnapshotsDTO> nodeStatusSnapshots = new ArrayList<>(updatedNodesMap.size());
+        for (final NodeResponse nodeResponse : updatedNodesMap.values()) {
+            if (problematicNodeResponses.contains(nodeResponse)) {
+                continue;
+            }
+
+            final StatusHistoryEntity nodeResponseEntity = nodeResponse == clientResponse ? responseEntity : nodeResponse.getClientResponse().getEntity(StatusHistoryEntity.class);
+            final StatusHistoryDTO nodeStatus = nodeResponseEntity.getStatusHistory();
+            lastStatusHistory = nodeStatus;
+
+            final NodeIdentifier nodeId = nodeResponse.getNodeId();
+            final NodeStatusSnapshotsDTO nodeStatusSnapshot = new NodeStatusSnapshotsDTO();
+            nodeStatusSnapshot.setNodeId(nodeId.getId());
+            nodeStatusSnapshot.setAddress(nodeId.getApiAddress());
+            nodeStatusSnapshot.setApiPort(nodeId.getApiPort());
+            nodeStatusSnapshot.setStatusSnapshots(nodeStatus.getAggregateSnapshots());
+            nodeStatusSnapshots.add(nodeStatusSnapshot);
+        }
+
+        final StatusHistoryDTO clusterStatusHistory = new StatusHistoryDTO();
+        clusterStatusHistory.setAggregateSnapshots(mergeStatusHistories(nodeStatusSnapshots, metricDescriptors));
+        clusterStatusHistory.setGenerated(new Date());
+        clusterStatusHistory.setNodeSnapshots(nodeStatusSnapshots);
+        if (lastStatusHistory != null) {
+            clusterStatusHistory.setComponentDetails(lastStatusHistory.getComponentDetails());
+            clusterStatusHistory.setFieldDescriptors(lastStatusHistory.getFieldDescriptors());
+        }
+
+        final StatusHistoryEntity clusterEntity = new StatusHistoryEntity();
+        clusterEntity.setStatusHistory(clusterStatusHistory);
+        clusterEntity.setRevision(responseEntity.getRevision());
+
+        return new NodeResponse(clientResponse, clusterEntity);
+    }
+
+
+
     /**
      * Determines if all problematic responses were due to 404 NOT_FOUND. Assumes that problematicNodeResponses is not empty and is not comprised of responses from all nodes in the cluster (at least
      * one node contained the counter in question).
@@ -3612,7 +4261,7 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
      * @return Whether all problematic node responses were due to a missing counter
      */
     private boolean isMissingCounter(final Set<NodeResponse> problematicNodeResponses, final URI uri) {
-        if (isCountersEndpoint(uri)) {
+        if (isCounterEndpoint(uri)) {
             boolean notFound = true;
             for (final NodeResponse problematicResponse : problematicNodeResponses) {
                 if (problematicResponse.getStatus() != 404) {
@@ -4026,207 +4675,12 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return bulletinRepository;
     }
 
-    @Override
-    public ProcessGroupStatus getProcessGroupStatus(final String groupId) {
-        final Set<Node> connectedNodes = getNodes(Node.Status.CONNECTED);
-
-        // ensure there are some nodes in the cluster
-        if (connectedNodes.isEmpty()) {
-            throw new NoConnectedNodesException();
-        }
-
-        ProcessGroupStatus mergedProcessGroupStatus = null;
-        for (final Node node : connectedNodes) {
-            final NodeIdentifier nodeId = node.getNodeId();
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-            final ProcessGroupStatus nodeRootProcessGroupStatus = nodeHeartbeatPayload.getProcessGroupStatus();
-            final ProcessGroupStatus nodeProcessGroupStatus = groupId.equals(ROOT_GROUP_ID_ALIAS) ? nodeRootProcessGroupStatus : getProcessGroupStatus(nodeRootProcessGroupStatus, groupId);
-            if (nodeProcessGroupStatus == null) {
-                continue;
-            }
-
-            if (mergedProcessGroupStatus == null) {
-                mergedProcessGroupStatus = nodeProcessGroupStatus.clone();
-
-                // update any  issues with the node label
-                if (mergedProcessGroupStatus.getRemoteProcessGroupStatus() != null) {
-                    for (final RemoteProcessGroupStatus remoteProcessGroupStatus : mergedProcessGroupStatus.getRemoteProcessGroupStatus()) {
-                        final List<String> nodeAuthorizationIssues = remoteProcessGroupStatus.getAuthorizationIssues();
-                        if (!nodeAuthorizationIssues.isEmpty()) {
-                            for (final ListIterator<String> iter = nodeAuthorizationIssues.listIterator(); iter.hasNext();) {
-                                final String Issue = iter.next();
-                                iter.set("[" + nodeId.getApiAddress() + ":" + nodeId.getApiPort() + "] -- " + Issue);
-                            }
-                            remoteProcessGroupStatus.setAuthorizationIssues(nodeAuthorizationIssues);
-                        }
-                    }
-                }
-            } else {
-                final ProcessGroupStatus nodeClone = nodeProcessGroupStatus.clone();
-                for (final RemoteProcessGroupStatus remoteProcessGroupStatus : nodeClone.getRemoteProcessGroupStatus()) {
-                    final List<String> nodeAuthorizationIssues = remoteProcessGroupStatus.getAuthorizationIssues();
-                    if (!nodeAuthorizationIssues.isEmpty()) {
-                        for (final ListIterator<String> iter = nodeAuthorizationIssues.listIterator(); iter.hasNext();) {
-                            final String Issue = iter.next();
-                            iter.set("[" + nodeId.getApiAddress() + ":" + nodeId.getApiPort() + "] -- " + Issue);
-                        }
-                        remoteProcessGroupStatus.setAuthorizationIssues(nodeAuthorizationIssues);
-                    }
-                }
-
-                ProcessGroupStatus.merge(mergedProcessGroupStatus, nodeClone);
-            }
-        }
-
-        return mergedProcessGroupStatus;
-    }
-
-    private ProcessGroupStatus getProcessGroupStatus(final ProcessGroupStatus parent, final String groupId) {
-        if (parent.getId().equals(groupId)) {
-            return parent;
-        }
-
-        for (final ProcessGroupStatus child : parent.getProcessGroupStatus()) {
-            final ProcessGroupStatus matching = getProcessGroupStatus(child, groupId);
-            if (matching != null) {
-                return matching;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public SystemDiagnostics getSystemDiagnostics() {
-        final Set<Node> connectedNodes = getNodes(Node.Status.CONNECTED);
-
-        // ensure there are some nodes...
-        if (connectedNodes.isEmpty()) {
-            throw new NoConnectedNodesException();
-        }
-
-        SystemDiagnostics clusterDiagnostics = null;
-        for (final Node node : connectedNodes) {
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-            final SystemDiagnostics nodeDiagnostics = nodeHeartbeatPayload.getSystemDiagnostics();
-            if (nodeDiagnostics == null) {
-                continue;
-            }
-
-            if (clusterDiagnostics == null) {
-                clusterDiagnostics = nodeDiagnostics.clone();
-            } else {
-                merge(clusterDiagnostics, nodeDiagnostics);
-            }
-        }
-
-        return clusterDiagnostics;
-    }
-
-    private void merge(final SystemDiagnostics target, final SystemDiagnostics sd) {
-
-        // threads
-        target.setDaemonThreads(target.getDaemonThreads() + sd.getDaemonThreads());
-        target.setTotalThreads(target.getTotalThreads() + sd.getTotalThreads());
-
-        // heap
-        target.setTotalHeap(target.getTotalHeap() + sd.getTotalHeap());
-        target.setUsedHeap(target.getUsedHeap() + sd.getUsedHeap());
-        target.setMaxHeap(target.getMaxHeap() + sd.getMaxHeap());
-
-        // non heap
-        target.setTotalNonHeap(target.getTotalNonHeap() + sd.getTotalNonHeap());
-        target.setUsedNonHeap(target.getUsedNonHeap() + sd.getUsedNonHeap());
-        target.setMaxNonHeap(target.getMaxNonHeap() + sd.getMaxNonHeap());
-
-        // processors
-        target.setAvailableProcessors(target.getAvailableProcessors() + sd.getAvailableProcessors());
-
-        // load
-        if (sd.getProcessorLoadAverage() != null) {
-            if (target.getProcessorLoadAverage() != null) {
-                target.setProcessorLoadAverage(target.getProcessorLoadAverage() + sd.getProcessorLoadAverage());
-            } else {
-                target.setProcessorLoadAverage(sd.getProcessorLoadAverage());
-            }
-        }
-
-        // db disk usage
-        merge(target.getFlowFileRepositoryStorageUsage(), sd.getFlowFileRepositoryStorageUsage());
-
-        // repo disk usage
-        final Map<String, StorageUsage> targetContentRepoMap;
-        if (target.getContentRepositoryStorageUsage() == null) {
-            targetContentRepoMap = new LinkedHashMap<>();
-            target.setContentRepositoryStorageUsage(targetContentRepoMap);
-        } else {
-            targetContentRepoMap = target.getContentRepositoryStorageUsage();
-        }
-        if (sd.getContentRepositoryStorageUsage() != null) {
-            for (final Map.Entry<String, StorageUsage> sdEntry : sd.getContentRepositoryStorageUsage().entrySet()) {
-                final StorageUsage mergedDiskUsage = targetContentRepoMap.get(sdEntry.getKey());
-                if (mergedDiskUsage == null) {
-                    targetContentRepoMap.put(sdEntry.getKey(), sdEntry.getValue());
-                } else {
-                    merge(mergedDiskUsage, sdEntry.getValue());
-                }
-            }
-        }
-
-        // garbage collection
-        final Map<String, GarbageCollection> targetGarbageCollection;
-        if (target.getGarbageCollection() == null) {
-            targetGarbageCollection = new LinkedHashMap<>();
-            target.setGarbageCollection(targetGarbageCollection);
-        } else {
-            targetGarbageCollection = target.getGarbageCollection();
-        }
-        if (sd.getGarbageCollection() != null) {
-            for (final Map.Entry<String, GarbageCollection> gcEntry : sd.getGarbageCollection().entrySet()) {
-                final GarbageCollection mergedGarbageCollection = targetGarbageCollection.get(gcEntry.getKey());
-                if (mergedGarbageCollection == null) {
-                    targetGarbageCollection.put(gcEntry.getKey(), gcEntry.getValue().clone());
-                } else {
-                    merge(mergedGarbageCollection, gcEntry.getValue());
-                }
-            }
-        }
-    }
-
-    private void merge(final StorageUsage target, final StorageUsage du) {
-        target.setFreeSpace(target.getFreeSpace() + du.getFreeSpace());
-        target.setTotalSpace(target.getTotalSpace() + du.getTotalSpace());
-    }
-
-    private void merge(final GarbageCollection target, final GarbageCollection gc) {
-        target.setCollectionCount(target.getCollectionCount() + gc.getCollectionCount());
-        target.setCollectionTime(target.getCollectionTime() + gc.getCollectionTime());
-    }
 
     public static Date normalizeStatusSnapshotDate(final Date toNormalize, final long numMillis) {
         final long time = toNormalize.getTime();
         return new Date(time - time % numMillis);
     }
 
-    private NodeDTO createNodeDTO(final Node node) {
-        final NodeDTO nodeDto = new NodeDTO();
-        final NodeIdentifier nodeId = node.getNodeId();
-        nodeDto.setNodeId(nodeId.getId());
-        nodeDto.setAddress(nodeId.getApiAddress());
-        nodeDto.setApiPort(nodeId.getApiPort());
-        nodeDto.setStatus(node.getStatus().name());
-        nodeDto.setPrimary(node.equals(getPrimaryNode()));
-        final Date connectionRequested = new Date(node.getConnectionRequestedTimestamp());
-        nodeDto.setConnectionRequested(connectionRequested);
-
-        return nodeDto;
-    }
 
     private List<StatusSnapshotDTO> aggregate(Map<Date, List<StatusSnapshot>> snapshotsToAggregate) {
         // Aggregate the snapshots
@@ -4245,278 +4699,65 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         return aggregatedSnapshotDtos;
     }
 
-    public ClusterStatusHistoryDTO getProcessorStatusHistory(final String processorId) {
-        return getProcessorStatusHistory(processorId, null, null, Integer.MAX_VALUE);
-    }
-
-    public ClusterStatusHistoryDTO getProcessorStatusHistory(final String processorId, final Date startDate, final Date endDate, final int preferredDataPoints) {
-        final List<NodeStatusHistoryDTO> nodeHistories = new ArrayList<>();
 
-        StatusHistoryDTO lastStatusHistory = null;
-        final Set<MetricDescriptor<?>> processorDescriptors = new LinkedHashSet<>();
-        final Map<Date, List<StatusSnapshot>> snapshotsToAggregate = new TreeMap<>();
+    private StatusSnapshot createSnapshot(final StatusSnapshotDTO snapshotDto, final Map<String, MetricDescriptor<?>> metricDescriptors) {
+        final StandardStatusSnapshot snapshot = new StandardStatusSnapshot();
+        snapshot.setTimestamp(snapshotDto.getTimestamp());
 
-        for (final Node node : getRawNodes()) {
-            final ComponentStatusRepository statusRepository = componentMetricsRepositoryMap.get(node.getNodeId());
-            if (statusRepository == null) {
-                continue;
-            }
+        final Map<String, Long> metrics = snapshotDto.getStatusMetrics();
+        for (final Map.Entry<String, Long> entry : metrics.entrySet()) {
+            final String metricId = entry.getKey();
+            final Long value = entry.getValue();
 
-            final StatusHistory statusHistory = statusRepository.getProcessorStatusHistory(processorId, startDate, endDate, preferredDataPoints);
-            if (statusHistory == null) {
-                continue;
-            }
-
-            processorDescriptors.addAll(statusRepository.getProcessorMetricDescriptors());
-
-            // record the status history (last) to get the component details for use later
-            final StatusHistoryDTO statusHistoryDto = createStatusHistoryDto(statusHistory);
-            lastStatusHistory = statusHistoryDto;
-
-            final NodeStatusHistoryDTO nodeHistory = new NodeStatusHistoryDTO();
-            nodeHistory.setStatusHistory(statusHistoryDto);
-            nodeHistory.setNode(createNodeDTO(node));
-            nodeHistories.add(nodeHistory);
-
-            // collect all of the snapshots to aggregate
-            for (final StatusSnapshot snapshot : statusHistory.getStatusSnapshots()) {
-                final Date normalizedDate = normalizeStatusSnapshotDate(snapshot.getTimestamp(), componentStatusSnapshotMillis);
-                List<StatusSnapshot> snapshots = snapshotsToAggregate.get(normalizedDate);
-                if (snapshots == null) {
-                    snapshots = new ArrayList<>();
-                    snapshotsToAggregate.put(normalizedDate, snapshots);
-                }
-                snapshots.add(snapshot);
+            final MetricDescriptor<?> descriptor = metricDescriptors.get(metricId);
+            if (descriptor != null) {
+                snapshot.addStatusMetric(descriptor, value);
             }
         }
 
-        // Aggregate the snapshots
-        final List<StatusSnapshotDTO> aggregatedSnapshotDtos = aggregate(snapshotsToAggregate);
-
-        // get the details for this component from the last status history
-        final LinkedHashMap<String, String> clusterStatusHistoryDetails = new LinkedHashMap<>();
-        clusterStatusHistoryDetails.putAll(lastStatusHistory.getDetails());
-
-        final StatusHistoryDTO clusterStatusHistory = new StatusHistoryDTO();
-        clusterStatusHistory.setGenerated(new Date());
-        clusterStatusHistory.setFieldDescriptors(StatusHistoryUtil.createFieldDescriptorDtos(processorDescriptors));
-        clusterStatusHistory.setDetails(clusterStatusHistoryDetails);
-        clusterStatusHistory.setStatusSnapshots(aggregatedSnapshotDtos);
-
-        final ClusterStatusHistoryDTO history = new ClusterStatusHistoryDTO();
-        history.setGenerated(new Date());
-        history.setNodeStatusHistory(nodeHistories);
-        history.setClusterStatusHistory(clusterStatusHistory);
-        return history;
+        return snapshot;
     }
 
-    public StatusHistoryDTO createStatusHistoryDto(final StatusHistory statusHistory) {
-        final StatusHistoryDTO dto = new StatusHistoryDTO();
-
-        dto.setDetails(new LinkedHashMap<>(statusHistory.getComponentDetails()));
-        dto.setFieldDescriptors(StatusHistoryUtil.createFieldDescriptorDtos(statusHistory));
-        dto.setGenerated(statusHistory.getDateGenerated());
+    private List<StatusSnapshotDTO> mergeStatusHistories(final List<NodeStatusSnapshotsDTO> nodeStatusSnapshots, final Map<String, MetricDescriptor<?>> metricDescriptors) {
+        // We want a Map<Date, List<StatusSnapshot>>, which is a Map of "normalized Date" (i.e., a time range, essentially)
+        // to all Snapshots for that time. The list will contain one snapshot for each node. However, we can have the case
+        // where the NCM has a different value for the componentStatusSnapshotMillis than the nodes have. In this case,
+        // we end up with multiple entries in the List<StatusSnapshot> for the same node/timestamp, which skews our aggregate
+        // results. In order to avoid this, we will use only the latest snapshot for a node that falls into the the time range
+        // of interest.
+        // To accomplish this, we have an intermediate data structure, which is a Map of "normalized Date" to an inner Map
+        // of Node Identifier to StatusSnapshot. We then will flatten this Map and aggregate the results.
+        final Map<Date, Map<String, StatusSnapshot>> dateToNodeSnapshots = new TreeMap<>();
 
-        final List<StatusSnapshotDTO> statusSnapshots = new ArrayList<>();
-        for (final StatusSnapshot statusSnapshot : statusHistory.getStatusSnapshots()) {
-            statusSnapshots.add(StatusHistoryUtil.createStatusSnapshotDto(statusSnapshot));
-        }
-        dto.setStatusSnapshots(statusSnapshots);
-
-        return dto;
-    }
-
-    public ClusterStatusHistoryDTO getConnectionStatusHistory(final String connectionId) {
-        return getConnectionStatusHistory(connectionId, null, null, Integer.MAX_VALUE);
-    }
-
-    public ClusterStatusHistoryDTO getConnectionStatusHistory(final String connectionId, final Date startDate, final Date endDate, final int preferredDataPoints) {
-        final List<NodeStatusHistoryDTO> nodeHistories = new ArrayList<>();
-
-        StatusHistoryDTO lastStatusHistory = null;
-        final Set<MetricDescriptor<?>> connectionDescriptors = new LinkedHashSet<>();
-        final Map<Date, List<StatusSnapshot>> snapshotsToAggregate = new TreeMap<>();
-
-        for (final Node node : getRawNodes()) {
-            final ComponentStatusRepository statusRepository = componentMetricsRepositoryMap.get(node.getNodeId());
-            if (statusRepository == null) {
-                continue;
-            }
-
-            final StatusHistory statusHistory = statusRepository.getConnectionStatusHistory(connectionId, startDate, endDate, preferredDataPoints);
-            if (statusHistory == null) {
-                continue;
-            }
-
-            final StatusHistoryDTO statusHistoryDto = createStatusHistoryDto(statusHistory);
-            // record the status history (last) to get the componet details for use later
-            lastStatusHistory = statusHistoryDto;
-            connectionDescriptors.addAll(statusRepository.getConnectionMetricDescriptors());
-
-            final NodeStatusHistoryDTO nodeHistory = new NodeStatusHistoryDTO();
-            nodeHistory.setStatusHistory(statusHistoryDto);
-            nodeHistory.setNode(createNodeDTO(node));
-            nodeHistories.add(nodeHistory);
-
-            // collect all of the snapshots to aggregate
-            for (final StatusSnapshot snapshot : statusHistory.getStatusSnapshots()) {
+        // group status snapshot's for each node by date
+        for (final NodeStatusSnapshotsDTO nodeStatusSnapshot : nodeStatusSnapshots) {
+            for (final StatusSnapshotDTO snapshotDto : nodeStatusSnapshot.getStatusSnapshots()) {
+                final StatusSnapshot snapshot = createSnapshot(snapshotDto, metricDescriptors);
                 final Date normalizedDate = normalizeStatusSnapshotDate(snapshot.getTimestamp(), componentStatusSnapshotMillis);
-                List<StatusSnapshot> snapshots = snapshotsToAggregate.get(normalizedDate);
-                if (snapshots == null) {
-                    snapshots = new ArrayList<>();
-                    snapshotsToAggregate.put(normalizedDate, snapshots);
-                }
-                snapshots.add(snapshot);
-            }
-        }
-
-        // Aggregate the snapshots
-        final List<StatusSnapshotDTO> aggregatedSnapshotDtos = aggregate(snapshotsToAggregate);
-
-        // get the details for this component from the last status history
-        final LinkedHashMap<String, String> clusterStatusHistoryDetails = new LinkedHashMap<>();
-        clusterStatusHistoryDetails.putAll(lastStatusHistory.getDetails());
-
-        final StatusHistoryDTO clusterStatusHistory = new StatusHistoryDTO();
-        clusterStatusHistory.setGenerated(new Date());
-        clusterStatusHistory.setFieldDescriptors(StatusHistoryUtil.createFieldDescriptorDtos(connectionDescriptors));
-        clusterStatusHistory.setDetails(clusterStatusHistoryDetails);
-        clusterStatusHistory.setStatusSnapshots(aggregatedSnapshotDtos);
-
-        final ClusterStatusHistoryDTO history = new ClusterStatusHistoryDTO();
-        history.setGenerated(new Date());
-        history.setNodeStatusHistory(nodeHistories);
-        history.setClusterStatusHistory(clusterStatusHistory);
-        return history;
-    }
-
-    public ClusterStatusHistoryDTO getProcessGroupStatusHistory(final String processGroupId) {
-        return getProcessGroupStatusHistory(processGroupId, null, null, Integer.MAX_VALUE);
-    }
-
-    public ClusterStatusHistoryDTO getProcessGroupStatusHistory(final String processGroupId, final Date startDate, final Date endDate, final int preferredDataPoints) {
-        final List<NodeStatusHistoryDTO> nodeHistories = new ArrayList<>();
 
-        StatusHistoryDTO lastStatusHistory = null;
-        final Set<MetricDescriptor<?>> processGroupDescriptors = new LinkedHashSet<>();
-        final Map<Date, List<StatusSnapshot>> snapshotsToAggregate = new TreeMap<>();
-
-        for (final Node node : getRawNodes()) {
-            final ComponentStatusRepository statusRepository = componentMetricsRepositoryMap.get(node.getNodeId());
-            if (statusRepository == null) {
-                continue;
-            }
-
-            final StatusHistory statusHistory = statusRepository.getProcessGroupStatusHistory(processGroupId, startDate, endDate, preferredDataPoints);
-            if (statusHistory == null) {
-                continue;
-            }
-
-            final StatusHistoryDTO statusHistoryDto = createStatusHistoryDto(statusHistory);
-            // record the status history (last) to get the componet details for use later
-            lastStatusHistory = statusHistoryDto;
-            processGroupDescriptors.addAll(statusRepository.getProcessGroupMetricDescriptors());
-
-            final NodeStatusHistoryDTO nodeHistory = new NodeStatusHistoryDTO();
-            nodeHistory.setStatusHistory(statusHistoryDto);
-            nodeHistory.setNode(createNodeDTO(node));
-            nodeHistories.add(nodeHistory);
-
-            // collect all of the snapshots to aggregate
-            for (final StatusSnapshot snapshot : statusHistory.getStatusSnapshots()) {
-                final Date normalizedDate = normalizeStatusSnapshotDate(snapshot.getTimestamp(), componentStatusSnapshotMillis);
-                List<StatusSnapshot> snapshots = snapshotsToAggregate.get(normalizedDate);
-                if (snapshots == null) {
-                    snapshots = new ArrayList<>();
-                    snapshotsToAggregate.put(normalizedDate, snapshots);
+                Map<String, StatusSnapshot> nodeToSnapshotMap = dateToNodeSnapshots.get(normalizedDate);
+                if (nodeToSnapshotMap == null) {
+                    nodeToSnapshotMap = new HashMap<>();
+                    dateToNodeSnapshots.put(normalizedDate, nodeToSnapshotMap);
                 }
-                snapshots.add(snapshot);
+                nodeToSnapshotMap.put(nodeStatusSnapshot.getNodeId(), snapshot);
             }
         }
 
-        // Aggregate the snapshots
-        final List<StatusSnapshotDTO> aggregatedSnapshotDtos = aggregate(snapshotsToAggregate);
-
-        // get the details for this component from the last status history
-        final LinkedHashMap<String, String> clusterStatusHistoryDetails = new LinkedHashMap<>();
-        clusterStatusHistoryDetails.putAll(lastStatusHistory.getDetails());
-
-        final StatusHistoryDTO clusterStatusHistory = new StatusHistoryDTO();
-        clusterStatusHistory.setGenerated(new Date());
-        clusterStatusHistory.setDetails(clusterStatusHistoryDetails);
-        clusterStatusHistory.setFieldDescriptors(StatusHistoryUtil.createFieldDescriptorDtos(processGroupDescriptors));
-        clusterStatusHistory.setStatusSnapshots(aggregatedSnapshotDtos);
-
-        final ClusterStatusHistoryDTO history = new ClusterStatusHistoryDTO();
-        history.setGenerated(new Date());
-        history.setNodeStatusHistory(nodeHistories);
-        history.setClusterStatusHistory(clusterStatusHistory);
-        return history;
-    }
-
-    public ClusterStatusHistoryDTO getRemoteProcessGroupStatusHistory(final String remoteGroupId) {
-        return getRemoteProcessGroupStatusHistory(remoteGroupId, null, null, Integer.MAX_VALUE);
-    }
-
-    public ClusterStatusHistoryDTO getRemoteProcessGroupStatusHistory(final String remoteGroupId, final Date startDate, final Date endDate, final int preferredDataPoints) {
-        final List<NodeStatusHistoryDTO> nodeHistories = new ArrayList<>();
-
-        StatusHistoryDTO lastStatusHistory = null;
-        final Set<MetricDescriptor<?>> remoteProcessGroupDescriptors = new LinkedHashSet<>();
+        // aggregate the snapshots by (normalized) timestamp
         final Map<Date, List<StatusSnapshot>> snapshotsToAggregate = new TreeMap<>();
-
-        for (final Node node : getRawNodes()) {
-            final ComponentStatusRepository statusRepository = componentMetricsRepositoryMap.get(node.getNodeId());
-            if (statusRepository == null) {
-                continue;
-            }
-
-            final StatusHistory statusHistory = statusRepository.getRemoteProcessGroupStatusHistory(remoteGroupId, startDate, endDate, preferredDataPoints);
-            if (statusHistory == null) {
-                continue;
-            }
-
-            final StatusHistoryDTO statusHistoryDto = createStatusHistoryDto(statusHistory);
-            // record the status history (last) to get the componet details for use later
-            lastStatusHistory = statusHistoryDto;
-            remoteProcessGroupDescriptors.addAll(statusRepository.getRemoteProcessGroupMetricDescriptors());
-
-            final NodeStatusHistoryDTO nodeHistory = new NodeStatusHistoryDTO();
-            nodeHistory.setStatusHistory(statusHistoryDto);
-            nodeHistory.setNode(createNodeDTO(node));
-            nodeHistories.add(nodeHistory);
-
-            // collect all of the snapshots to aggregate
-            for (final StatusSnapshot snapshot : statusHistory.getStatusSnapshots()) {
-                final Date normalizedDate = normalizeStatusSnapshotDate(snapshot.getTimestamp(), componentStatusSnapshotMillis);
-                List<StatusSnapshot> snapshots = snapshotsToAggregate.get(normalizedDate);
-                if (snapshots == null) {
-                    snapshots = new ArrayList<>();
-                    snapshotsToAggregate.put(normalizedDate, snapshots);
-                }
-                snapshots.add(snapshot);
-            }
+        for (final Map.Entry<Date, Map<String, StatusSnapshot>> entry : dateToNodeSnapshots.entrySet()) {
+            final Date normalizedDate = entry.getKey();
+            final Map<String, StatusSnapshot> nodeToSnapshot = entry.getValue();
+            final List<StatusSnapshot> snapshotsForTimestamp = new ArrayList<>(nodeToSnapshot.values());
+            snapshotsToAggregate.put(normalizedDate, snapshotsForTimestamp);
         }
 
-        // Aggregate the snapshots
-        final List<StatusSnapshotDTO> aggregatedSnapshotDtos = aggregate(snapshotsToAggregate);
+        final List<StatusSnapshotDTO> aggregatedSnapshots = aggregate(snapshotsToAggregate);
+        return aggregatedSnapshots;
+    }
 
-        // get the details for this comp

<TRUNCATED>

[17/18] nifi git commit: NIFI-1552: - Introducing the Authorizer API and additional components necessary for discovery and creation of configured instances. - Minor refactoring of existing Authority Provider API code/configuration to avoid some xsd namin

Posted by mc...@apache.org.
NIFI-1552: - Introducing the Authorizer API and additional components necessary for discovery and creation of configured instances. - Minor refactoring of existing Authority Provider API code/configuration to avoid some xsd naming conflicts. These components will be removed in NIFI-1551. - Introducing a number of the resource definitions that the Authorizer will make access decisions on. This list is likely not finalized may see some changes in NIFI-1554. - Address comments from PR. - This closes #318.

Signed-off-by: Matt Gilman <ma...@gmail.com>


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

Branch: refs/heads/master
Commit: 9aa69b242efca4d5103852facacb412e0f0b6022
Parents: 1ac0526
Author: Matt Gilman <ma...@gmail.com>
Authored: Fri Apr 1 15:13:00 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Mon Apr 4 11:47:43 2016 -0400

----------------------------------------------------------------------
 .travis.yml                                     |   2 -
 .../authorization/AuthorizationRequest.java     | 132 +++++++
 .../nifi/authorization/AuthorizationResult.java |  99 ++++++
 .../apache/nifi/authorization/Authorizer.java   |  61 ++++
 .../AuthorizerConfigurationContext.java         |  48 +++
 .../AuthorizerInitializationContext.java        |  37 ++
 .../nifi/authorization/AuthorizerLookup.java    |  31 ++
 .../nifi/authorization/RequestAction.java       |  25 ++
 .../org/apache/nifi/authorization/Resource.java |  37 ++
 .../annotation/AuthorizerContext.java           |  35 ++
 .../exception/AuthorizationAccessException.java |  32 ++
 .../exception/AuthorizerCreationException.java  |  39 +++
 .../AuthorizerDestructionException.java         |  39 +++
 .../AuthorityProviderFactoryBean.java           |  45 +--
 .../authorization/AuthorizerFactoryBean.java    | 343 +++++++++++++++++++
 ...rdAuthorityProviderConfigurationContext.java |   5 +-
 .../StandardAuthorizerConfigurationContext.java |  51 +++
 ...StandardAuthorizerInitializationContext.java |  41 +++
 .../resources/nifi-administration-context.xml   |  11 +-
 .../src/main/xsd/authority-providers.xsd        |  12 +-
 .../src/main/xsd/authorizers.xsd                |  49 +++
 .../nifi-framework-authorization/pom.xml        |  31 ++
 .../authorization/resource/ResourceFactory.java | 272 +++++++++++++++
 .../authorization/resource/ResourceType.java    |  39 +++
 .../nifi-framework/pom.xml                      |   1 +
 25 files changed, 1480 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index b5c02d0..811a4c2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,8 +5,6 @@ os:
 
 jdk:
   - oraclejdk8
-  - oraclejdk7
-  - openjdk7
 
 # before_install aids in a couple workarounds for issues within the Travis-CI environment
 #   1. Workaround for buffer overflow issues with OpenJDK versions of java as per https://github.com/travis-ci/travis-ci/issues/5227#issuecomment-165135711

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
new file mode 100644
index 0000000..38c9e26
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Represents an authorization request for a given user/entity performing an action against a resource within some context.
+ */
+public class AuthorizationRequest {
+
+    private final Resource resource;
+    private final String identity;
+    private final RequestAction action;
+    private final Map<String, String> context;
+    private final Map<String, String> eventAttributes;
+
+    private AuthorizationRequest(final Builder builder) {
+        Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
+        Objects.requireNonNull(builder.identity, "The identity of the user is required when creating an authorization request");
+        Objects.requireNonNull(builder.action, "The action is required when creating an authorization request");
+
+        this.resource = builder.resource;
+        this.identity = builder.identity;
+        this.action = builder.action;
+        this.context = Collections.unmodifiableMap(builder.context);
+        this.eventAttributes = Collections.unmodifiableMap(builder.eventAttributes);
+    }
+
+    /**
+     * The Resource being authorized. Not null.
+     *
+     * @return The resource
+     */
+    public Resource getResource() {
+        return resource;
+    }
+
+    /**
+     * The identity accessing the Resource. Not null.
+     *
+     * @return The identity
+     */
+    public String getIdentity() {
+        return identity;
+    }
+
+    /**
+     * The action being taken against the Resource. Not null.
+     *
+     * @return The action
+     */
+    public RequestAction getAction() {
+        return action;
+    }
+
+    /**
+     * The context of the user request to make additional access decisions. May be null.
+     *
+     * @return  The context of the user request
+     */
+    public Map<String, String> getContext() {
+        return context;
+    }
+
+    /**
+     * The event attributes to make additional access decisions for provenance events. May be null.
+     *
+     * @return  The event attributes
+     */
+    public Map<String, String> getEventAttributes() {
+        return eventAttributes;
+    }
+
+    /**
+     * AuthorizationRequest builder.
+     */
+    public static final class Builder {
+
+        private Resource resource;
+        private String identity;
+        private RequestAction action;
+        private Map<String, String> context;
+        private Map<String, String> eventAttributes;
+
+        public Builder resource(final Resource resource) {
+            this.resource = resource;
+            return this;
+        }
+
+        public Builder identity(final String identity) {
+            this.identity = identity;
+            return this;
+        }
+
+        public Builder action(final RequestAction action) {
+            this.action = action;
+            return this;
+        }
+
+        public Builder context(final Map<String, String> context) {
+            this.context = new HashMap<>(context);
+            return this;
+        }
+
+        public Builder eventAttributes(final Map<String, String> eventAttributes) {
+            this.eventAttributes = new HashMap<>(eventAttributes);
+            return this;
+        }
+
+        public AuthorizationRequest build() {
+            return new AuthorizationRequest(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
new file mode 100644
index 0000000..acbbbe2
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+/**
+ * Represents a decision whether authorization is granted.
+ */
+public class AuthorizationResult {
+
+    private enum Result {
+        Approved,
+        Denied,
+        ResourceNotFound
+    }
+
+    private static final AuthorizationResult APPROVED = new AuthorizationResult(Result.Approved, null);
+    private static final AuthorizationResult RESOURCE_NOT_FOUND = new AuthorizationResult(Result.ResourceNotFound, null);
+
+    private final Result result;
+    private final String explanation;
+
+    /**
+     * Creates a new AuthorizationResult with the specified result and explanation.
+     *
+     * @param result of the authorization
+     * @param explanation for the authorization attempt
+     */
+    private AuthorizationResult(Result result, String explanation) {
+        if (Result.Denied.equals(result) && explanation == null) {
+            throw new IllegalArgumentException("An explanation is required when the authorization request is denied.");
+        }
+
+        this.result = result;
+        this.explanation = explanation;
+    }
+
+    /**
+     * @return Whether or not the request is approved
+     */
+    public Result getResult() {
+        return result;
+    }
+
+    /**
+     * @return If the request is denied, the reason why. Null otherwise
+     */
+    public String getExplanation() {
+        return explanation;
+    }
+
+    /**
+     * @return a new approved AuthorizationResult
+     */
+    public static AuthorizationResult approved() {
+        return APPROVED;
+    }
+
+    /**
+     * Resource not found will indicate that there are no specific authorization rules for this resource.
+     * @return a new resource not found AuthorizationResult
+     */
+    public static AuthorizationResult resourceNotFound() {
+        return RESOURCE_NOT_FOUND;
+    }
+
+    /**
+     * Creates a new denied AuthorizationResult with a message indicating 'Access is denied'.
+     *
+     * @return a new denied AuthorizationResult
+     */
+    public static AuthorizationResult denied() {
+        return denied("Access is denied");
+    }
+
+    /**
+     * Creates a new denied AuthorizationResult with the specified explanation.
+     *
+     * @param explanation for why it was denied
+     * @return a new denied AuthorizationResult with the specified explanation
+     * @throws IllegalArgumentException if explanation is null
+     */
+    public static AuthorizationResult denied(String explanation) {
+        return new AuthorizationResult(Result.Denied, explanation);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java b/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
new file mode 100644
index 0000000..eb18cf0
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/Authorizer.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+
+/**
+ * Authorizes user requests.
+ */
+public interface Authorizer {
+
+    /**
+     * Determines if the specified user/entity is authorized to access the specified resource within the given context.
+     *
+     * @param   request The authorization request
+     * @return  the authorization result
+     * @throws  AuthorityAccessException if unable to access the authorities
+     */
+    AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException;
+
+    /**
+     * Called immediately after instance creation for implementers to perform additional setup
+     *
+     * @param initializationContext in which to initialize
+     */
+    void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException;
+
+    /**
+     * Called to configure the Authorizer.
+     *
+     * @param configurationContext at the time of configuration
+     * @throws AuthorizerCreationException for any issues configuring the provider
+     */
+    void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException;
+
+    /**
+     * Called immediately before instance destruction for implementers to release resources.
+     *
+     * @throws AuthorizerDestructionException If pre-destruction fails.
+     */
+    void preDestruction() throws AuthorizerDestructionException;
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
new file mode 100644
index 0000000..b2b6b3a
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface AuthorizerConfigurationContext {
+
+    /**
+     * @return identifier for the authorizer
+     */
+    String getIdentifier();
+
+    /**
+     * Retrieves all properties the component currently understands regardless
+     * of whether a value has been set for them or not. If no value is present
+     * then its value is null and thus any registered default for the property
+     * descriptor applies.
+     *
+     * @return Map of all properties
+     */
+    Map<String, String> getProperties();
+
+    /**
+     * @param property to lookup the descriptor and value of
+     * @return the value the component currently understands for the given
+     * PropertyDescriptor. This method does not substitute default
+     * PropertyDescriptor values, so the value returned will be null if not set
+     */
+    String getProperty(String property);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java
new file mode 100644
index 0000000..4b3d77c
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerInitializationContext.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+/**
+ * Initialization content for Authorizers.
+ */
+public interface AuthorizerInitializationContext {
+
+    /**
+     * The identifier of the Authorizer.
+     *
+     * @return  The identifier
+     */
+    public String getIdentifier();
+
+    /**
+     * The lookup for accessing other configured Authorizers.
+     *
+     * @return  The Authorizer lookup
+     */
+    public AuthorizerLookup getAuthorizerLookup();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java
new file mode 100644
index 0000000..9669976
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerLookup.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+/**
+ *
+ */
+public interface AuthorizerLookup {
+
+    /**
+     * Looks up the Authorizer with the specified identifier
+     *
+     * @param identifier        The identifier of the Authorizer
+     * @return                  The Authorizer
+     */
+    Authorizer getAuthorizer(String identifier);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/RequestAction.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/RequestAction.java b/nifi-api/src/main/java/org/apache/nifi/authorization/RequestAction.java
new file mode 100644
index 0000000..182988f
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/RequestAction.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+/**
+ * Actions a user/entity can take on a resource.
+ */
+public enum RequestAction {
+    READ,
+    WRITE;
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/Resource.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/Resource.java b/nifi-api/src/main/java/org/apache/nifi/authorization/Resource.java
new file mode 100644
index 0000000..7756bda
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/Resource.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+/**
+ * Resource in an authorization request.
+ */
+public interface Resource {
+
+    /**
+     * The identifier for this resource.
+     *
+     * @return identifier for this resource
+     */
+    String getIdentifier();
+
+    /**
+     * The name of this resource.
+     *
+     * @return name of this resource
+     */
+    String getName();
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java
new file mode 100644
index 0000000..b0d3f83
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/annotation/AuthorizerContext.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ *
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface AuthorizerContext {
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java
new file mode 100644
index 0000000..8b22d45
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizationAccessException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization.exception;
+
+/**
+ * Represents the case when an authorization decision could not be made because the Authorizer was unable to access the underlying data store.
+ */
+public class AuthorizationAccessException extends RuntimeException {
+
+    public AuthorizationAccessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AuthorizationAccessException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java
new file mode 100644
index 0000000..4264202
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerCreationException.java
@@ -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.
+ */
+package org.apache.nifi.authorization.exception;
+
+/**
+ * Represents the exceptional case when an Authorizer fails instantiation.
+ *
+ */
+public class AuthorizerCreationException extends RuntimeException {
+
+    public AuthorizerCreationException() {
+    }
+
+    public AuthorizerCreationException(String msg) {
+        super(msg);
+    }
+
+    public AuthorizerCreationException(Throwable cause) {
+        super(cause);
+    }
+
+    public AuthorizerCreationException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java
new file mode 100644
index 0000000..852eca1
--- /dev/null
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/exception/AuthorizerDestructionException.java
@@ -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.
+ */
+package org.apache.nifi.authorization.exception;
+
+/**
+ * Represents the exceptional case when an Authorizer fails destruction.
+ *
+ */
+public class AuthorizerDestructionException extends RuntimeException {
+
+    public AuthorizerDestructionException() {
+    }
+
+    public AuthorizerDestructionException(String msg) {
+        super(msg);
+    }
+
+    public AuthorizerDestructionException(Throwable cause) {
+        super(cause);
+    }
+
+    public AuthorizerDestructionException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorityProviderFactoryBean.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorityProviderFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorityProviderFactoryBean.java
index b3e9547..e1a02b8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorityProviderFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorityProviderFactoryBean.java
@@ -16,38 +16,19 @@
  */
 package org.apache.nifi.authorization;
 
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.authorization.annotation.AuthorityProviderContext;
 import org.apache.nifi.authorization.exception.AuthorityAccessException;
 import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException;
 import org.apache.nifi.authorization.exception.ProviderCreationException;
 import org.apache.nifi.authorization.exception.ProviderDestructionException;
 import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.authorization.generated.AuthorityProviderProperty;
 import org.apache.nifi.authorization.generated.AuthorityProviders;
-import org.apache.nifi.authorization.generated.Property;
 import org.apache.nifi.authorization.generated.Provider;
 import org.apache.nifi.nar.ExtensionManager;
 import org.apache.nifi.nar.NarCloseable;
 import org.apache.nifi.util.NiFiProperties;
-import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
@@ -57,6 +38,26 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.xml.sax.SAXException;
 
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * Factory bean for loading the configured authority provider.
  */
@@ -196,7 +197,7 @@ public class AuthorityProviderFactoryBean implements FactoryBean, ApplicationCon
     private AuthorityProviderConfigurationContext loadAuthorityProviderConfiguration(final Provider provider) {
         final Map<String, String> providerProperties = new HashMap<>();
 
-        for (final Property property : provider.getProperty()) {
+        for (final AuthorityProviderProperty property : provider.getProperty()) {
             providerProperties.put(property.getName(), property.getValue());
         }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
new file mode 100644
index 0000000..58caea9
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.generated.AuthorityProviders;
+import org.apache.nifi.authorization.generated.Authorizers;
+import org.apache.nifi.authorization.generated.Property;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.nar.NarCloseable;
+import org.apache.nifi.util.NiFiProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Factory bean for loading the configured authorizer.
+ */
+public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, AuthorizerLookup {
+
+    private static final Logger logger = LoggerFactory.getLogger(AuthorizerFactoryBean.class);
+    private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
+    private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authorization.generated";
+    private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+
+    /**
+     * Load the JAXBContext.
+     */
+    private static JAXBContext initializeJaxbContext() {
+        try {
+            return JAXBContext.newInstance(JAXB_GENERATED_PATH, AuthorizerFactoryBean.class.getClassLoader());
+        } catch (JAXBException e) {
+            throw new RuntimeException("Unable to create JAXBContext.");
+        }
+    }
+
+    private Authorizer authorizer;
+    private NiFiProperties properties;
+    private final Map<String, Authorizer> authorizers = new HashMap<>();
+
+    @Override
+    public Authorizer getAuthorizer(String identifier) {
+        return authorizers.get(identifier);
+    }
+
+    @Override
+    public Object getObject() throws Exception {
+        if (authorizer == null) {
+            // look up the authorizer to use
+            final String authorizerIdentifier = properties.getProperty(NiFiProperties.SECURITY_USER_AUTHORITY_PROVIDER);
+
+            // ensure the authorizer class name was specified
+            if (StringUtils.isBlank(authorizerIdentifier)) {
+                // if configured for ssl, the authorizer must be specified
+                if (properties.getSslPort() != null) {
+                    throw new Exception("When running securely, the authorizer identifier must be specified in the nifi properties file.");
+                }
+
+                // use a default authorizer... only allowable when running not securely
+                authorizer = createDefaultAuthorizer();
+            } else {
+                final Authorizers authorizerConfiguration = loadAuthorizersConfiguration();
+
+                // create each authorizer
+                for (final org.apache.nifi.authorization.generated.Authorizer authorizer : authorizerConfiguration.getAuthorizer()) {
+                    authorizers.put(authorizer.getIdentifier(), createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz()));
+                }
+
+                // configure each authorizer
+                for (final org.apache.nifi.authorization.generated.Authorizer provider : authorizerConfiguration.getAuthorizer()) {
+                    final Authorizer instance = authorizers.get(provider.getIdentifier());
+                    instance.onConfigured(loadAuthorizerConfiguration(provider));
+                }
+
+                // get the authorizer instance
+                authorizer = getAuthorizer(authorizerIdentifier);
+
+                // ensure it was found
+                if (authorizer == null) {
+                    throw new Exception(String.format("The specified authorizer '%s' could not be found.", authorizerIdentifier));
+                }
+            }
+        }
+
+        return authorizer;
+    }
+
+    private Authorizers loadAuthorizersConfiguration() throws Exception {
+        final File authorizersConfigurationFile = properties.getAuthorityProviderConfiguraitonFile();
+
+        // load the authorizers from the specified file
+        if (authorizersConfigurationFile.exists()) {
+            try {
+                // find the schema
+                final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+                final Schema schema = schemaFactory.newSchema(AuthorityProviders.class.getResource(AUTHORIZERS_XSD));
+
+                // attempt to unmarshal
+                final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
+                unmarshaller.setSchema(schema);
+                final JAXBElement<Authorizers> element = unmarshaller.unmarshal(new StreamSource(authorizersConfigurationFile), Authorizers.class);
+                return element.getValue();
+            } catch (SAXException | JAXBException e) {
+                throw new Exception("Unable to load the authorizer configuration file at: " + authorizersConfigurationFile.getAbsolutePath());
+            }
+        } else {
+            throw new Exception("Unable to find the authorizer configuration file at " + authorizersConfigurationFile.getAbsolutePath());
+        }
+    }
+
+    private Authorizer createAuthorizer(final String identifier, final String authorizerClassName) throws Exception {
+        // get the classloader for the specified authorizer
+        final ClassLoader authorizerClassLoader = ExtensionManager.getClassLoader(authorizerClassName);
+        if (authorizerClassLoader == null) {
+            throw new Exception(String.format("The specified authorizer class '%s' is not known to this nifi.", authorizerClassName));
+        }
+
+        // get the current context classloader
+        final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+
+        final Authorizer instance;
+        try {
+            // set the appropriate class loader
+            Thread.currentThread().setContextClassLoader(authorizerClassLoader);
+
+            // attempt to load the class
+            Class<?> rawAuthorizerClass = Class.forName(authorizerClassName, true, authorizerClassLoader);
+            Class<? extends Authorizer> authorizerClass = rawAuthorizerClass.asSubclass(Authorizer.class);
+
+            // otherwise create a new instance
+            Constructor constructor = authorizerClass.getConstructor();
+            instance = (Authorizer) constructor.newInstance();
+
+            // method injection
+            performMethodInjection(instance, authorizerClass);
+
+            // field injection
+            performFieldInjection(instance, authorizerClass);
+
+            // call post construction lifecycle event
+            instance.initialize(new StandardAuthorizerInitializationContext(identifier, this));
+        } finally {
+            if (currentClassLoader != null) {
+                Thread.currentThread().setContextClassLoader(currentClassLoader);
+            }
+        }
+
+        return withNarLoader(instance);
+    }
+
+    private AuthorizerConfigurationContext loadAuthorizerConfiguration(final org.apache.nifi.authorization.generated.Authorizer authorizer) {
+        final Map<String, String> authorizerProperties = new HashMap<>();
+
+        for (final Property property : authorizer.getProperty()) {
+            authorizerProperties.put(property.getName(), property.getValue());
+        }
+
+        return new StandardAuthorizerConfigurationContext(authorizer.getIdentifier(), authorizerProperties);
+    }
+
+    private void performMethodInjection(final Authorizer instance, final Class authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+        for (final Method method : authorizerClass.getMethods()) {
+            if (method.isAnnotationPresent(AuthorizerContext.class)) {
+                // make the method accessible
+                final boolean isAccessible = method.isAccessible();
+                method.setAccessible(true);
+
+                try {
+                    final Class<?>[] argumentTypes = method.getParameterTypes();
+
+                    // look for setters (single argument)
+                    if (argumentTypes.length == 1) {
+                        final Class<?> argumentType = argumentTypes[0];
+
+                        // look for well known types
+                        if (NiFiProperties.class.isAssignableFrom(argumentType)) {
+                            // nifi properties injection
+                            method.invoke(instance, properties);
+                        }
+                    }
+                } finally {
+                    method.setAccessible(isAccessible);
+                }
+            }
+        }
+
+        final Class parentClass = authorizerClass.getSuperclass();
+        if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
+            performMethodInjection(instance, parentClass);
+        }
+    }
+
+    private void performFieldInjection(final Authorizer instance, final Class authorizerClass) throws IllegalArgumentException, IllegalAccessException {
+        for (final Field field : authorizerClass.getDeclaredFields()) {
+            if (field.isAnnotationPresent(AuthorizerContext.class)) {
+                // make the method accessible
+                final boolean isAccessible = field.isAccessible();
+                field.setAccessible(true);
+
+                try {
+                    // get the type
+                    final Class<?> fieldType = field.getType();
+
+                    // only consider this field if it isn't set yet
+                    if (field.get(instance) == null) {
+                        // look for well known types
+                        if (NiFiProperties.class.isAssignableFrom(fieldType)) {
+                            // nifi properties injection
+                            field.set(instance, properties);
+                        }
+                    }
+
+                } finally {
+                    field.setAccessible(isAccessible);
+                }
+            }
+        }
+
+        final Class parentClass = authorizerClass.getSuperclass();
+        if (parentClass != null && AuthorityProvider.class.isAssignableFrom(parentClass)) {
+            performFieldInjection(instance, parentClass);
+        }
+    }
+
+    /**
+     * @return a default Authorizer to use when running unsecurely with no authorizer configured
+     */
+    private Authorizer createDefaultAuthorizer() {
+        return new Authorizer() {
+            @Override
+            public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
+                return AuthorizationResult.approved();
+            }
+
+            @Override
+            public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
+            }
+
+            @Override
+            public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+            }
+
+            @Override
+            public void preDestruction() throws AuthorizerDestructionException {
+            }
+        };
+    }
+
+    /**
+     * Decorates the base authorizer to ensure the nar context classloader is used when invoking the underlying methods.
+     *
+     * @param baseAuthorizer base authorizer
+     * @return authorizer
+     */
+    public Authorizer withNarLoader(final Authorizer baseAuthorizer) {
+        return new Authorizer() {
+            @Override
+            public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
+                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                    return baseAuthorizer.authorize(request);
+                }
+            }
+
+            @Override
+            public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
+                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                    baseAuthorizer.initialize(initializationContext);
+                }
+            }
+
+            @Override
+            public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                    baseAuthorizer.onConfigured(configurationContext);
+                }
+            }
+
+            @Override
+            public void preDestruction() throws AuthorizerDestructionException {
+                try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
+                    baseAuthorizer.preDestruction();
+                }
+            }
+        };
+    }
+
+    @Override
+    public Class getObjectType() {
+        return Authorizer.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        if (authorizer != null) {
+            authorizer.preDestruction();
+        }
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorityProviderConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorityProviderConfigurationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorityProviderConfigurationContext.java
index 0535e27..45b84c8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorityProviderConfigurationContext.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorityProviderConfigurationContext.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.authorization;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -29,7 +30,7 @@ public class StandardAuthorityProviderConfigurationContext implements AuthorityP
 
     public StandardAuthorityProviderConfigurationContext(String identifier, Map<String, String> properties) {
         this.identifier = identifier;
-        this.properties = properties;
+        this.properties = Collections.unmodifiableMap(new HashMap<String, String>(properties));
     }
 
     @Override
@@ -39,7 +40,7 @@ public class StandardAuthorityProviderConfigurationContext implements AuthorityP
 
     @Override
     public Map<String, String> getProperties() {
-        return Collections.unmodifiableMap(properties);
+        return properties;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
new file mode 100644
index 0000000..946da96
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class StandardAuthorizerConfigurationContext implements AuthorizerConfigurationContext {
+
+    private final String identifier;
+    private final Map<String, String> properties;
+
+    public StandardAuthorizerConfigurationContext(String identifier, Map<String, String> properties) {
+        this.identifier = identifier;
+        this.properties = Collections.unmodifiableMap(new HashMap<String, String>(properties));
+    }
+
+    @Override
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    @Override
+    public String getProperty(String property) {
+        return properties.get(property);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerInitializationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerInitializationContext.java
new file mode 100644
index 0000000..344f49c
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/authorization/StandardAuthorizerInitializationContext.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization;
+
+/**
+ *
+ */
+public class StandardAuthorizerInitializationContext implements AuthorizerInitializationContext {
+
+    private final String identifier;
+    private final AuthorizerLookup authorizerLookup;
+
+    public StandardAuthorizerInitializationContext(String identifier, AuthorizerLookup authorizerLookup) {
+        this.identifier = identifier;
+        this.authorizerLookup = authorizerLookup;
+    }
+
+    @Override
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public AuthorizerLookup getAuthorizerLookup() {
+        return authorizerLookup;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/resources/nifi-administration-context.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/resources/nifi-administration-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/resources/nifi-administration-context.xml
index 1423cbe..3a46314 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/resources/nifi-administration-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/resources/nifi-administration-context.xml
@@ -16,17 +16,18 @@
 <beans default-lazy-init="true"
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
-    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
-    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
 
     <!-- user authority provider -->
     <bean id="authorityProvider" class="org.apache.nifi.authorization.AuthorityProviderFactoryBean" depends-on="clusterManager">
         <property name="properties" ref="nifiProperties"/>
     </bean>
 
+    <!-- user/entity authorizer -->
+    <bean id="authorizer" class="org.apache.nifi.authorization.AuthorizerFactoryBean" depends-on="clusterManager">
+        <property name="properties" ref="nifiProperties"/>
+    </bean>
+
     <!-- initialize the user data source -->
     <bean id="userDataSource" class="org.apache.nifi.admin.UserDataSourceFactoryBean" destroy-method="shutdown">
         <property name="properties" ref="nifiProperties"/>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authority-providers.xsd
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authority-providers.xsd b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authority-providers.xsd
index 122fa2c..1a5fe50 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authority-providers.xsd
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authority-providers.xsd
@@ -17,22 +17,22 @@
     <!-- role -->
     <xs:complexType name="Provider">
         <xs:sequence>
-            <xs:element name="identifier" type="NonEmptyStringType"/>
-            <xs:element name="class" type="NonEmptyStringType"/>
-            <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+            <xs:element name="identifier" type="AuthorityProviderNonEmptyStringType"/>
+            <xs:element name="class" type="AuthorityProviderNonEmptyStringType"/>
+            <xs:element name="property" type="AuthorityProviderProperty" minOccurs="0" maxOccurs="unbounded" />
         </xs:sequence>
     </xs:complexType>
 
     <!-- Name/Value properties-->
-    <xs:complexType name="Property">
+    <xs:complexType name="AuthorityProviderProperty">
         <xs:simpleContent>
             <xs:extension base="xs:string">
-                <xs:attribute name="name" type="NonEmptyStringType"></xs:attribute>
+                <xs:attribute name="name" type="AuthorityProviderNonEmptyStringType"></xs:attribute>
             </xs:extension>
         </xs:simpleContent>
     </xs:complexType>
 
-    <xs:simpleType name="NonEmptyStringType">
+    <xs:simpleType name="AuthorityProviderNonEmptyStringType">
         <xs:restriction base="xs:string">
             <xs:minLength value="1"/>
         </xs:restriction>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authorizers.xsd
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authorizers.xsd b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authorizers.xsd
new file mode 100644
index 0000000..4b68b00
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/xsd/authorizers.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <!-- role -->
+    <xs:complexType name="Authorizer">
+        <xs:sequence>
+            <xs:element name="identifier" type="NonEmptyStringType"/>
+            <xs:element name="class" type="NonEmptyStringType"/>
+            <xs:element name="property" type="Property" minOccurs="0" maxOccurs="unbounded" />
+        </xs:sequence>
+    </xs:complexType>
+
+    <!-- Name/Value properties-->
+    <xs:complexType name="Property">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute name="name" type="NonEmptyStringType"></xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:simpleType name="NonEmptyStringType">
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <!-- users -->
+    <xs:element name="authorizers">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="authorizer" type="Authorizer" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/pom.xml
new file mode 100644
index 0000000..8532ec5
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<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</groupId>
+        <artifactId>nifi-framework</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-framework-authorization</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
new file mode 100644
index 0000000..a641810
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.authorization.resource;
+
+import org.apache.nifi.authorization.Resource;
+
+import java.util.Objects;
+
+public final class ResourceFactory {
+
+    private final static Resource FLOW_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/flow";
+        }
+
+        @Override
+        public String getName() {
+            return "NiFi Flow";
+        }
+    };
+
+    private final static Resource RESOURCE_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/resources";
+        }
+
+        @Override
+        public String getName() {
+            return "NiFi Resources";
+        }
+    };
+
+    private final static Resource SYSTEM_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/system";
+        }
+
+        @Override
+        public String getName() {
+            return "System";
+        }
+    };
+
+    private final static Resource CONTROLLER_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/controller";
+        }
+
+        @Override
+        public String getName() {
+            return "Controller";
+        }
+    };
+
+    private final static Resource PROVENANCE_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/provenance";
+        }
+
+        @Override
+        public String getName() {
+            return "Provenance";
+        }
+    };
+
+    private final static Resource TOKEN_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/token";
+        }
+
+        @Override
+        public String getName() {
+            return "API access token";
+        }
+    };
+
+    private final static Resource SITE_TO_SITE_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/site-to-site";
+        }
+
+        @Override
+        public String getName() {
+            return "Site to Site";
+        }
+    };
+
+    private final static Resource PROXY_RESOURCE = new Resource() {
+        @Override
+        public String getIdentifier() {
+            return "/proxy";
+        }
+
+        @Override
+        public String getName() {
+            return "Proxy User Requests";
+        }
+    };
+
+    /**
+     * Gets the Resource for accessing the NiFi flow. This includes the data flow structure, component status, search results, and banner/about text.
+     *
+     * @return  The NiFi resource
+     */
+    public static Resource getFlowResource() {
+        return FLOW_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for detailing all available NiFi Resources.
+     *
+     * @return  The Resource resource
+     */
+    public static Resource getResourceResource() {
+        return RESOURCE_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for accessing details of the System NiFi is running on.
+     *
+     * @return  The System resource
+     */
+    public static Resource getSystemResource() {
+        return SYSTEM_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for accessing the Controller. This includes Controller level configuration, bulletins, reporting tasks, and the cluster.
+     *
+     * @return  The resource for accessing the Controller
+     */
+    public static Resource getControllerResource() {
+        return CONTROLLER_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for accessing provenance. Access to this Resource allows the user to access data provenance. However, additional authorization
+     * is required based on the component that generated the event and the attributes of the event.
+     *
+     * @return  The provenance resource
+     */
+    public static Resource getProvenanceResource() {
+        return PROVENANCE_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for creating API access tokens.
+     *
+     * @return  The token request resource
+     */
+    public static Resource getTokenResource() {
+        return TOKEN_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for obtaining site to site details. This will allow other NiFi instances to obtain necessary configuration to initiate a
+     * site to site data transfer.
+     *
+     * @return  The resource for obtaining site to site details
+     */
+    public static Resource getSiteToSiteResource() {
+        return SITE_TO_SITE_RESOURCE;
+    }
+
+    /**
+     * Gets the Resource for proxying a user request.
+     *
+     * @return  The resource for proxying a user request
+     */
+    public static Resource getProxyResource() {
+        return PROXY_RESOURCE;
+    }
+
+    /**
+     * Gets a Resource for accessing a component configuration.
+     *
+     * @param resourceType  The type of resource being accessed
+     * @param identifier    The identifier of the component being accessed
+     * @param name          The name of the component being accessed
+     * @return              The resource
+     */
+    public static Resource getComponentResource(final ResourceType resourceType, final String identifier, final String name) {
+        Objects.requireNonNull(resourceType, "The resource must be specified.");
+        Objects.requireNonNull(identifier, "The component identifier must be specified.");
+        Objects.requireNonNull(name, "The component name must be specified.");
+
+        return new Resource() {
+            @Override
+            public String getIdentifier() {
+                return String.format("%s/%s", resourceType.getValue(), identifier);
+            }
+
+            @Override
+            public String getName() {
+                return name;
+            }
+        };
+    }
+
+    /**
+     * Gets a Resource for accessing a component's provenance events.
+     *
+     * @param resourceType  The type of resource being accessed
+     * @param identifier    The identifier of the component being accessed
+     * @param name          The name of the component being accessed
+     * @return              The resource
+     */
+    public static Resource getComponentProvenanceResource(final ResourceType resourceType, final String identifier, final String name) {
+        final Resource componentResource = getComponentResource(resourceType, identifier, name);
+        return new Resource() {
+            @Override
+            public String getIdentifier() {
+                return String.format("%s/%s", componentResource.getIdentifier(), "provenance");
+            }
+
+            @Override
+            public String getName() {
+                return componentResource.getName() + " provenance";
+            }
+        };
+    }
+
+    /**
+     * Gets a Resource fo accessing a flowfile queue for the specified connection.
+     *
+     * @param connectionIdentifier  The identifier of the connection
+     * @param connectionName        The name of the connection
+     * @return                      The resource
+     */
+    public static Resource getFlowFileQueueResource(final String connectionIdentifier, final String connectionName) {
+        Objects.requireNonNull(connectionIdentifier, "The connection identifier must be specified.");
+        Objects.requireNonNull(connectionName, "The connection name must be specified.");
+
+        return new Resource() {
+            @Override
+            public String getIdentifier() {
+                return String.format("/flowfile-queue/%s", connectionIdentifier);
+            }
+
+            @Override
+            public String getName() {
+                return connectionName + " queue";
+            }
+        };
+    }
+
+    /**
+     * Prevent outside instantiation.
+     */
+    private ResourceFactory() {}
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
new file mode 100644
index 0000000..5e122ec
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
@@ -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.
+ */
+package org.apache.nifi.authorization.resource;
+
+public enum ResourceType {
+    Processor("/processors"),
+    InputPort("/input-ports"),
+    OutputPort("/output-ports"),
+    Connection("/connections"),
+    ProcessGroup("/process-groups"),
+    RemoteProcessGroup("/remote-process-groups"),
+    Label("/labels"),
+    ControllerService("/controller-services"),
+    Template("/templates");
+
+    final String value;
+
+    private ResourceType(final String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/9aa69b24/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
index e04d04d..7faf517 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/pom.xml
@@ -36,6 +36,7 @@
         <module>nifi-file-authorization-provider</module>
         <module>nifi-cluster-authorization-provider</module>
         <module>nifi-user-actions</module>
+        <module>nifi-framework-authorization</module>
         <module>nifi-administration</module>
         <module>nifi-web</module>
         <module>nifi-resources</module>


[08/18] nifi git commit: NIFI-1563: - Federate requests and merge responses from nodes instead of storing bulletins and stats at NCM - Updating UI to support restructured status history DTO. - Return 'Insufficient History' message if aggregate stats don'

Posted by mc...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 945c671..b981bde 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -27,11 +27,8 @@ import org.apache.nifi.admin.service.AccountNotFoundException;
 import org.apache.nifi.admin.service.AuditService;
 import org.apache.nifi.admin.service.UserService;
 import org.apache.nifi.authorization.Authority;
-import org.apache.nifi.cluster.HeartbeatPayload;
 import org.apache.nifi.cluster.context.ClusterContext;
 import org.apache.nifi.cluster.context.ClusterContextThreadLocal;
-import org.apache.nifi.cluster.manager.exception.IllegalClusterStateException;
-import org.apache.nifi.cluster.manager.exception.NoConnectedNodesException;
 import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
 import org.apache.nifi.cluster.node.Node;
@@ -55,11 +52,6 @@ import org.apache.nifi.controller.repository.claim.ContentDirection;
 import org.apache.nifi.controller.service.ControllerServiceNode;
 import org.apache.nifi.controller.service.ControllerServiceReference;
 import org.apache.nifi.controller.service.ControllerServiceState;
-import org.apache.nifi.controller.status.ConnectionStatus;
-import org.apache.nifi.controller.status.PortStatus;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.controller.status.ProcessorStatus;
-import org.apache.nifi.controller.status.RemoteProcessGroupStatus;
 import org.apache.nifi.diagnostics.SystemDiagnostics;
 import org.apache.nifi.groups.ProcessGroup;
 import org.apache.nifi.groups.ProcessGroupCounts;
@@ -72,7 +64,6 @@ import org.apache.nifi.remote.RootGroupPort;
 import org.apache.nifi.reporting.Bulletin;
 import org.apache.nifi.reporting.BulletinQuery;
 import org.apache.nifi.reporting.BulletinRepository;
-import org.apache.nifi.reporting.ComponentType;
 import org.apache.nifi.user.AccountStatus;
 import org.apache.nifi.user.NiFiUser;
 import org.apache.nifi.user.NiFiUserGroup;
@@ -91,6 +82,7 @@ import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
 import org.apache.nifi.web.api.dto.CounterDTO;
 import org.apache.nifi.web.api.dto.CountersDTO;
+import org.apache.nifi.web.api.dto.CountersSnapshotDTO;
 import org.apache.nifi.web.api.dto.DocumentedTypeDTO;
 import org.apache.nifi.web.api.dto.DropRequestDTO;
 import org.apache.nifi.web.api.dto.DtoFactory;
@@ -100,7 +92,6 @@ import org.apache.nifi.web.api.dto.FunnelDTO;
 import org.apache.nifi.web.api.dto.LabelDTO;
 import org.apache.nifi.web.api.dto.ListingRequestDTO;
 import org.apache.nifi.web.api.dto.NodeDTO;
-import org.apache.nifi.web.api.dto.NodeSystemDiagnosticsDTO;
 import org.apache.nifi.web.api.dto.PortDTO;
 import org.apache.nifi.web.api.dto.PreviousValueDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
@@ -125,21 +116,12 @@ import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO;
 import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO;
 import org.apache.nifi.web.api.dto.search.SearchResultsDTO;
-import org.apache.nifi.web.api.dto.status.ClusterConnectionStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterPortStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterProcessorStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterRemoteProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusDTO;
-import org.apache.nifi.web.api.dto.status.ClusterStatusHistoryDTO;
+import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
 import org.apache.nifi.web.api.dto.status.ControllerStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodeConnectionStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodePortStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodeProcessorStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodeRemoteProcessGroupStatusDTO;
-import org.apache.nifi.web.api.dto.status.NodeStatusDTO;
+import org.apache.nifi.web.api.dto.status.PortStatusDTO;
 import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.controller.ControllerFacade;
 import org.apache.nifi.web.dao.ConnectionDAO;
@@ -393,7 +375,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ConnectionDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -424,7 +406,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ProcessorDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -455,7 +437,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<LabelDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -486,7 +468,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<FunnelDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -532,7 +514,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<SnippetDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -562,7 +544,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<PortDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -592,7 +574,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<PortDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -622,7 +604,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<RemoteProcessGroupDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -649,7 +631,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<RemoteProcessGroupPortDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -676,7 +658,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<RemoteProcessGroupPortDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -711,7 +693,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save updated controller
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ProcessGroupDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -751,7 +733,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ControllerConfigurationDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -808,14 +790,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // clear the state for the specified component
                 processorDAO.clearState(groupId, processorId);
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -836,14 +818,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // clear the state for the specified component
                 controllerServiceDAO.clearState(controllerServiceId);
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -864,14 +846,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // clear the state for the specified component
                 reportingTaskDAO.clearState(reportingTaskId);
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -889,14 +871,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -936,14 +918,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -962,14 +944,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -988,14 +970,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1025,14 +1007,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1050,14 +1032,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1075,14 +1057,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1100,14 +1082,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1125,14 +1107,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1161,7 +1143,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ConnectionDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1213,7 +1195,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ProcessorDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1244,7 +1226,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<LabelDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1275,7 +1257,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<FunnelDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1366,7 +1348,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<FlowSnippetDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -1396,7 +1378,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 final SnippetDTO responseSnippetDTO = dtoFactory.createSnippetDto(snippet);
                 responseSnippetDTO.setContents(snippetUtils.populateFlowSnippet(snippet, false, false));
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<SnippetDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1426,7 +1408,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<PortDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1456,7 +1438,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<PortDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1486,7 +1468,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ProcessGroupDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1516,7 +1498,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<RemoteProcessGroupDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1588,7 +1570,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<FlowSnippetDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -1611,14 +1593,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // create the archive
                 controllerFacade.createArchive();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1654,7 +1636,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 // save the flow
                 controllerFacade.save();
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ProcessorDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -1689,7 +1671,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ControllerServiceDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1723,7 +1705,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ControllerServiceDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -1750,7 +1732,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
             public ConfigurationResult<Set<ControllerServiceReferencingComponentDTO>> execute() {
                 final ControllerServiceReference reference = controllerServiceDAO.updateControllerServiceReferencingComponents(controllerServiceId, scheduledState, controllerServiceState);
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Set<ControllerServiceReferencingComponentDTO>>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -1780,14 +1762,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -1815,7 +1797,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ReportingTaskDTO>() {
                     @Override
                     public boolean isNew() {
                         return true;
@@ -1849,7 +1831,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<ReportingTaskDTO>() {
                     @Override
                     public boolean isNew() {
                         return false;
@@ -1879,14 +1861,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                     controllerFacade.save();
                 }
 
-                return new ConfigurationResult() {
+                return new ConfigurationResult<Void>() {
                     @Override
                     public boolean isNew() {
                         return false;
                     }
 
                     @Override
-                    public ControllerConfigurationDTO getConfiguration() {
+                    public Void getConfiguration() {
                         return null;
                     }
                 };
@@ -2105,78 +2087,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     @Override
     public ProcessGroupStatusDTO getProcessGroupStatus(String groupId) {
-        ProcessGroupStatusDTO statusReport;
-        if (properties.isClusterManager()) {
-            final ProcessGroupStatus mergedProcessGroupStatus = clusterManager.getProcessGroupStatus(groupId);
-            if (mergedProcessGroupStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for process group %s.", groupId));
-            }
-            statusReport = dtoFactory.createProcessGroupStatusDto(clusterManager.getBulletinRepository(), mergedProcessGroupStatus);
-        } else {
-            statusReport = controllerFacade.getProcessGroupStatus(groupId);
-        }
-        return statusReport;
+        return controllerFacade.getProcessGroupStatus(groupId);
     }
 
     @Override
     public ControllerStatusDTO getControllerStatus() {
-        final ControllerStatusDTO controllerStatus;
-
-        if (properties.isClusterManager()) {
-            final Set<Node> connectedNodes = clusterManager.getNodes(Node.Status.CONNECTED);
-
-            if (connectedNodes.isEmpty()) {
-                throw new NoConnectedNodesException();
-            }
-
-            int activeThreadCount = 0;
-            long totalFlowFileObjectCount = 0;
-            long totalFlowFileByteCount = 0;
-            for (final Node node : connectedNodes) {
-                final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-                if (nodeHeartbeatPayload == null) {
-                    continue;
-                }
-
-                activeThreadCount += nodeHeartbeatPayload.getActiveThreadCount();
-                totalFlowFileObjectCount += nodeHeartbeatPayload.getTotalFlowFileCount();
-                totalFlowFileByteCount += nodeHeartbeatPayload.getTotalFlowFileBytes();
-            }
-
-            controllerStatus = new ControllerStatusDTO();
-            controllerStatus.setActiveThreadCount(activeThreadCount);
-            controllerStatus.setQueued(FormatUtils.formatCount(totalFlowFileObjectCount) + " / " + FormatUtils.formatDataSize(totalFlowFileByteCount));
-
-            final int numNodes = clusterManager.getNodeIds().size();
-            controllerStatus.setConnectedNodes(connectedNodes.size() + " / " + numNodes);
-
-            // get the bulletins for the controller
-            final BulletinRepository bulletinRepository = clusterManager.getBulletinRepository();
-            controllerStatus.setBulletins(dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForController()));
-
-            // get the controller service bulletins
-            final BulletinQuery controllerServiceQuery = new BulletinQuery.Builder().sourceType(ComponentType.CONTROLLER_SERVICE).build();
-            controllerStatus.setControllerServiceBulletins(dtoFactory.createBulletinDtos(bulletinRepository.findBulletins(controllerServiceQuery)));
-
-            // get the reporting task bulletins
-            final BulletinQuery reportingTaskQuery = new BulletinQuery.Builder().sourceType(ComponentType.REPORTING_TASK).build();
-            controllerStatus.setReportingTaskBulletins(dtoFactory.createBulletinDtos(bulletinRepository.findBulletins(reportingTaskQuery)));
-
-            // get the component counts by extracting them from the roots' group status
-            final ProcessGroupStatus status = clusterManager.getProcessGroupStatus("root");
-            if (status != null) {
-                final ProcessGroupCounts counts = extractProcessGroupCounts(status);
-                controllerStatus.setRunningCount(counts.getRunningCount());
-                controllerStatus.setStoppedCount(counts.getStoppedCount());
-                controllerStatus.setInvalidCount(counts.getInvalidCount());
-                controllerStatus.setDisabledCount(counts.getDisabledCount());
-                controllerStatus.setActiveRemotePortCount(counts.getActiveRemotePortCount());
-                controllerStatus.setInactiveRemotePortCount(counts.getInactiveRemotePortCount());
-            }
-        } else {
-            // get the controller status
-            controllerStatus = controllerFacade.getControllerStatus();
-        }
+        // get the controller status
+        final ControllerStatusDTO controllerStatus = controllerFacade.getControllerStatus();
 
         // determine if there are any pending user accounts - only include if appropriate
         if (NiFiUserUtils.getAuthorities().contains(Authority.ROLE_ADMIN.toString())) {
@@ -2218,53 +2135,17 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     @Override
     public CountersDTO getCounters() {
-        if (properties.isClusterManager()) {
-            final Map<String, CounterDTO> mergedCountersMap = new HashMap<>();
-            final Set<Node> connectedNodes = clusterManager.getNodes(Node.Status.CONNECTED);
-
-            if (connectedNodes.isEmpty()) {
-                throw new NoConnectedNodesException();
-            }
-
-            for (final Node node : connectedNodes) {
-                final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-                if (nodeHeartbeatPayload == null) {
-                    continue;
-                }
-                final List<Counter> nodeCounters = node.getHeartbeatPayload().getCounters();
-                if (nodeCounters == null) {
-                    continue;
-                }
-
-                // for each node, add its counter values to the aggregate values
-                for (final Counter nodeCounter : nodeCounters) {
-                    final CounterDTO mergedCounter = mergedCountersMap.get(nodeCounter.getIdentifier());
-
-                    // either create a new aggregate counter or update the aggregate counter
-                    if (mergedCounter == null) {
-                        // add new counter
-                        mergedCountersMap.put(nodeCounter.getIdentifier(), dtoFactory.createCounterDto(nodeCounter));
-                    } else {
-                        // update aggregate counter
-                        mergedCounter.setValueCount(mergedCounter.getValueCount() + nodeCounter.getValue());
-                        mergedCounter.setValue(FormatUtils.formatCount(mergedCounter.getValueCount()));
-                    }
-                }
-            }
-
-            final CountersDTO mergedCounters = new CountersDTO();
-            mergedCounters.setGenerated(new Date());
-            mergedCounters.setCounters(mergedCountersMap.values());
-            return mergedCounters;
-        } else {
-            List<Counter> counters = controllerFacade.getCounters();
-            Set<CounterDTO> counterDTOs = new LinkedHashSet<>(counters.size());
-            for (Counter counter : counters) {
-                counterDTOs.add(dtoFactory.createCounterDto(counter));
-            }
-            return dtoFactory.createCountersDto(counterDTOs);
+        List<Counter> counters = controllerFacade.getCounters();
+        Set<CounterDTO> counterDTOs = new LinkedHashSet<>(counters.size());
+        for (Counter counter : counters) {
+            counterDTOs.add(dtoFactory.createCounterDto(counter));
         }
 
+        final CountersSnapshotDTO snapshotDto = dtoFactory.createCountersDto(counterDTOs);
+        final CountersDTO countersDto = new CountersDTO();
+        countersDto.setAggregateSnapshot(snapshotDto);
+
+        return countersDto;
     }
 
     @Override
@@ -2308,6 +2189,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     @Override
+    public ConnectionStatusDTO getConnectionStatus(String groupId, String connectionId) {
+        return controllerFacade.getConnectionStatus(groupId, connectionId);
+    }
+
+    @Override
     public StatusHistoryDTO getConnectionStatusHistory(String groupId, String connectionId) {
         return controllerFacade.getConnectionStatusHistory(groupId, connectionId);
     }
@@ -2386,6 +2272,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     @Override
+    public ProcessorStatusDTO getProcessorStatus(String groupId, String id) {
+        return controllerFacade.getProcessorStatus(groupId, id);
+    }
+
+    @Override
     public StatusHistoryDTO getProcessorStatusHistory(String groupId, String id) {
         return controllerFacade.getProcessorStatusHistory(groupId, id);
     }
@@ -2429,18 +2320,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     @Override
     public SystemDiagnosticsDTO getSystemDiagnostics() {
-        final SystemDiagnosticsDTO dto;
-        if (properties.isClusterManager()) {
-            final SystemDiagnostics clusterDiagnostics = clusterManager.getSystemDiagnostics();
-            if (clusterDiagnostics == null) {
-                throw new IllegalStateException("Nodes are connected but no systems diagnostics have been reported.");
-            }
-            dto = dtoFactory.createSystemDiagnosticsDto(clusterDiagnostics);
-        } else {
-            final SystemDiagnostics sysDiagnostics = controllerFacade.getSystemDiagnostics();
-            dto = dtoFactory.createSystemDiagnosticsDto(sysDiagnostics);
-        }
-        return dto;
+        final SystemDiagnostics sysDiagnostics = controllerFacade.getSystemDiagnostics();
+        return dtoFactory.createSystemDiagnosticsDto(sysDiagnostics);
     }
 
     /**
@@ -2651,16 +2532,31 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     @Override
+    public PortStatusDTO getInputPortStatus(String groupId, String inputPortId) {
+        return controllerFacade.getInputPortStatus(groupId, inputPortId);
+    }
+
+    @Override
     public PortDTO getOutputPort(String groupId, String outputPortId) {
         return dtoFactory.createPortDto(outputPortDAO.getPort(groupId, outputPortId));
     }
 
     @Override
+    public PortStatusDTO getOutputPortStatus(String groupId, String outputPortId) {
+        return controllerFacade.getOutputPortStatus(groupId, outputPortId);
+    }
+
+    @Override
     public RemoteProcessGroupDTO getRemoteProcessGroup(String groupId, String remoteProcessGroupId) {
         return dtoFactory.createRemoteProcessGroupDto(remoteProcessGroupDAO.getRemoteProcessGroup(groupId, remoteProcessGroupId));
     }
 
     @Override
+    public RemoteProcessGroupStatusDTO getRemoteProcessGroupStatus(String groupId, String id) {
+        return controllerFacade.getRemoteProcessGroupStatus(groupId, id);
+    }
+
+    @Override
     public StatusHistoryDTO getRemoteProcessGroupStatusHistory(String groupId, String id) {
         return controllerFacade.getRemoteProcessGroupStatusHistory(groupId, id);
     }
@@ -2934,575 +2830,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         clusterManager.deleteNode(nodeId, userDn);
     }
 
-    private ProcessorStatus findNodeProcessorStatus(final ProcessGroupStatus groupStatus, final String processorId) {
-        ProcessorStatus processorStatus = null;
-
-        for (final ProcessorStatus status : groupStatus.getProcessorStatus()) {
-            if (processorId.equals(status.getId())) {
-                processorStatus = status;
-                break;
-            }
-        }
-
-        if (processorStatus == null) {
-            for (final ProcessGroupStatus status : groupStatus.getProcessGroupStatus()) {
-                processorStatus = findNodeProcessorStatus(status, processorId);
-
-                if (processorStatus != null) {
-                    break;
-                }
-            }
-        }
-
-        return processorStatus;
-    }
-
-    // TODO Refactor!!!
-    @Override
-    public ClusterProcessorStatusDTO getClusterProcessorStatus(String processorId) {
-
-        final ClusterProcessorStatusDTO clusterProcessorStatusDto = new ClusterProcessorStatusDTO();
-        clusterProcessorStatusDto.setNodeProcessorStatus(new ArrayList<NodeProcessorStatusDTO>());
-
-        // set the current time
-        clusterProcessorStatusDto.setStatsLastRefreshed(new Date());
-
-        final Set<Node> nodes = clusterManager.getNodes(Node.Status.CONNECTED);
-        boolean firstNode = true;
-        for (final Node node : nodes) {
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeStats = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeStats == null || nodeStats.getProcessorStatus() == null) {
-                continue;
-            }
-
-            // attempt to find the processor stats for this node
-            final ProcessorStatus processorStatus = findNodeProcessorStatus(nodeStats, processorId);
-
-            // sanity check that we have status for this processor
-            if (processorStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for processor id '%s'.", processorId));
-            }
-
-            if (firstNode) {
-                clusterProcessorStatusDto.setProcessorId(processorId);
-                clusterProcessorStatusDto.setProcessorName(processorStatus.getName());
-                clusterProcessorStatusDto.setProcessorType(processorStatus.getType());
-                clusterProcessorStatusDto.setProcessorRunStatus(processorStatus.getRunStatus().toString());
-                firstNode = false;
-            }
-
-            // create node processor status dto
-            final NodeProcessorStatusDTO nodeProcessorStatusDTO = new NodeProcessorStatusDTO();
-            clusterProcessorStatusDto.getNodeProcessorStatus().add(nodeProcessorStatusDTO);
-
-            // populate node processor status dto
-            final String nodeId = node.getNodeId().getId();
-            nodeProcessorStatusDTO.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-            nodeProcessorStatusDTO.setProcessorStatus(dtoFactory.createProcessorStatusDto(processorStatus));
-
-        }
-
-        return clusterProcessorStatusDto;
-    }
-
-    private ConnectionStatus findNodeConnectionStatus(final ProcessGroupStatus groupStatus, final String connectionId) {
-        ConnectionStatus connectionStatus = null;
-
-        for (final ConnectionStatus status : groupStatus.getConnectionStatus()) {
-            if (connectionId.equals(status.getId())) {
-                connectionStatus = status;
-                break;
-            }
-        }
-
-        if (connectionStatus == null) {
-            for (final ProcessGroupStatus status : groupStatus.getProcessGroupStatus()) {
-                connectionStatus = findNodeConnectionStatus(status, connectionId);
-
-                if (connectionStatus != null) {
-                    break;
-                }
-            }
-        }
-
-        return connectionStatus;
-    }
-
-    @Override
-    public ClusterConnectionStatusDTO getClusterConnectionStatus(String connectionId) {
-        final ClusterConnectionStatusDTO clusterConnectionStatusDto = new ClusterConnectionStatusDTO();
-        clusterConnectionStatusDto.setNodeConnectionStatus(new ArrayList<NodeConnectionStatusDTO>());
-
-        // set the current time
-        clusterConnectionStatusDto.setStatsLastRefreshed(new Date());
-
-        final Set<Node> nodes = clusterManager.getNodes(Node.Status.CONNECTED);
-        boolean firstNode = true;
-        for (final Node node : nodes) {
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeStats = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeStats == null || nodeStats.getProcessorStatus() == null) {
-                continue;
-            }
-
-            // find the connection status for this node
-            final ConnectionStatus connectionStatus = findNodeConnectionStatus(nodeStats, connectionId);
-
-            // sanity check that we have status for this connection
-            if (connectionStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for connection id '%s'.", connectionId));
-            }
-
-            if (firstNode) {
-                clusterConnectionStatusDto.setConnectionId(connectionId);
-                clusterConnectionStatusDto.setConnectionName(connectionStatus.getName());
-                firstNode = false;
-            }
-
-            // create node connection status dto
-            final NodeConnectionStatusDTO nodeConnectionStatusDTO = new NodeConnectionStatusDTO();
-            clusterConnectionStatusDto.getNodeConnectionStatus().add(nodeConnectionStatusDTO);
-
-            // populate node processor status dto
-            final String nodeId = node.getNodeId().getId();
-            nodeConnectionStatusDTO.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-            nodeConnectionStatusDTO.setConnectionStatus(dtoFactory.createConnectionStatusDto(connectionStatus));
-
-        }
-
-        return clusterConnectionStatusDto;
-    }
-
-    private ProcessGroupStatus findNodeProcessGroupStatus(final ProcessGroupStatus groupStatus, final String processGroupId) {
-        ProcessGroupStatus processGroupStatus = null;
-
-        if (processGroupId.equals(groupStatus.getId())) {
-            processGroupStatus = groupStatus;
-        }
-
-        if (processGroupStatus == null) {
-            for (final ProcessGroupStatus status : groupStatus.getProcessGroupStatus()) {
-                processGroupStatus = findNodeProcessGroupStatus(status, processGroupId);
-
-                if (processGroupStatus != null) {
-                    break;
-                }
-            }
-        }
-
-        return processGroupStatus;
-    }
-
-    @Override
-    public ClusterProcessGroupStatusDTO getClusterProcessGroupStatus(String processGroupId) {
-
-        final ClusterProcessGroupStatusDTO clusterProcessGroupStatusDto = new ClusterProcessGroupStatusDTO();
-        clusterProcessGroupStatusDto.setNodeProcessGroupStatus(new ArrayList<NodeProcessGroupStatusDTO>());
-
-        // set the current time
-        clusterProcessGroupStatusDto.setStatsLastRefreshed(new Date());
-
-        final Set<Node> nodes = clusterManager.getNodes(Node.Status.CONNECTED);
-        boolean firstNode = true;
-        for (final Node node : nodes) {
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeStats = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeStats == null || nodeStats.getProcessorStatus() == null) {
-                continue;
-            }
-
-            // attempt to find the process group stats for this node
-            final ProcessGroupStatus processGroupStatus = findNodeProcessGroupStatus(nodeStats, processGroupId);
-
-            // sanity check that we have status for this process group
-            if (processGroupStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for process group id '%s'.", processGroupId));
-            }
-
-            if (firstNode) {
-                clusterProcessGroupStatusDto.setProcessGroupId(processGroupId);
-                clusterProcessGroupStatusDto.setProcessGroupName(processGroupStatus.getName());
-                firstNode = false;
-            }
-
-            // create node process group status dto
-            final NodeProcessGroupStatusDTO nodeProcessGroupStatusDTO = new NodeProcessGroupStatusDTO();
-            clusterProcessGroupStatusDto.getNodeProcessGroupStatus().add(nodeProcessGroupStatusDTO);
-
-            // populate node process group status dto
-            final String nodeId = node.getNodeId().getId();
-            nodeProcessGroupStatusDTO.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-            nodeProcessGroupStatusDTO.setProcessGroupStatus(dtoFactory.createProcessGroupStatusDto(clusterManager.getBulletinRepository(), processGroupStatus));
-
-        }
-
-        return clusterProcessGroupStatusDto;
-    }
-
-    private PortStatus findNodeInputPortStatus(final ProcessGroupStatus groupStatus, final String inputPortId) {
-        PortStatus portStatus = null;
-
-        for (final PortStatus status : groupStatus.getInputPortStatus()) {
-            if (inputPortId.equals(status.getId())) {
-                portStatus = status;
-                break;
-            }
-        }
-
-        if (portStatus == null) {
-            for (final ProcessGroupStatus status : groupStatus.getProcessGroupStatus()) {
-                portStatus = findNodeInputPortStatus(status, inputPortId);
-
-                if (portStatus != null) {
-                    break;
-                }
-            }
-        }
-
-        return portStatus;
-    }
-
-    @Override
-    public ClusterPortStatusDTO getClusterInputPortStatus(String inputPortId) {
-        final ClusterPortStatusDTO clusterInputPortStatusDto = new ClusterPortStatusDTO();
-        clusterInputPortStatusDto.setNodePortStatus(new ArrayList<NodePortStatusDTO>());
-
-        // set the current time
-        clusterInputPortStatusDto.setStatsLastRefreshed(new Date());
-
-        final Set<Node> nodes = clusterManager.getNodes(Node.Status.CONNECTED);
-        boolean firstNode = true;
-        for (final Node node : nodes) {
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeStats = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeStats == null || nodeStats.getProcessorStatus() == null) {
-                continue;
-            }
-
-            // find the input status for this node
-            final PortStatus inputPortStatus = findNodeInputPortStatus(nodeStats, inputPortId);
-
-            // sanity check that we have status for this input port
-            if (inputPortStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for input port id '%s'.", inputPortId));
-            }
-
-            if (firstNode) {
-                clusterInputPortStatusDto.setPortId(inputPortId);
-                clusterInputPortStatusDto.setPortName(inputPortStatus.getName());
-                firstNode = false;
-            }
-
-            // create node port status dto
-            final NodePortStatusDTO nodeInputPortStatusDTO = new NodePortStatusDTO();
-            clusterInputPortStatusDto.getNodePortStatus().add(nodeInputPortStatusDTO);
-
-            // populate node input port status dto
-            final String nodeId = node.getNodeId().getId();
-            nodeInputPortStatusDTO.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-            nodeInputPortStatusDTO.setPortStatus(dtoFactory.createPortStatusDto(inputPortStatus));
-        }
-
-        return clusterInputPortStatusDto;
-    }
-
-    private PortStatus findNodeOutputPortStatus(final ProcessGroupStatus groupStatus, final String outputPortId) {
-        PortStatus portStatus = null;
-
-        for (final PortStatus status : groupStatus.getOutputPortStatus()) {
-            if (outputPortId.equals(status.getId())) {
-                portStatus = status;
-                break;
-            }
-        }
-
-        if (portStatus == null) {
-            for (final ProcessGroupStatus status : groupStatus.getProcessGroupStatus()) {
-                portStatus = findNodeOutputPortStatus(status, outputPortId);
-
-                if (portStatus != null) {
-                    break;
-                }
-            }
-        }
-
-        return portStatus;
-    }
-
-    @Override
-    public ClusterPortStatusDTO getClusterOutputPortStatus(String outputPortId) {
-        final ClusterPortStatusDTO clusterOutputPortStatusDto = new ClusterPortStatusDTO();
-        clusterOutputPortStatusDto.setNodePortStatus(new ArrayList<NodePortStatusDTO>());
-
-        // set the current time
-        clusterOutputPortStatusDto.setStatsLastRefreshed(new Date());
-
-        final Set<Node> nodes = clusterManager.getNodes(Node.Status.CONNECTED);
-        boolean firstNode = true;
-        for (final Node node : nodes) {
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeStats = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeStats == null || nodeStats.getProcessorStatus() == null) {
-                continue;
-            }
-
-            // find the output status for this node
-            final PortStatus outputPortStatus = findNodeOutputPortStatus(nodeStats, outputPortId);
-
-            // sanity check that we have status for this output port
-            if (outputPortStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for output port id '%s'.", outputPortId));
-            }
-
-            if (firstNode) {
-                clusterOutputPortStatusDto.setPortId(outputPortId);
-                clusterOutputPortStatusDto.setPortName(outputPortStatus.getName());
-                firstNode = false;
-            }
-
-            // create node port status dto
-            final NodePortStatusDTO nodeOutputPortStatusDTO = new NodePortStatusDTO();
-            clusterOutputPortStatusDto.getNodePortStatus().add(nodeOutputPortStatusDTO);
-
-            // populate node output port status dto
-            final String nodeId = node.getNodeId().getId();
-            nodeOutputPortStatusDTO.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-            nodeOutputPortStatusDTO.setPortStatus(dtoFactory.createPortStatusDto(outputPortStatus));
-        }
-
-        return clusterOutputPortStatusDto;
-    }
-
-    private RemoteProcessGroupStatus findNodeRemoteProcessGroupStatus(final ProcessGroupStatus groupStatus, final String remoteProcessGroupId) {
-        RemoteProcessGroupStatus remoteProcessGroupStatus = null;
-
-        for (final RemoteProcessGroupStatus status : groupStatus.getRemoteProcessGroupStatus()) {
-            if (remoteProcessGroupId.equals(status.getId())) {
-                remoteProcessGroupStatus = status;
-                break;
-            }
-        }
-
-        if (remoteProcessGroupStatus == null) {
-            for (final ProcessGroupStatus status : groupStatus.getProcessGroupStatus()) {
-                remoteProcessGroupStatus = findNodeRemoteProcessGroupStatus(status, remoteProcessGroupId);
-
-                if (remoteProcessGroupStatus != null) {
-                    break;
-                }
-            }
-        }
-
-        return remoteProcessGroupStatus;
-    }
-
-    @Override
-    public ClusterRemoteProcessGroupStatusDTO getClusterRemoteProcessGroupStatus(String remoteProcessGroupId) {
-        final ClusterRemoteProcessGroupStatusDTO clusterRemoteProcessGroupStatusDto = new ClusterRemoteProcessGroupStatusDTO();
-        clusterRemoteProcessGroupStatusDto.setNodeRemoteProcessGroupStatus(new ArrayList<NodeRemoteProcessGroupStatusDTO>());
-
-        // set the current time
-        clusterRemoteProcessGroupStatusDto.setStatsLastRefreshed(new Date());
-
-        final Set<Node> nodes = clusterManager.getNodes(Node.Status.CONNECTED);
-        boolean firstNode = true;
-        for (final Node node : nodes) {
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeStats = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeStats == null || nodeStats.getProcessorStatus() == null) {
-                continue;
-            }
-
-            // find the remote process group for this node
-            final RemoteProcessGroupStatus remoteProcessGroupStatus = findNodeRemoteProcessGroupStatus(nodeStats, remoteProcessGroupId);
-
-            // sanity check that we have status for this remote process group
-            if (remoteProcessGroupStatus == null) {
-                throw new ResourceNotFoundException(String.format("Unable to find status for remote process group id '%s'.", remoteProcessGroupId));
-            }
-
-            if (firstNode) {
-                clusterRemoteProcessGroupStatusDto.setRemoteProcessGroupId(remoteProcessGroupId);
-                clusterRemoteProcessGroupStatusDto.setRemoteProcessGroupName(remoteProcessGroupStatus.getName());
-                firstNode = false;
-            }
-
-            // create node remote process group status dto
-            final NodeRemoteProcessGroupStatusDTO nodeRemoteProcessGroupStatusDTO = new NodeRemoteProcessGroupStatusDTO();
-            clusterRemoteProcessGroupStatusDto.getNodeRemoteProcessGroupStatus().add(nodeRemoteProcessGroupStatusDTO);
-
-            // populate node remote process group status dto
-            final String nodeId = node.getNodeId().getId();
-            nodeRemoteProcessGroupStatusDTO.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-            nodeRemoteProcessGroupStatusDTO.setRemoteProcessGroupStatus(dtoFactory.createRemoteProcessGroupStatusDto(remoteProcessGroupStatus));
-        }
-
-        return clusterRemoteProcessGroupStatusDto;
-    }
-
-    @Override
-    public ClusterStatusHistoryDTO getClusterProcessorStatusHistory(String processorId) {
-        return clusterManager.getProcessorStatusHistory(processorId);
-    }
-
-    @Override
-    public ClusterStatusHistoryDTO getClusterConnectionStatusHistory(String connectionId) {
-        return clusterManager.getConnectionStatusHistory(connectionId);
-    }
-
-    @Override
-    public ClusterStatusHistoryDTO getClusterProcessGroupStatusHistory(String processGroupId) {
-        return clusterManager.getProcessGroupStatusHistory(processGroupId);
-    }
-
-    @Override
-    public ClusterStatusHistoryDTO getClusterRemoteProcessGroupStatusHistory(String remoteProcessGroupId) {
-        return clusterManager.getRemoteProcessGroupStatusHistory(remoteProcessGroupId);
-    }
-
-    @Override
-    public NodeStatusDTO getNodeStatus(String nodeId) {
-        // find the node in question
-        final Node node = clusterManager.getNode(nodeId);
-
-        // verify node state
-        if (node == null) {
-            throw new UnknownNodeException("Node does not exist.");
-        } else if (Node.Status.CONNECTED != node.getStatus()) {
-            throw new IllegalClusterStateException(
-                    String.format("Node '%s:%s' is not connected to the cluster.",
-                            node.getNodeId().getApiAddress(), node.getNodeId().getApiPort()));
-        }
-
-        // get the node's last heartbeat
-        final NodeStatusDTO nodeStatus = new NodeStatusDTO();
-        final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-        if (nodeHeartbeatPayload == null) {
-            return nodeStatus;
-        }
-
-        // get the node status
-        final ProcessGroupStatus nodeProcessGroupStatus = nodeHeartbeatPayload.getProcessGroupStatus();
-        if (nodeProcessGroupStatus == null) {
-            return nodeStatus;
-        }
-
-        final ProcessGroupStatusDTO nodeProcessGroupStatusDto = dtoFactory.createProcessGroupStatusDto(clusterManager.getBulletinRepository(), nodeProcessGroupStatus);
-        nodeStatus.setControllerStatus(nodeProcessGroupStatusDto);
-        nodeStatus.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-
-        return nodeStatus;
-    }
-
-    @Override
-    public NodeSystemDiagnosticsDTO getNodeSystemDiagnostics(String nodeId) {
-        // find the node in question
-        final Node node = clusterManager.getNode(nodeId);
-
-        // verify node state
-        if (node == null) {
-            throw new UnknownNodeException("Node does not exist.");
-        } else if (Node.Status.CONNECTED != node.getStatus()) {
-            throw new IllegalClusterStateException(
-                    String.format("Node '%s:%s' is not connected to the cluster.",
-                            node.getNodeId().getApiAddress(), node.getNodeId().getApiPort()));
-        }
-
-        // get the node's last heartbeat
-        final NodeSystemDiagnosticsDTO nodeStatus = new NodeSystemDiagnosticsDTO();
-        final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-        if (nodeHeartbeatPayload == null) {
-            return nodeStatus;
-        }
-
-        // get the node status
-        final SystemDiagnostics nodeSystemDiagnostics = nodeHeartbeatPayload.getSystemDiagnostics();
-        if (nodeSystemDiagnostics == null) {
-            return nodeStatus;
-        }
-
-        // populate the dto
-        nodeStatus.setControllerStatus(dtoFactory.createSystemDiagnosticsDto(nodeSystemDiagnostics));
-        nodeStatus.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-
-        return nodeStatus;
-    }
-
-    @Override
-    public ClusterStatusDTO getClusterStatus() {
-
-        // create cluster status dto
-        final ClusterStatusDTO clusterStatusDto = new ClusterStatusDTO();
-
-        // populate node status dtos
-        final Collection<NodeStatusDTO> nodeStatusDtos = new ArrayList<>();
-        clusterStatusDto.setNodeStatus(nodeStatusDtos);
-
-        for (final Node node : clusterManager.getNodes()) {
-
-            if (Node.Status.CONNECTED != node.getStatus()) {
-                continue;
-            }
-
-            final HeartbeatPayload nodeHeartbeatPayload = node.getHeartbeatPayload();
-            if (nodeHeartbeatPayload == null) {
-                continue;
-            }
-
-            final ProcessGroupStatus nodeProcessGroupStatus = nodeHeartbeatPayload.getProcessGroupStatus();
-            if (nodeProcessGroupStatus == null) {
-                continue;
-            }
-
-            final ProcessGroupStatusDTO nodeProcessGroupStatusDto = dtoFactory.createProcessGroupStatusDto(clusterManager.getBulletinRepository(), nodeProcessGroupStatus);
-
-            // create node status dto
-            final NodeStatusDTO nodeStatusDto = new NodeStatusDTO();
-            nodeStatusDtos.add(nodeStatusDto);
-
-            // populate the status
-            nodeStatusDto.setControllerStatus(nodeProcessGroupStatusDto);
-
-            // create and add node dto
-            final String nodeId = node.getNodeId().getId();
-            nodeStatusDto.setNode(dtoFactory.createNodeDTO(node, clusterManager.getNodeEvents(nodeId), isPrimaryNode(nodeId)));
-
-        }
-
-        return clusterStatusDto;
-    }
-
     @Override
     public ProcessorDTO getProcessor(String id) {
         ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
@@ -3650,91 +2977,4 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
             return date1;
         }
     }
-
-    /**
-     * Utility method for extracting component counts from the specified group status.
-     */
-    private ProcessGroupCounts extractProcessGroupCounts(ProcessGroupStatus groupStatus) {
-        int running = 0;
-        int stopped = 0;
-        int invalid = 0;
-        int disabled = 0;
-        int activeRemotePorts = 0;
-        int inactiveRemotePorts = 0;
-
-        for (final ProcessorStatus processorStatus : groupStatus.getProcessorStatus()) {
-            switch (processorStatus.getRunStatus()) {
-                case Disabled:
-                    disabled++;
-                    break;
-                case Running:
-                    running++;
-                    break;
-                case Invalid:
-                    invalid++;
-                    break;
-                default:
-                    stopped++;
-                    break;
-            }
-        }
-
-        for (final PortStatus portStatus : groupStatus.getInputPortStatus()) {
-            switch (portStatus.getRunStatus()) {
-                case Disabled:
-                    disabled++;
-                    break;
-                case Running:
-                    running++;
-                    break;
-                case Invalid:
-                    invalid++;
-                    break;
-                default:
-                    stopped++;
-                    break;
-            }
-        }
-
-        for (final PortStatus portStatus : groupStatus.getOutputPortStatus()) {
-            switch (portStatus.getRunStatus()) {
-                case Disabled:
-                    disabled++;
-                    break;
-                case Running:
-                    running++;
-                    break;
-                case Invalid:
-                    invalid++;
-                    break;
-                default:
-                    stopped++;
-                    break;
-            }
-        }
-
-        for (final RemoteProcessGroupStatus remoteStatus : groupStatus.getRemoteProcessGroupStatus()) {
-            if (remoteStatus.getActiveRemotePortCount() != null) {
-                activeRemotePorts += remoteStatus.getActiveRemotePortCount();
-            }
-            if (remoteStatus.getInactiveRemotePortCount() != null) {
-                inactiveRemotePorts += remoteStatus.getInactiveRemotePortCount();
-            }
-            if (CollectionUtils.isNotEmpty(remoteStatus.getAuthorizationIssues())) {
-                invalid++;
-            }
-        }
-
-        for (final ProcessGroupStatus childGroupStatus : groupStatus.getProcessGroupStatus()) {
-            final ProcessGroupCounts childCounts = extractProcessGroupCounts(childGroupStatus);
-            running += childCounts.getRunningCount();
-            stopped += childCounts.getStoppedCount();
-            invalid += childCounts.getInvalidCount();
-            disabled += childCounts.getDisabledCount();
-            activeRemotePorts += childCounts.getActiveRemotePortCount();
-            inactiveRemotePorts += childCounts.getInactiveRemotePortCount();
-        }
-
-        return new ProcessGroupCounts(0, 0, running, stopped, invalid, disabled, activeRemotePorts, inactiveRemotePorts);
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
index 6f895b8..3b429e7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
@@ -79,6 +79,8 @@ public abstract class ApplicationResource {
     private static final int CLUSTER_CONTEXT_HEADER_VALUE_MAX_BYTES = (int) (0.75 * HEADER_BUFFER_SIZE);
     private static final Logger logger = LoggerFactory.getLogger(ApplicationResource.class);
 
+    public static final String NODEWISE = "false";
+
     @Context
     private HttpServletRequest httpServletRequest;
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/0d3bd2c4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/BulletinBoardResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/BulletinBoardResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/BulletinBoardResource.java
index 6197953..d13b5c9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/BulletinBoardResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/BulletinBoardResource.java
@@ -16,20 +16,19 @@
  */
 package org.apache.nifi.web.api;
 
-import com.wordnik.swagger.annotations.Api;
-import com.wordnik.swagger.annotations.ApiOperation;
-import com.wordnik.swagger.annotations.ApiParam;
-import com.wordnik.swagger.annotations.ApiResponse;
-import com.wordnik.swagger.annotations.ApiResponses;
-import com.wordnik.swagger.annotations.Authorization;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.api.dto.BulletinBoardDTO;
 import org.apache.nifi.web.api.dto.BulletinQueryDTO;
@@ -39,18 +38,23 @@ import org.apache.nifi.web.api.request.BulletinBoardPatternParameter;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.IntegerParameter;
 import org.apache.nifi.web.api.request.LongParameter;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
 
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiParam;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
+import com.wordnik.swagger.annotations.Authorization;
+
 /**
  * RESTful endpoint for managing a Template.
  */
 @Api(hidden = true)
 public class BulletinBoardResource extends ApplicationResource {
 
-    private static final Logger logger = LoggerFactory.getLogger(BulletinBoardResource.class);
+    private NiFiProperties properties;
+    private WebClusterManager clusterManager;
 
     private NiFiServiceFacade serviceFacade;
 
@@ -128,6 +132,11 @@ public class BulletinBoardResource extends ApplicationResource {
             )
             @QueryParam("limit") IntegerParameter limit) {
 
+        // replicate if cluster manager
+        if (properties.isClusterManager()) {
+            return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+
         // build the bulletin query
         final BulletinQueryDTO query = new BulletinQueryDTO();
 
@@ -171,4 +180,11 @@ public class BulletinBoardResource extends ApplicationResource {
         this.serviceFacade = serviceFacade;
     }
 
+    public void setClusterManager(WebClusterManager clusterManager) {
+        this.clusterManager = clusterManager;
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
 }