You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by br...@apache.org on 2016/12/09 19:51:45 UTC

[1/3] nifi-minifi git commit: MINIFI-154 Adding support for Controller Services

Repository: nifi-minifi
Updated Branches:
  refs/heads/master b028f5a00 -> cbb2bdd8e


http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ProcessGroupsAndRemoteProcessGroups.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ProcessGroupsAndRemoteProcessGroups.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ProcessGroupsAndRemoteProcessGroups.yml
index 46be605..a62ab4a 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ProcessGroupsAndRemoteProcessGroups.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ProcessGroupsAndRemoteProcessGroups.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: ProcessGroupsAndRemoteProcessGroups
   comment: ''
@@ -101,6 +101,7 @@ Processors:
   Properties:
     Delete Attributes Expression:
     top: top
+Controller Services: []
 Process Groups:
 - id: 207888b1-0158-1000-0000-000000000000
   name: middle
@@ -118,6 +119,7 @@ Process Groups:
     Properties:
       Delete Attributes Expression:
       middle: middle
+  Controller Services: []
   Process Groups:
   - id: 20794cd4-0158-1000-0000-000000000000
     name: bottom
@@ -135,6 +137,7 @@ Process Groups:
       Properties:
         Delete Attributes Expression:
         bottom: bottom
+    Controller Services: []
     Process Groups: []
     Input Ports:
     - id: 207a5f50-0158-1000-0000-000000000000

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ReplaceTextExpressionLanguageCSVReformatting.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ReplaceTextExpressionLanguageCSVReformatting.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ReplaceTextExpressionLanguageCSVReformatting.yml
index cc89aa6..ec14cff 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ReplaceTextExpressionLanguageCSVReformatting.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/ReplaceTextExpressionLanguageCSVReformatting.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: ReplaceTextExpressionLanguageCSVReformatting
   comment: ''
@@ -123,6 +123,7 @@ Processors:
       2006,10-01-2004,10may2004
       2007,15-05-2006,10jun2005
       2009,8-8-2008,10aug2008
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/SimpleTailFileToRPG.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/SimpleTailFileToRPG.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/SimpleTailFileToRPG.yml
index c70a018..9c4155a 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/SimpleTailFileToRPG.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/SimpleTailFileToRPG.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: Simple TailFile To RPG
   comment: ''
@@ -77,6 +77,7 @@ Processors:
     tailfile-maximum-age: 24 hours
     tailfile-recursive-lookup: 'false'
     tailfile-rolling-strategy: Fixed name
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFramework.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFramework.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFramework.yml
index b510f97..8bf6ef9 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFramework.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFramework.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: StressTestFramework
   comment: ''
@@ -98,6 +98,7 @@ Processors:
     Delete Attributes Expression:
     property 1: value 1
     property 2: value 2 ${nextInt()}
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFrameworkFunnel.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFrameworkFunnel.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFrameworkFunnel.yml
index 95e8f52..1106a85 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFrameworkFunnel.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/StressTestFrameworkFunnel.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: StressTestFramework
   comment: ''
@@ -143,6 +143,7 @@ Processors:
     Delete Attributes Expression:
     property 1: value 1
     property 2: value 2 ${nextInt()}
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/config.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/config.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/config.yml
index c1685af..8886205 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/config.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/config.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: MiNiFi Flow
   comment: ''

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5707a9d..446d8ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -206,12 +206,6 @@ limitations under the License.
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi.minifi</groupId>
-                <artifactId>minifi-standard-services-api-nar</artifactId>
-                <version>0.2.0-SNAPSHOT</version>
-                <type>nar</type>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.nifi.minifi</groupId>
                 <artifactId>minifi-update-attribute-nar</artifactId>
                 <version>0.2.0-SNAPSHOT</version>
                 <type>nar</type>
@@ -546,6 +540,11 @@ limitations under the License.
                 <version>${org.apache.nifi.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.nifi</groupId>
+                <artifactId>nifi-site-to-site-reporting-task</artifactId>
+                <version>${org.apache.nifi.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>commons-io</groupId>
                 <artifactId>commons-io</artifactId>
                 <version>2.5</version>
@@ -561,19 +560,19 @@ limitations under the License.
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcprov-jdk15on</artifactId>
-                <version>1.54</version>
+                <version>1.55</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcpg-jdk15on</artifactId>
-                <version>1.54</version>
+                <version>1.55</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcpkix-jdk15on</artifactId>
-                <version>1.54</version>
+                <version>1.55</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>


[2/3] nifi-minifi git commit: MINIFI-154 Adding support for Controller Services

Posted by br...@apache.org.
http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-standard-services-api-nar/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-standard-services-api-nar/pom.xml b/minifi-nar-bundles/minifi-standard-services-api-nar/pom.xml
deleted file mode 100644
index c8ab6ee..0000000
--- a/minifi-nar-bundles/minifi-standard-services-api-nar/pom.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-<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">
-    <!--
-      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.
-    -->
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.nifi</groupId>
-        <artifactId>nifi-standard-services</artifactId>
-        <version>1.0.0</version>
-        <relativePath />
-    </parent>
-    <groupId>org.apache.nifi.minifi</groupId>
-    <artifactId>minifi-standard-services-api-nar</artifactId>
-    <version>0.2.0-SNAPSHOT</version>
-    <packaging>nar</packaging>
-    <properties>
-        <maven.javadoc.skip>true</maven.javadoc.skip>
-        <source.skip>true</source.skip>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-ssl-context-service-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-distributed-cache-client-service-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-load-distribution-service-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-http-context-map-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-dbcp-service-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-hbase-client-service-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-
-        <!-- Manage provided dependencies in lib -->
-        <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcprov-jdk15on</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcpg-jdk15on</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcpkix-jdk15on</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>ch.qos.logback</groupId>
-            <artifactId>logback-classic</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-
-    </dependencies>
-</project>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/LICENSE b/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/NOTICE
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/NOTICE b/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index 7eb13a7..0000000
--- a/minifi-nar-bundles/minifi-standard-services-api-nar/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,24 +0,0 @@
-minifi-standard-nar
-Copyright 2014-2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-******************
-Apache Software License v2
-******************
-
-The following binary components are provided under the Apache Software License v2
-
-  (ASLv2) Apache Commons IO
-    The following NOTICE information applies:
-      Apache Commons IO
-      Copyright 2002-2012 The Apache Software Foundation
-
-  (ASLv2) Apache Commons Lang
-    The following NOTICE information applies:
-      Apache Commons Lang
-      Copyright 2001-2015 The Apache Software Foundation
-
-      This product includes software from the Spring Framework,
-      under the Apache License 2.0 (see: StringUtils.containsWhitespace())

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/pom.xml b/minifi-nar-bundles/pom.xml
index 2061163..3d9eea9 100644
--- a/minifi-nar-bundles/pom.xml
+++ b/minifi-nar-bundles/pom.xml
@@ -28,7 +28,6 @@
         <module>minifi-provenance-repository-bundle</module>
         <module>minifi-provenance-reporting-bundle</module>
         <module>minifi-update-attribute-nar</module>
-        <module>minifi-standard-services-api-nar</module>
         <module>minifi-standard-nar</module>
         <module>minifi-ssl-context-service-nar</module>
     </modules>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ConfigSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ConfigSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ConfigSchemaFunction.java
index ed016e1..5665430 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ConfigSchemaFunction.java
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ConfigSchemaFunction.java
@@ -19,6 +19,7 @@ package org.apache.nifi.minifi.toolkit.configuration.dto;
 
 import org.apache.nifi.minifi.commons.schema.ConfigSchema;
 import org.apache.nifi.minifi.commons.schema.ConnectionSchema;
+import org.apache.nifi.minifi.commons.schema.ControllerServiceSchema;
 import org.apache.nifi.minifi.commons.schema.FunnelSchema;
 import org.apache.nifi.minifi.commons.schema.PortSchema;
 import org.apache.nifi.minifi.commons.schema.ProcessGroupSchema;
@@ -45,6 +46,7 @@ import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.OU
 public class ConfigSchemaFunction implements Function<TemplateDTO, ConfigSchema> {
     private final FlowControllerSchemaFunction flowControllerSchemaFunction;
     private final ProcessorSchemaFunction processorSchemaFunction;
+    private final ControllerServiceSchemaFunction controllerServiceSchemaFunction;
     private final ConnectionSchemaFunction connectionSchemaFunction;
     private final FunnelSchemaFunction funnelSchemaFunction;
     private final RemoteProcessGroupSchemaFunction remoteProcessGroupSchemaFunction;
@@ -53,12 +55,12 @@ public class ConfigSchemaFunction implements Function<TemplateDTO, ConfigSchema>
 
     public ConfigSchemaFunction() {
         this(new FlowControllerSchemaFunction(), new ProcessorSchemaFunction(), new ConnectionSchemaFunction(), new FunnelSchemaFunction(), new RemoteProcessGroupSchemaFunction(
-                new RemoteInputPortSchemaFunction()), new PortSchemaFunction(INPUT_PORTS_KEY), new PortSchemaFunction(OUTPUT_PORTS_KEY));
+                new RemoteInputPortSchemaFunction()), new PortSchemaFunction(INPUT_PORTS_KEY), new PortSchemaFunction(OUTPUT_PORTS_KEY), new ControllerServiceSchemaFunction());
     }
 
     public ConfigSchemaFunction(FlowControllerSchemaFunction flowControllerSchemaFunction, ProcessorSchemaFunction processorSchemaFunction, ConnectionSchemaFunction connectionSchemaFunction,
                                 FunnelSchemaFunction funnelSchemaFunction, RemoteProcessGroupSchemaFunction remoteProcessGroupSchemaFunction, PortSchemaFunction inputPortSchemaFunction,
-                                PortSchemaFunction outputPortSchemaFunction) {
+                                PortSchemaFunction outputPortSchemaFunction, ControllerServiceSchemaFunction controllerServiceSchemaFunction) {
         this.flowControllerSchemaFunction = flowControllerSchemaFunction;
         this.processorSchemaFunction = processorSchemaFunction;
         this.connectionSchemaFunction = connectionSchemaFunction;
@@ -66,6 +68,7 @@ public class ConfigSchemaFunction implements Function<TemplateDTO, ConfigSchema>
         this.remoteProcessGroupSchemaFunction = remoteProcessGroupSchemaFunction;
         this.inputPortSchemaFunction = inputPortSchemaFunction;
         this.outputPortSchemaFunction = outputPortSchemaFunction;
+        this.controllerServiceSchemaFunction = controllerServiceSchemaFunction;
     }
 
     @Override
@@ -100,6 +103,12 @@ public class ConfigSchemaFunction implements Function<TemplateDTO, ConfigSchema>
                 .map(ProcessorSchema::toMap)
                 .collect(Collectors.toList()));
 
+        map.put(CommonPropertyKeys.CONTROLLER_SERVICES_KEY, nullToEmpty(snippet.getControllerServices()).stream()
+                .map(controllerServiceSchemaFunction)
+                .sorted(Comparator.comparing(ControllerServiceSchema::getName))
+                .map(ControllerServiceSchema::toMap)
+                .collect(Collectors.toList()));
+
         map.put(CommonPropertyKeys.CONNECTIONS_KEY, nullToEmpty(snippet.getConnections()).stream()
                 .map(connectionSchemaFunction)
                 .sorted(Comparator.comparing(ConnectionSchema::getName))

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ControllerServiceSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ControllerServiceSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ControllerServiceSchemaFunction.java
new file mode 100644
index 0000000..c76751c
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ControllerServiceSchemaFunction.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.minifi.toolkit.configuration.dto;
+
+import org.apache.nifi.minifi.commons.schema.ControllerServiceSchema;
+import org.apache.nifi.web.api.dto.ControllerServiceDTO;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import static org.apache.nifi.minifi.commons.schema.common.CollectionUtil.nullToEmpty;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ANNOTATION_DATA_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.TYPE_KEY;
+
+public class ControllerServiceSchemaFunction implements Function<ControllerServiceDTO, ControllerServiceSchema> {
+    @Override
+    public ControllerServiceSchema apply(ControllerServiceDTO controllerServiceDTO) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(NAME_KEY, controllerServiceDTO.getName());
+        map.put(ID_KEY, controllerServiceDTO.getId());
+        map.put(TYPE_KEY, controllerServiceDTO.getType());
+
+        map.put(PROPERTIES_KEY, new HashMap<>(nullToEmpty(controllerServiceDTO.getProperties())));
+
+        String annotationData = controllerServiceDTO.getAnnotationData();
+        if(annotationData != null && !annotationData.isEmpty()) {
+            map.put(ANNOTATION_DATA_KEY, annotationData);
+        }
+
+        return new ControllerServiceSchema(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaFunction.java
index 89097cc..2efaca8 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaFunction.java
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaFunction.java
@@ -29,8 +29,11 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static org.apache.nifi.minifi.commons.schema.common.CollectionUtil.nullToEmpty;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ANNOTATION_DATA_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CLASS_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_PERIOD_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_STRATEGY_KEY;
 
@@ -42,7 +45,7 @@ public class ProcessorSchemaFunction implements Function<ProcessorDTO, Processor
         Map<String, Object> map = new HashMap<>();
         map.put(NAME_KEY, processorDTO.getName());
         map.put(ID_KEY, processorDTO.getId());
-        map.put(ProcessorSchema.CLASS_KEY, processorDTO.getType());
+        map.put(CLASS_KEY, processorDTO.getType());
         map.put(SCHEDULING_STRATEGY_KEY, processorDTOConfig.getSchedulingStrategy());
         map.put(SCHEDULING_PERIOD_KEY, processorDTOConfig.getSchedulingPeriod());
 
@@ -57,11 +60,11 @@ public class ProcessorSchemaFunction implements Function<ProcessorDTO, Processor
                 .filter(RelationshipDTO::isAutoTerminate)
                 .map(RelationshipDTO::getName)
                 .collect(Collectors.toList()));
-        map.put(ProcessorSchema.PROCESSOR_PROPS_KEY, new HashMap<>(nullToEmpty(processorDTOConfig.getProperties())));
+        map.put(PROPERTIES_KEY, new HashMap<>(nullToEmpty(processorDTOConfig.getProperties())));
 
         String annotationData = processorDTOConfig.getAnnotationData();
         if(annotationData != null && !annotationData.isEmpty()) {
-            map.put(ProcessorSchema.ANNOTATION_DATA_KEY, annotationData);
+            map.put(ANNOTATION_DATA_KEY, annotationData);
         }
 
         return new ProcessorSchema(map);

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMainTest.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMainTest.java b/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMainTest.java
index 70f9e75..597546f 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMainTest.java
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMainTest.java
@@ -208,6 +208,11 @@ public class ConfigMainTest {
     }
 
     @Test
+    public void testTransformRoundTripNestedControllerServices() throws IOException, JAXBException, SchemaLoaderException {
+        transformRoundTrip("NestedControllerServices");
+    }
+
+    @Test
     public void testSuccessTransformProcessGroup() throws IOException, JAXBException, SchemaLoaderException {
         ConfigMain.transformTemplateToSchema(getClass().getClassLoader().getResourceAsStream("TemplateWithProcessGroup.xml")).toMap();
     }

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaTest.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaTest.java b/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaTest.java
index 719c89a..e3125fa 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaTest.java
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/java/org/apache/nifi/minifi/toolkit/configuration/dto/ProcessorSchemaTest.java
@@ -32,6 +32,9 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ANNOTATION_DATA_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CLASS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
 import static org.junit.Assert.assertEquals;
 
 public class ProcessorSchemaTest extends BaseSchemaTester<ProcessorSchema, ProcessorDTO> {
@@ -110,7 +113,7 @@ public class ProcessorSchemaTest extends BaseSchemaTester<ProcessorSchema, Proce
         map = new HashMap<>();
         map.put(CommonPropertyKeys.NAME_KEY, testName);
         map.put(CommonPropertyKeys.ID_KEY, testId);
-        map.put(ProcessorSchema.CLASS_KEY, testProcessorClass);
+        map.put(CLASS_KEY, testProcessorClass);
         map.put(CommonPropertyKeys.SCHEDULING_STRATEGY_KEY, testSchedulingStrategy);
         map.put(CommonPropertyKeys.SCHEDULING_PERIOD_KEY, testSchedulingPeriod);
         map.put(CommonPropertyKeys.MAX_CONCURRENT_TASKS_KEY, testMaxConcurrentTasks);
@@ -118,8 +121,8 @@ public class ProcessorSchemaTest extends BaseSchemaTester<ProcessorSchema, Proce
         map.put(CommonPropertyKeys.YIELD_PERIOD_KEY, testYieldDuration);
         map.put(ProcessorSchema.RUN_DURATION_NANOS_KEY, testRunDurationNanos);
         map.put(ProcessorSchema.AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, Arrays.asList(testRelationship));
-        map.put(ProcessorSchema.PROCESSOR_PROPS_KEY, new HashMap<>(properties));
-        map.put(ProcessorSchema.ANNOTATION_DATA_KEY, testAnnotationData);
+        map.put(PROPERTIES_KEY, new HashMap<>(properties));
+        map.put(ANNOTATION_DATA_KEY, testAnnotationData);
     }
 
     @Test
@@ -139,7 +142,7 @@ public class ProcessorSchemaTest extends BaseSchemaTester<ProcessorSchema, Proce
     @Test
     public void testNoProcessorClass() {
         dto.setType(null);
-        map.remove(ProcessorSchema.CLASS_KEY);
+        map.remove(CLASS_KEY);
         assertDtoAndMapConstructorAreSame(1);
     }
 
@@ -203,14 +206,14 @@ public class ProcessorSchemaTest extends BaseSchemaTester<ProcessorSchema, Proce
     @Test
     public void testNoProperties() {
         config.setProperties(null);
-        map.remove(ProcessorSchema.PROCESSOR_PROPS_KEY);
+        map.remove(PROPERTIES_KEY);
         assertDtoAndMapConstructorAreSame(0);
     }
 
     @Test
     public void testNoAnnotationData() {
         config.setAnnotationData(null);
-        map.remove(ProcessorSchema.ANNOTATION_DATA_KEY);
+        map.remove(ANNOTATION_DATA_KEY);
         assertDtoAndMapConstructorAreSame(0);
     }
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/CsvToJson.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/CsvToJson.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/CsvToJson.yml
index eaa16c2..ad0d0ac 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/CsvToJson.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/CsvToJson.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: CsvToJsonWorking
   comment: ''
@@ -148,6 +148,7 @@ Processors:
   - success
   Properties:
     Delete Attributes Expression:
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/DecompressionCircularFlow.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/DecompressionCircularFlow.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/DecompressionCircularFlow.yml
index 4d11eac..f93877e 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/DecompressionCircularFlow.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/DecompressionCircularFlow.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: DecompressionCircularFlow2
   comment: ''
@@ -187,6 +187,7 @@ Processors:
     Compression Level:
     Mode: decompress
     Update Filename:
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/InvokeHttpMiNiFiTemplateTest.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/InvokeHttpMiNiFiTemplateTest.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/InvokeHttpMiNiFiTemplateTest.yml
index a427409..6a84d72 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/InvokeHttpMiNiFiTemplateTest.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/InvokeHttpMiNiFiTemplateTest.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: InvokeHttpMiNiFiTemplateTest2
   comment: ''
@@ -166,6 +166,7 @@ Processors:
   Properties:
     Delete Attributes Expression:
     q: nifi
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/MultipleRelationships.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/MultipleRelationships.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/MultipleRelationships.yml
index 8f8b038..264b68d 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/MultipleRelationships.yml
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/MultipleRelationships.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-MiNiFi Config Version: 2
+MiNiFi Config Version: 3
 Flow Controller:
   name: MultipleRelationships
   comment: ''
@@ -114,6 +114,7 @@ Processors:
   Properties:
     Delete Attributes Expression:
     filename: abc
+Controller Services: []
 Process Groups: []
 Input Ports: []
 Output Ports: []

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.xml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.xml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.xml
new file mode 100644
index 0000000..13fc40e
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.xml
@@ -0,0 +1,1089 @@
+<?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.
+ -->
+<template encoding-version="1.0">
+  <description></description>
+  <groupId>d193767e-0158-1000-9f0b-960406019246</groupId>
+  <name>NestedControllerServices</name>
+  <snippet>
+    <connections>
+      <id>d5234d12-0158-1000-0000-000000000000</id>
+      <parentGroupId>d193767e-0158-1000-0000-000000000000</parentGroupId>
+      <backPressureDataSizeThreshold>1 GB</backPressureDataSizeThreshold>
+      <backPressureObjectThreshold>10000</backPressureObjectThreshold>
+      <destination>
+        <groupId>d193767e-0158-1000-0000-000000000000</groupId>
+        <id>d5233667-0158-1000-0000-000000000000</id>
+        <type>PROCESSOR</type>
+      </destination>
+      <flowFileExpiration>0 sec</flowFileExpiration>
+      <labelIndex>1</labelIndex>
+      <name></name>
+      <selectedRelationships>success</selectedRelationships>
+      <source>
+        <groupId>d193767e-0158-1000-0000-000000000000</groupId>
+        <id>d5232ad7-0158-1000-0000-000000000000</id>
+        <type>PROCESSOR</type>
+      </source>
+      <zIndex>0</zIndex>
+    </connections>
+    <controllerServices>
+      <id>d4c47b18-0158-1000-0000-000000000000</id>
+      <parentGroupId>d193767e-0158-1000-0000-000000000000</parentGroupId>
+      <comments></comments>
+      <descriptors>
+        <entry>
+          <key>Keystore Filename</key>
+          <value>
+            <name>Keystore Filename</name>
+          </value>
+        </entry>
+        <entry>
+          <key>Keystore Password</key>
+          <value>
+            <name>Keystore Password</name>
+          </value>
+        </entry>
+        <entry>
+          <key>key-password</key>
+          <value>
+            <name>key-password</name>
+          </value>
+        </entry>
+        <entry>
+          <key>Keystore Type</key>
+          <value>
+            <name>Keystore Type</name>
+          </value>
+        </entry>
+        <entry>
+          <key>Truststore Filename</key>
+          <value>
+            <name>Truststore Filename</name>
+          </value>
+        </entry>
+        <entry>
+          <key>Truststore Password</key>
+          <value>
+            <name>Truststore Password</name>
+          </value>
+        </entry>
+        <entry>
+          <key>Truststore Type</key>
+          <value>
+            <name>Truststore Type</name>
+          </value>
+        </entry>
+        <entry>
+          <key>SSL Protocol</key>
+          <value>
+            <name>SSL Protocol</name>
+          </value>
+        </entry>
+      </descriptors>
+      <name>test-root</name>
+      <properties>
+        <entry>
+          <key>Keystore Filename</key>
+        </entry>
+        <entry>
+          <key>Keystore Password</key>
+        </entry>
+        <entry>
+          <key>key-password</key>
+        </entry>
+        <entry>
+          <key>Keystore Type</key>
+        </entry>
+        <entry>
+          <key>Truststore Filename</key>
+        </entry>
+        <entry>
+          <key>Truststore Password</key>
+        </entry>
+        <entry>
+          <key>Truststore Type</key>
+        </entry>
+        <entry>
+          <key>SSL Protocol</key>
+        </entry>
+      </properties>
+      <state>DISABLED</state>
+      <type>org.apache.nifi.ssl.StandardSSLContextService</type>
+    </controllerServices>
+    <processGroups>
+      <id>d4c4b4e4-0158-1000-0000-000000000000</id>
+      <parentGroupId>d193767e-0158-1000-0000-000000000000</parentGroupId>
+      <position>
+        <x>602.334350907364</x>
+        <y>0.0</y>
+      </position>
+      <comments></comments>
+      <contents>
+        <connections>
+          <id>d522e203-0158-1000-0000-000000000000</id>
+          <parentGroupId>d4c4b4e4-0158-1000-0000-000000000000</parentGroupId>
+          <backPressureDataSizeThreshold>1 GB</backPressureDataSizeThreshold>
+          <backPressureObjectThreshold>10000</backPressureObjectThreshold>
+          <destination>
+            <groupId>d4c4b4e4-0158-1000-0000-000000000000</groupId>
+            <id>d522d82b-0158-1000-0000-000000000000</id>
+            <type>PROCESSOR</type>
+          </destination>
+          <flowFileExpiration>0 sec</flowFileExpiration>
+          <labelIndex>1</labelIndex>
+          <name></name>
+          <selectedRelationships>success</selectedRelationships>
+          <source>
+            <groupId>d4c4b4e4-0158-1000-0000-000000000000</groupId>
+            <id>d520168b-0158-1000-0000-000000000000</id>
+            <type>PROCESSOR</type>
+          </source>
+          <zIndex>0</zIndex>
+        </connections>
+        <controllerServices>
+          <id>d4c4c947-0158-1000-0000-000000000000</id>
+          <parentGroupId>d4c4b4e4-0158-1000-0000-000000000000</parentGroupId>
+          <comments></comments>
+          <descriptors>
+            <entry>
+              <key>Maximum Outstanding Requests</key>
+              <value>
+                <name>Maximum Outstanding Requests</name>
+              </value>
+            </entry>
+            <entry>
+              <key>Request Expiration</key>
+              <value>
+                <name>Request Expiration</name>
+              </value>
+            </entry>
+          </descriptors>
+          <name>test-middle</name>
+          <properties>
+            <entry>
+              <key>Maximum Outstanding Requests</key>
+            </entry>
+            <entry>
+              <key>Request Expiration</key>
+            </entry>
+          </properties>
+          <state>DISABLED</state>
+          <type>org.apache.nifi.http.StandardHttpContextMap</type>
+        </controllerServices>
+        <processGroups>
+          <id>d4c52c16-0158-1000-0000-000000000000</id>
+          <parentGroupId>d4c4b4e4-0158-1000-0000-000000000000</parentGroupId>
+          <position>
+            <x>444.00000013523464</x>
+            <y>139.99998313812395</y>
+          </position>
+          <comments></comments>
+          <contents>
+            <connections>
+              <id>d52147e4-0158-1000-0000-000000000000</id>
+              <parentGroupId>d4c52c16-0158-1000-0000-000000000000</parentGroupId>
+              <backPressureDataSizeThreshold>1 GB</backPressureDataSizeThreshold>
+              <backPressureObjectThreshold>10000</backPressureObjectThreshold>
+              <destination>
+                <groupId>d4c52c16-0158-1000-0000-000000000000</groupId>
+                <id>d5205c43-0158-1000-0000-000000000000</id>
+                <type>PROCESSOR</type>
+              </destination>
+              <flowFileExpiration>0 sec</flowFileExpiration>
+              <labelIndex>1</labelIndex>
+              <name></name>
+              <selectedRelationships>success</selectedRelationships>
+              <source>
+                <groupId>d4c52c16-0158-1000-0000-000000000000</groupId>
+                <id>d5211ba3-0158-1000-0000-000000000000</id>
+                <type>PROCESSOR</type>
+              </source>
+              <zIndex>0</zIndex>
+            </connections>
+            <connections>
+              <id>d521c3e8-0158-1000-0000-000000000000</id>
+              <parentGroupId>d4c52c16-0158-1000-0000-000000000000</parentGroupId>
+              <backPressureDataSizeThreshold>1 GB</backPressureDataSizeThreshold>
+              <backPressureObjectThreshold>10000</backPressureObjectThreshold>
+              <destination>
+                <groupId>d4c52c16-0158-1000-0000-000000000000</groupId>
+                <id>d521ab50-0158-1000-0000-000000000000</id>
+                <type>PROCESSOR</type>
+              </destination>
+              <flowFileExpiration>0 sec</flowFileExpiration>
+              <labelIndex>1</labelIndex>
+              <name></name>
+              <selectedRelationships>duplicate</selectedRelationships>
+              <selectedRelationships>failure</selectedRelationships>
+              <selectedRelationships>non-duplicate</selectedRelationships>
+              <source>
+                <groupId>d4c52c16-0158-1000-0000-000000000000</groupId>
+                <id>d5205c43-0158-1000-0000-000000000000</id>
+                <type>PROCESSOR</type>
+              </source>
+              <zIndex>0</zIndex>
+            </connections>
+            <controllerServices>
+              <id>d4c5554d-0158-1000-0000-000000000000</id>
+              <parentGroupId>d4c52c16-0158-1000-0000-000000000000</parentGroupId>
+              <comments></comments>
+              <descriptors>
+                <entry>
+                  <key>Server Hostname</key>
+                  <value>
+                    <name>Server Hostname</name>
+                  </value>
+                </entry>
+                <entry>
+                  <key>Server Port</key>
+                  <value>
+                    <name>Server Port</name>
+                  </value>
+                </entry>
+                <entry>
+                  <key>SSL Context Service</key>
+                  <value>
+                    <identifiesControllerService>org.apache.nifi.ssl.SSLContextService</identifiesControllerService>
+                    <name>SSL Context Service</name>
+                  </value>
+                </entry>
+                <entry>
+                  <key>Communications Timeout</key>
+                  <value>
+                    <name>Communications Timeout</name>
+                  </value>
+                </entry>
+              </descriptors>
+              <name>test-inner</name>
+              <properties>
+                <entry>
+                  <key>Server Hostname</key>
+                  <value>localhost</value>
+                </entry>
+                <entry>
+                  <key>Server Port</key>
+                </entry>
+                <entry>
+                  <key>SSL Context Service</key>
+                  <value>d4c47b18-0158-1000-0000-000000000000</value>
+                </entry>
+                <entry>
+                  <key>Communications Timeout</key>
+                </entry>
+              </properties>
+              <state>DISABLED</state>
+              <type>org.apache.nifi.distributed.cache.client.DistributedMapCacheClientService</type>
+            </controllerServices>
+            <processors>
+              <id>d5205c43-0158-1000-0000-000000000000</id>
+              <parentGroupId>d4c52c16-0158-1000-0000-000000000000</parentGroupId>
+              <position>
+                <x>654.0000001352346</x>
+                <y>379.99999839691304</y>
+              </position>
+              <config>
+                <bulletinLevel>WARN</bulletinLevel>
+                <comments></comments>
+                <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+                <descriptors>
+                  <entry>
+                    <key>Cache Entry Identifier</key>
+                    <value>
+                      <name>Cache Entry Identifier</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>FlowFile Description</key>
+                    <value>
+                      <name>FlowFile Description</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Age Off Duration</key>
+                    <value>
+                      <name>Age Off Duration</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Distributed Cache Service</key>
+                    <value>
+                      <identifiesControllerService>org.apache.nifi.distributed.cache.client.DistributedMapCacheClient</identifiesControllerService>
+                      <name>Distributed Cache Service</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Cache The Entry Identifier</key>
+                    <value>
+                      <name>Cache The Entry Identifier</name>
+                    </value>
+                  </entry>
+                </descriptors>
+                <executionNode>ALL</executionNode>
+                <lossTolerant>false</lossTolerant>
+                <penaltyDuration>30 sec</penaltyDuration>
+                <properties>
+                  <entry>
+                    <key>Cache Entry Identifier</key>
+                    <value>${hash.value}</value>
+                  </entry>
+                  <entry>
+                    <key>FlowFile Description</key>
+                    <value>test</value>
+                  </entry>
+                  <entry>
+                    <key>Age Off Duration</key>
+                  </entry>
+                  <entry>
+                    <key>Distributed Cache Service</key>
+                    <value>d4c5554d-0158-1000-0000-000000000000</value>
+                  </entry>
+                  <entry>
+                    <key>Cache The Entry Identifier</key>
+                    <value>true</value>
+                  </entry>
+                </properties>
+                <runDurationMillis>0</runDurationMillis>
+                <schedulingPeriod>0 sec</schedulingPeriod>
+                <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+                <yieldDuration>1 sec</yieldDuration>
+              </config>
+              <name>DetectDuplicate</name>
+              <relationships>
+                <autoTerminate>false</autoTerminate>
+                <name>duplicate</name>
+              </relationships>
+              <relationships>
+                <autoTerminate>false</autoTerminate>
+                <name>failure</name>
+              </relationships>
+              <relationships>
+                <autoTerminate>false</autoTerminate>
+                <name>non-duplicate</name>
+              </relationships>
+              <style></style>
+              <type>org.apache.nifi.processors.standard.DetectDuplicate</type>
+            </processors>
+            <processors>
+              <id>d5211ba3-0158-1000-0000-000000000000</id>
+              <parentGroupId>d4c52c16-0158-1000-0000-000000000000</parentGroupId>
+              <position>
+                <x>669.0000001352346</x>
+                <y>154.999998396913</y>
+              </position>
+              <config>
+                <bulletinLevel>WARN</bulletinLevel>
+                <comments></comments>
+                <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+                <descriptors>
+                  <entry>
+                    <key>URL</key>
+                    <value>
+                      <name>URL</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Filename</key>
+                    <value>
+                      <name>Filename</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>SSL Context Service</key>
+                    <value>
+                      <identifiesControllerService>org.apache.nifi.ssl.SSLContextService</identifiesControllerService>
+                      <name>SSL Context Service</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Username</key>
+                    <value>
+                      <name>Username</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Password</key>
+                    <value>
+                      <name>Password</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Connection Timeout</key>
+                    <value>
+                      <name>Connection Timeout</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Data Timeout</key>
+                    <value>
+                      <name>Data Timeout</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>User Agent</key>
+                    <value>
+                      <name>User Agent</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Accept Content-Type</key>
+                    <value>
+                      <name>Accept Content-Type</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Follow Redirects</key>
+                    <value>
+                      <name>Follow Redirects</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>redirect-cookie-policy</key>
+                    <value>
+                      <name>redirect-cookie-policy</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Proxy Host</key>
+                    <value>
+                      <name>Proxy Host</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Proxy Port</key>
+                    <value>
+                      <name>Proxy Port</name>
+                    </value>
+                  </entry>
+                </descriptors>
+                <executionNode>ALL</executionNode>
+                <lossTolerant>false</lossTolerant>
+                <penaltyDuration>30 sec</penaltyDuration>
+                <properties>
+                  <entry>
+                    <key>URL</key>
+                    <value>https://localhost:8080/</value>
+                  </entry>
+                  <entry>
+                    <key>Filename</key>
+                    <value>getLocalhost</value>
+                  </entry>
+                  <entry>
+                    <key>SSL Context Service</key>
+                  </entry>
+                  <entry>
+                    <key>Username</key>
+                  </entry>
+                  <entry>
+                    <key>Password</key>
+                  </entry>
+                  <entry>
+                    <key>Connection Timeout</key>
+                    <value>30 sec</value>
+                  </entry>
+                  <entry>
+                    <key>Data Timeout</key>
+                    <value>30 sec</value>
+                  </entry>
+                  <entry>
+                    <key>User Agent</key>
+                  </entry>
+                  <entry>
+                    <key>Accept Content-Type</key>
+                  </entry>
+                  <entry>
+                    <key>Follow Redirects</key>
+                    <value>false</value>
+                  </entry>
+                  <entry>
+                    <key>redirect-cookie-policy</key>
+                    <value>default</value>
+                  </entry>
+                  <entry>
+                    <key>Proxy Host</key>
+                  </entry>
+                  <entry>
+                    <key>Proxy Port</key>
+                  </entry>
+                </properties>
+                <runDurationMillis>0</runDurationMillis>
+                <schedulingPeriod>0 sec</schedulingPeriod>
+                <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+                <yieldDuration>1 sec</yieldDuration>
+              </config>
+              <name>GetHTTP</name>
+              <relationships>
+                <autoTerminate>false</autoTerminate>
+                <name>success</name>
+              </relationships>
+              <style></style>
+              <type>org.apache.nifi.processors.standard.GetHTTP</type>
+            </processors>
+            <processors>
+              <id>d521ab50-0158-1000-0000-000000000000</id>
+              <parentGroupId>d4c52c16-0158-1000-0000-000000000000</parentGroupId>
+              <position>
+                <x>635.0000001352346</x>
+                <y>631.999998396913</y>
+              </position>
+              <config>
+                <bulletinLevel>WARN</bulletinLevel>
+                <comments></comments>
+                <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+                <descriptors>
+                  <entry>
+                    <key>Log Level</key>
+                    <value>
+                      <name>Log Level</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Log Payload</key>
+                    <value>
+                      <name>Log Payload</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Attributes to Log</key>
+                    <value>
+                      <name>Attributes to Log</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Attributes to Ignore</key>
+                    <value>
+                      <name>Attributes to Ignore</name>
+                    </value>
+                  </entry>
+                  <entry>
+                    <key>Log prefix</key>
+                    <value>
+                      <name>Log prefix</name>
+                    </value>
+                  </entry>
+                </descriptors>
+                <executionNode>ALL</executionNode>
+                <lossTolerant>false</lossTolerant>
+                <penaltyDuration>30 sec</penaltyDuration>
+                <properties>
+                  <entry>
+                    <key>Log Level</key>
+                    <value>info</value>
+                  </entry>
+                  <entry>
+                    <key>Log Payload</key>
+                    <value>false</value>
+                  </entry>
+                  <entry>
+                    <key>Attributes to Log</key>
+                  </entry>
+                  <entry>
+                    <key>Attributes to Ignore</key>
+                  </entry>
+                  <entry>
+                    <key>Log prefix</key>
+                  </entry>
+                </properties>
+                <runDurationMillis>0</runDurationMillis>
+                <schedulingPeriod>0 sec</schedulingPeriod>
+                <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+                <yieldDuration>1 sec</yieldDuration>
+              </config>
+              <name>LogAttribute</name>
+              <relationships>
+                <autoTerminate>true</autoTerminate>
+                <name>success</name>
+              </relationships>
+              <style></style>
+              <type>org.apache.nifi.processors.standard.LogAttribute</type>
+            </processors>
+          </contents>
+          <name>inner</name>
+        </processGroups>
+        <processors>
+          <id>d520168b-0158-1000-0000-000000000000</id>
+          <parentGroupId>d4c4b4e4-0158-1000-0000-000000000000</parentGroupId>
+          <position>
+            <x>-60.99999986476536</x>
+            <y>54.99998313812398</y>
+          </position>
+          <config>
+            <bulletinLevel>WARN</bulletinLevel>
+            <comments></comments>
+            <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+            <descriptors>
+              <entry>
+                <key>Listening Port</key>
+                <value>
+                  <name>Listening Port</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Hostname</key>
+                <value>
+                  <name>Hostname</name>
+                </value>
+              </entry>
+              <entry>
+                <key>SSL Context Service</key>
+                <value>
+                  <identifiesControllerService>org.apache.nifi.ssl.SSLContextService</identifiesControllerService>
+                  <name>SSL Context Service</name>
+                </value>
+              </entry>
+              <entry>
+                <key>HTTP Context Map</key>
+                <value>
+                  <identifiesControllerService>org.apache.nifi.http.HttpContextMap</identifiesControllerService>
+                  <name>HTTP Context Map</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allowed Paths</key>
+                <value>
+                  <name>Allowed Paths</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Default URL Character Set</key>
+                <value>
+                  <name>Default URL Character Set</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allow GET</key>
+                <value>
+                  <name>Allow GET</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allow POST</key>
+                <value>
+                  <name>Allow POST</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allow PUT</key>
+                <value>
+                  <name>Allow PUT</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allow DELETE</key>
+                <value>
+                  <name>Allow DELETE</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allow HEAD</key>
+                <value>
+                  <name>Allow HEAD</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Allow OPTIONS</key>
+                <value>
+                  <name>Allow OPTIONS</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Additional HTTP Methods</key>
+                <value>
+                  <name>Additional HTTP Methods</name>
+                </value>
+              </entry>
+              <entry>
+                <key>Client Authentication</key>
+                <value>
+                  <name>Client Authentication</name>
+                </value>
+              </entry>
+              <entry>
+                <key>container-queue-size</key>
+                <value>
+                  <name>container-queue-size</name>
+                </value>
+              </entry>
+            </descriptors>
+            <executionNode>ALL</executionNode>
+            <lossTolerant>false</lossTolerant>
+            <penaltyDuration>30 sec</penaltyDuration>
+            <properties>
+              <entry>
+                <key>Listening Port</key>
+                <value>80</value>
+              </entry>
+              <entry>
+                <key>Hostname</key>
+              </entry>
+              <entry>
+                <key>SSL Context Service</key>
+              </entry>
+              <entry>
+                <key>HTTP Context Map</key>
+                <value>d4c4c947-0158-1000-0000-000000000000</value>
+              </entry>
+              <entry>
+                <key>Allowed Paths</key>
+              </entry>
+              <entry>
+                <key>Default URL Character Set</key>
+                <value>UTF-8</value>
+              </entry>
+              <entry>
+                <key>Allow GET</key>
+                <value>true</value>
+              </entry>
+              <entry>
+                <key>Allow POST</key>
+                <value>true</value>
+              </entry>
+              <entry>
+                <key>Allow PUT</key>
+                <value>true</value>
+              </entry>
+              <entry>
+                <key>Allow DELETE</key>
+                <value>true</value>
+              </entry>
+              <entry>
+                <key>Allow HEAD</key>
+                <value>false</value>
+              </entry>
+              <entry>
+                <key>Allow OPTIONS</key>
+                <value>false</value>
+              </entry>
+              <entry>
+                <key>Additional HTTP Methods</key>
+              </entry>
+              <entry>
+                <key>Client Authentication</key>
+                <value>No Authentication</value>
+              </entry>
+              <entry>
+                <key>container-queue-size</key>
+                <value>50</value>
+              </entry>
+            </properties>
+            <runDurationMillis>0</runDurationMillis>
+            <schedulingPeriod>0 sec</schedulingPeriod>
+            <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+            <yieldDuration>1 sec</yieldDuration>
+          </config>
+          <name>HandleHttpRequest</name>
+          <relationships>
+            <autoTerminate>false</autoTerminate>
+            <name>success</name>
+          </relationships>
+          <style></style>
+          <type>org.apache.nifi.processors.standard.HandleHttpRequest</type>
+        </processors>
+        <processors>
+          <id>d522d82b-0158-1000-0000-000000000000</id>
+          <parentGroupId>d4c4b4e4-0158-1000-0000-000000000000</parentGroupId>
+          <position>
+            <x>-57.99999986476536</x>
+            <y>290.999983138124</y>
+          </position>
+          <config>
+            <bulletinLevel>WARN</bulletinLevel>
+            <comments></comments>
+            <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+            <descriptors>
+              <entry>
+                <key>HTTP Status Code</key>
+                <value>
+                  <name>HTTP Status Code</name>
+                </value>
+              </entry>
+              <entry>
+                <key>HTTP Context Map</key>
+                <value>
+                  <identifiesControllerService>org.apache.nifi.http.HttpContextMap</identifiesControllerService>
+                  <name>HTTP Context Map</name>
+                </value>
+              </entry>
+            </descriptors>
+            <executionNode>ALL</executionNode>
+            <lossTolerant>false</lossTolerant>
+            <penaltyDuration>30 sec</penaltyDuration>
+            <properties>
+              <entry>
+                <key>HTTP Status Code</key>
+                <value>200</value>
+              </entry>
+              <entry>
+                <key>HTTP Context Map</key>
+                <value>d4c4c947-0158-1000-0000-000000000000</value>
+              </entry>
+            </properties>
+            <runDurationMillis>0</runDurationMillis>
+            <schedulingPeriod>0 sec</schedulingPeriod>
+            <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+            <yieldDuration>1 sec</yieldDuration>
+          </config>
+          <name>HandleHttpResponse</name>
+          <relationships>
+            <autoTerminate>false</autoTerminate>
+            <name>failure</name>
+          </relationships>
+          <relationships>
+            <autoTerminate>false</autoTerminate>
+            <name>success</name>
+          </relationships>
+          <style></style>
+          <type>org.apache.nifi.processors.standard.HandleHttpResponse</type>
+        </processors>
+      </contents>
+      <name>middle</name>
+    </processGroups>
+    <processors>
+      <id>d5232ad7-0158-1000-0000-000000000000</id>
+      <parentGroupId>d193767e-0158-1000-0000-000000000000</parentGroupId>
+      <position>
+        <x>0.0</x>
+        <y>9.5862223843003</y>
+      </position>
+      <config>
+        <bulletinLevel>WARN</bulletinLevel>
+        <comments></comments>
+        <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+        <descriptors>
+          <entry>
+            <key>URL</key>
+            <value>
+              <name>URL</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Filename</key>
+            <value>
+              <name>Filename</name>
+            </value>
+          </entry>
+          <entry>
+            <key>SSL Context Service</key>
+            <value>
+              <identifiesControllerService>org.apache.nifi.ssl.SSLContextService</identifiesControllerService>
+              <name>SSL Context Service</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Username</key>
+            <value>
+              <name>Username</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Password</key>
+            <value>
+              <name>Password</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Connection Timeout</key>
+            <value>
+              <name>Connection Timeout</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Data Timeout</key>
+            <value>
+              <name>Data Timeout</name>
+            </value>
+          </entry>
+          <entry>
+            <key>User Agent</key>
+            <value>
+              <name>User Agent</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Accept Content-Type</key>
+            <value>
+              <name>Accept Content-Type</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Follow Redirects</key>
+            <value>
+              <name>Follow Redirects</name>
+            </value>
+          </entry>
+          <entry>
+            <key>redirect-cookie-policy</key>
+            <value>
+              <name>redirect-cookie-policy</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Proxy Host</key>
+            <value>
+              <name>Proxy Host</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Proxy Port</key>
+            <value>
+              <name>Proxy Port</name>
+            </value>
+          </entry>
+        </descriptors>
+        <executionNode>ALL</executionNode>
+        <lossTolerant>false</lossTolerant>
+        <penaltyDuration>30 sec</penaltyDuration>
+        <properties>
+          <entry>
+            <key>URL</key>
+            <value>https://localhost:8080/nifi</value>
+          </entry>
+          <entry>
+            <key>Filename</key>
+            <value>nifiCorrectGet</value>
+          </entry>
+          <entry>
+            <key>SSL Context Service</key>
+            <value>d4c47b18-0158-1000-0000-000000000000</value>
+          </entry>
+          <entry>
+            <key>Username</key>
+          </entry>
+          <entry>
+            <key>Password</key>
+          </entry>
+          <entry>
+            <key>Connection Timeout</key>
+            <value>30 sec</value>
+          </entry>
+          <entry>
+            <key>Data Timeout</key>
+            <value>30 sec</value>
+          </entry>
+          <entry>
+            <key>User Agent</key>
+          </entry>
+          <entry>
+            <key>Accept Content-Type</key>
+          </entry>
+          <entry>
+            <key>Follow Redirects</key>
+            <value>false</value>
+          </entry>
+          <entry>
+            <key>redirect-cookie-policy</key>
+            <value>default</value>
+          </entry>
+          <entry>
+            <key>Proxy Host</key>
+          </entry>
+          <entry>
+            <key>Proxy Port</key>
+          </entry>
+        </properties>
+        <runDurationMillis>0</runDurationMillis>
+        <schedulingPeriod>0 sec</schedulingPeriod>
+        <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+        <yieldDuration>1 sec</yieldDuration>
+      </config>
+      <name>GetHTTP</name>
+      <relationships>
+        <autoTerminate>false</autoTerminate>
+        <name>success</name>
+      </relationships>
+      <style></style>
+      <type>org.apache.nifi.processors.standard.GetHTTP</type>
+    </processors>
+    <processors>
+      <id>d5233667-0158-1000-0000-000000000000</id>
+      <parentGroupId>d193767e-0158-1000-0000-000000000000</parentGroupId>
+      <position>
+        <x>3.1954241180271765</x>
+        <y>238.0578704887564</y>
+      </position>
+      <config>
+        <bulletinLevel>WARN</bulletinLevel>
+        <comments></comments>
+        <concurrentlySchedulableTaskCount>1</concurrentlySchedulableTaskCount>
+        <descriptors>
+          <entry>
+            <key>Log Level</key>
+            <value>
+              <name>Log Level</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Log Payload</key>
+            <value>
+              <name>Log Payload</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Attributes to Log</key>
+            <value>
+              <name>Attributes to Log</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Attributes to Ignore</key>
+            <value>
+              <name>Attributes to Ignore</name>
+            </value>
+          </entry>
+          <entry>
+            <key>Log prefix</key>
+            <value>
+              <name>Log prefix</name>
+            </value>
+          </entry>
+        </descriptors>
+        <executionNode>ALL</executionNode>
+        <lossTolerant>false</lossTolerant>
+        <penaltyDuration>30 sec</penaltyDuration>
+        <properties>
+          <entry>
+            <key>Log Level</key>
+            <value>info</value>
+          </entry>
+          <entry>
+            <key>Log Payload</key>
+            <value>false</value>
+          </entry>
+          <entry>
+            <key>Attributes to Log</key>
+          </entry>
+          <entry>
+            <key>Attributes to Ignore</key>
+          </entry>
+          <entry>
+            <key>Log prefix</key>
+          </entry>
+        </properties>
+        <runDurationMillis>0</runDurationMillis>
+        <schedulingPeriod>0 sec</schedulingPeriod>
+        <schedulingStrategy>TIMER_DRIVEN</schedulingStrategy>
+        <yieldDuration>1 sec</yieldDuration>
+      </config>
+      <name>LogAttribute</name>
+      <relationships>
+        <autoTerminate>true</autoTerminate>
+        <name>success</name>
+      </relationships>
+      <style></style>
+      <type>org.apache.nifi.processors.standard.LogAttribute</type>
+    </processors>
+  </snippet>
+  <timestamp>12/06/2016 12:17:35 EST</timestamp>
+</template>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.yml
new file mode 100644
index 0000000..964b784
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/NestedControllerServices.yml
@@ -0,0 +1,290 @@
+# 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.
+
+MiNiFi Config Version: 3
+Flow Controller:
+  name: NestedControllerServices
+  comment: ''
+Core Properties:
+  flow controller graceful shutdown period: 10 sec
+  flow service write delay interval: 500 ms
+  administrative yield duration: 30 sec
+  bored yield duration: 10 millis
+  max concurrent threads: 1
+FlowFile Repository:
+  partitions: 256
+  checkpoint interval: 2 mins
+  always sync: false
+  Swap:
+    threshold: 20000
+    in period: 5 sec
+    in threads: 1
+    out period: 5 sec
+    out threads: 4
+Content Repository:
+  content claim max appendable size: 10 MB
+  content claim max flow files: 100
+  always sync: false
+Provenance Repository:
+  provenance rollover time: 1 min
+Component Status Repository:
+  buffer size: 1440
+  snapshot frequency: 1 min
+Security Properties:
+  keystore: ''
+  keystore type: ''
+  keystore password: ''
+  key password: ''
+  truststore: ''
+  truststore type: ''
+  truststore password: ''
+  ssl protocol: ''
+  Sensitive Props:
+    key:
+    algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL
+    provider: BC
+Processors:
+- id: d5232ad7-0158-1000-0000-000000000000
+  name: GetHTTP
+  class: org.apache.nifi.processors.standard.GetHTTP
+  max concurrent tasks: 1
+  scheduling strategy: TIMER_DRIVEN
+  scheduling period: 0 sec
+  penalization period: 30 sec
+  yield period: 1 sec
+  run duration nanos: 0
+  auto-terminated relationships list: []
+  Properties:
+    Accept Content-Type:
+    Connection Timeout: 30 sec
+    Data Timeout: 30 sec
+    Filename: nifiCorrectGet
+    Follow Redirects: 'false'
+    Password:
+    Proxy Host:
+    Proxy Port:
+    SSL Context Service: d4c47b18-0158-1000-0000-000000000000
+    URL: https://localhost:8080/nifi
+    User Agent:
+    Username:
+    redirect-cookie-policy: default
+- id: d5233667-0158-1000-0000-000000000000
+  name: LogAttribute
+  class: org.apache.nifi.processors.standard.LogAttribute
+  max concurrent tasks: 1
+  scheduling strategy: TIMER_DRIVEN
+  scheduling period: 0 sec
+  penalization period: 30 sec
+  yield period: 1 sec
+  run duration nanos: 0
+  auto-terminated relationships list:
+  - success
+  Properties:
+    Attributes to Ignore:
+    Attributes to Log:
+    Log Level: info
+    Log Payload: 'false'
+    Log prefix:
+Controller Services:
+- id: d4c47b18-0158-1000-0000-000000000000
+  name: test-root
+  type: org.apache.nifi.ssl.StandardSSLContextService
+  Properties:
+    Keystore Filename:
+    Keystore Password:
+    Keystore Type:
+    SSL Protocol:
+    Truststore Filename:
+    Truststore Password:
+    Truststore Type:
+    key-password:
+Process Groups:
+- id: d4c4b4e4-0158-1000-0000-000000000000
+  name: middle
+  Processors:
+  - id: d520168b-0158-1000-0000-000000000000
+    name: HandleHttpRequest
+    class: org.apache.nifi.processors.standard.HandleHttpRequest
+    max concurrent tasks: 1
+    scheduling strategy: TIMER_DRIVEN
+    scheduling period: 0 sec
+    penalization period: 30 sec
+    yield period: 1 sec
+    run duration nanos: 0
+    auto-terminated relationships list: []
+    Properties:
+      Additional HTTP Methods:
+      Allow DELETE: 'true'
+      Allow GET: 'true'
+      Allow HEAD: 'false'
+      Allow OPTIONS: 'false'
+      Allow POST: 'true'
+      Allow PUT: 'true'
+      Allowed Paths:
+      Client Authentication: No Authentication
+      Default URL Character Set: UTF-8
+      HTTP Context Map: d4c4c947-0158-1000-0000-000000000000
+      Hostname:
+      Listening Port: '80'
+      SSL Context Service:
+      container-queue-size: '50'
+  - id: d522d82b-0158-1000-0000-000000000000
+    name: HandleHttpResponse
+    class: org.apache.nifi.processors.standard.HandleHttpResponse
+    max concurrent tasks: 1
+    scheduling strategy: TIMER_DRIVEN
+    scheduling period: 0 sec
+    penalization period: 30 sec
+    yield period: 1 sec
+    run duration nanos: 0
+    auto-terminated relationships list: []
+    Properties:
+      HTTP Context Map: d4c4c947-0158-1000-0000-000000000000
+      HTTP Status Code: '200'
+  Controller Services:
+  - id: d4c4c947-0158-1000-0000-000000000000
+    name: test-middle
+    type: org.apache.nifi.http.StandardHttpContextMap
+    Properties:
+      Maximum Outstanding Requests:
+      Request Expiration:
+  Process Groups:
+  - id: d4c52c16-0158-1000-0000-000000000000
+    name: inner
+    Processors:
+    - id: d5205c43-0158-1000-0000-000000000000
+      name: DetectDuplicate
+      class: org.apache.nifi.processors.standard.DetectDuplicate
+      max concurrent tasks: 1
+      scheduling strategy: TIMER_DRIVEN
+      scheduling period: 0 sec
+      penalization period: 30 sec
+      yield period: 1 sec
+      run duration nanos: 0
+      auto-terminated relationships list: []
+      Properties:
+        Age Off Duration:
+        Cache Entry Identifier: ${hash.value}
+        Cache The Entry Identifier: 'true'
+        Distributed Cache Service: d4c5554d-0158-1000-0000-000000000000
+        FlowFile Description: test
+    - id: d5211ba3-0158-1000-0000-000000000000
+      name: GetHTTP
+      class: org.apache.nifi.processors.standard.GetHTTP
+      max concurrent tasks: 1
+      scheduling strategy: TIMER_DRIVEN
+      scheduling period: 0 sec
+      penalization period: 30 sec
+      yield period: 1 sec
+      run duration nanos: 0
+      auto-terminated relationships list: []
+      Properties:
+        Accept Content-Type:
+        Connection Timeout: 30 sec
+        Data Timeout: 30 sec
+        Filename: getLocalhost
+        Follow Redirects: 'false'
+        Password:
+        Proxy Host:
+        Proxy Port:
+        SSL Context Service:
+        URL: https://localhost:8080/
+        User Agent:
+        Username:
+        redirect-cookie-policy: default
+    - id: d521ab50-0158-1000-0000-000000000000
+      name: LogAttribute
+      class: org.apache.nifi.processors.standard.LogAttribute
+      max concurrent tasks: 1
+      scheduling strategy: TIMER_DRIVEN
+      scheduling period: 0 sec
+      penalization period: 30 sec
+      yield period: 1 sec
+      run duration nanos: 0
+      auto-terminated relationships list:
+      - success
+      Properties:
+        Attributes to Ignore:
+        Attributes to Log:
+        Log Level: info
+        Log Payload: 'false'
+        Log prefix:
+    Controller Services:
+    - id: d4c5554d-0158-1000-0000-000000000000
+      name: test-inner
+      type: org.apache.nifi.distributed.cache.client.DistributedMapCacheClientService
+      Properties:
+        Communications Timeout:
+        SSL Context Service: d4c47b18-0158-1000-0000-000000000000
+        Server Hostname: localhost
+        Server Port:
+    Process Groups: []
+    Input Ports: []
+    Output Ports: []
+    Funnels: []
+    Connections:
+    - id: d521c3e8-0158-1000-0000-000000000000
+      name: DetectDuplicate/failure/LogAttribute
+      source id: d5205c43-0158-1000-0000-000000000000
+      source relationship names:
+      - duplicate
+      - failure
+      - non-duplicate
+      destination id: d521ab50-0158-1000-0000-000000000000
+      max work queue size: 10000
+      max work queue data size: 1 GB
+      flowfile expiration: 0 sec
+      queue prioritizer class: ''
+    - id: d52147e4-0158-1000-0000-000000000000
+      name: GetHTTP/success/DetectDuplicate
+      source id: d5211ba3-0158-1000-0000-000000000000
+      source relationship names:
+      - success
+      destination id: d5205c43-0158-1000-0000-000000000000
+      max work queue size: 10000
+      max work queue data size: 1 GB
+      flowfile expiration: 0 sec
+      queue prioritizer class: ''
+    Remote Process Groups: []
+  Input Ports: []
+  Output Ports: []
+  Funnels: []
+  Connections:
+  - id: d522e203-0158-1000-0000-000000000000
+    name: HandleHttpRequest/success/HandleHttpResponse
+    source id: d520168b-0158-1000-0000-000000000000
+    source relationship names:
+    - success
+    destination id: d522d82b-0158-1000-0000-000000000000
+    max work queue size: 10000
+    max work queue data size: 1 GB
+    flowfile expiration: 0 sec
+    queue prioritizer class: ''
+  Remote Process Groups: []
+Input Ports: []
+Output Ports: []
+Funnels: []
+Connections:
+- id: d5234d12-0158-1000-0000-000000000000
+  name: GetHTTP/success/LogAttribute
+  source id: d5232ad7-0158-1000-0000-000000000000
+  source relationship names:
+  - success
+  destination id: d5233667-0158-1000-0000-000000000000
+  max work queue size: 10000
+  max work queue data size: 1 GB
+  flowfile expiration: 0 sec
+  queue prioritizer class: ''
+Remote Process Groups: []


[3/3] nifi-minifi git commit: MINIFI-154 Adding support for Controller Services

Posted by br...@apache.org.
MINIFI-154 Adding support for Controller Services

This closes #63

Signed-off-by: Bryan Rosander <br...@apache.org>


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

Branch: refs/heads/master
Commit: cbb2bdd8e00b3b96ef947db486a7608363c058a2
Parents: b028f5a
Author: Joseph Percivall <JP...@apache.org>
Authored: Wed Dec 7 13:59:58 2016 -0500
Committer: Bryan Rosander <br...@apache.org>
Committed: Fri Dec 9 14:50:46 2016 -0500

----------------------------------------------------------------------
 minifi-assembly/pom.xml                         |   14 +-
 minifi-bootstrap/pom.xml                        |    1 +
 .../bootstrap/util/ConfigTransformer.java       |   36 +-
 .../bootstrap/util/ConfigTransformerTest.java   |   16 +
 .../minifi/commons/schema/ConfigSchema.java     |    5 +-
 .../commons/schema/ControllerServiceSchema.java |   69 ++
 .../commons/schema/ProcessGroupSchema.java      |    9 +
 .../minifi/commons/schema/ProcessorSchema.java  |   12 +-
 .../schema/common/CommonPropertyKeys.java       |    9 +
 .../schema/serialization/SchemaLoader.java      |    2 +
 .../commons/schema/v1/ProcessorSchemaV1.java    |   10 +-
 .../commons/schema/v2/ConfigSchemaV2.java       |  242 ++++
 .../commons/schema/v2/ProcessGroupSchemaV2.java |  186 +++
 .../schema/serialization/SchemaLoaderTest.java  |   10 +-
 .../schema/v1/ProcessorSchemaV1Test.java        |   10 +-
 .../src/test/resources/config-minimal-v3.yml    |   38 +
 minifi-docs/src/main/assembly/dependencies.xml  |    7 +
 .../src/main/markdown/System_Admin_Guide.md     |   52 +-
 .../markdown/minifi-java-agent-quick-start.md   |   21 +-
 .../minifi-framework-nar/pom.xml                |    2 +
 .../minifi-provenance-reporting-nar/pom.xml     |    5 +-
 .../minifi-ssl-context-service-nar/pom.xml      |    6 +-
 .../src/main/resources/META-INF/NOTICE          |   19 -
 minifi-nar-bundles/minifi-standard-nar/pom.xml  |    5 +-
 .../minifi-standard-services-api-nar/pom.xml    |   94 --
 .../src/main/resources/META-INF/LICENSE         |  202 ----
 .../src/main/resources/META-INF/NOTICE          |   24 -
 minifi-nar-bundles/pom.xml                      |    1 -
 .../configuration/dto/ConfigSchemaFunction.java |   13 +-
 .../dto/ControllerServiceSchemaFunction.java    |   51 +
 .../dto/ProcessorSchemaFunction.java            |    9 +-
 .../toolkit/configuration/ConfigMainTest.java   |    5 +
 .../configuration/dto/ProcessorSchemaTest.java  |   15 +-
 .../src/test/resources/CsvToJson.yml            |    3 +-
 .../resources/DecompressionCircularFlow.yml     |    3 +-
 .../resources/InvokeHttpMiNiFiTemplateTest.yml  |    3 +-
 .../test/resources/MultipleRelationships.yml    |    3 +-
 .../test/resources/NestedControllerServices.xml | 1089 ++++++++++++++++++
 .../test/resources/NestedControllerServices.yml |  290 +++++
 .../ProcessGroupsAndRemoteProcessGroups.yml     |    5 +-
 ...aceTextExpressionLanguageCSVReformatting.yml |    3 +-
 .../src/test/resources/SimpleTailFileToRPG.yml  |    3 +-
 .../src/test/resources/StressTestFramework.yml  |    3 +-
 .../resources/StressTestFrameworkFunnel.yml     |    3 +-
 .../src/test/resources/config.yml               |    2 +-
 pom.xml                                         |   17 +-
 46 files changed, 2210 insertions(+), 417 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-assembly/pom.xml b/minifi-assembly/pom.xml
index f525d01..1ce48a7 100644
--- a/minifi-assembly/pom.xml
+++ b/minifi-assembly/pom.xml
@@ -166,8 +166,8 @@ limitations under the License.
             <artifactId>nifi-framework-core-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.nifi.minifi</groupId>
-            <artifactId>minifi-standard-services-api-nar</artifactId>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-services-api-nar</artifactId>
             <type>nar</type>
         </dependency>
         <dependency>
@@ -187,12 +187,6 @@ limitations under the License.
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-persistent-provenance-repository</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-site-to-site-reporting-task</artifactId>
-            <version>1.0.0</version>
-            <scope>compile</scope>
-        </dependency>
 
         <!-- Provided in NiFi so must include here too -->
         <dependency>
@@ -215,6 +209,10 @@ limitations under the License.
             <artifactId>commons-lang3</artifactId>
         </dependency>
         <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-bootstrap/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/pom.xml b/minifi-bootstrap/pom.xml
index 099f6e6..cb57cb2 100644
--- a/minifi-bootstrap/pom.xml
+++ b/minifi-bootstrap/pom.xml
@@ -80,6 +80,7 @@ limitations under the License.
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
+            <scope>provided</scope>
         </dependency>
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
index def5980..55d3285 100644
--- a/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
+++ b/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
@@ -25,6 +25,7 @@ import org.apache.nifi.minifi.commons.schema.ComponentStatusRepositorySchema;
 import org.apache.nifi.minifi.commons.schema.ConfigSchema;
 import org.apache.nifi.minifi.commons.schema.ConnectionSchema;
 import org.apache.nifi.minifi.commons.schema.ContentRepositorySchema;
+import org.apache.nifi.minifi.commons.schema.ControllerServiceSchema;
 import org.apache.nifi.minifi.commons.schema.CorePropertiesSchema;
 import org.apache.nifi.minifi.commons.schema.FlowControllerSchema;
 import org.apache.nifi.minifi.commons.schema.FlowFileRepositorySchema;
@@ -309,7 +310,11 @@ public final class ConfigTransformer {
 
             SecurityPropertiesSchema securityProperties = configSchema.getSecurityProperties();
             if (securityProperties.useSSL()) {
-                final Element controllerServicesNode = doc.createElement("controllerServices");
+                Element controllerServicesNode = doc.getElementById("controllerServices");
+                if(controllerServicesNode == null) {
+                    controllerServicesNode = doc.createElement("controllerServices");
+                }
+
                 rootNode.appendChild(controllerServicesNode);
                 addSSLControllerService(controllerServicesNode, securityProperties);
             }
@@ -356,6 +361,31 @@ public final class ConfigTransformer {
         }
     }
 
+    protected static void addControllerService(final Element element, ControllerServiceSchema controllerServiceSchema) throws ConfigurationChangeException {
+        try {
+            final Element serviceElement = element.getOwnerDocument().createElement("controllerService");
+            addTextElement(serviceElement, "id", controllerServiceSchema.getId());
+            addTextElement(serviceElement, "name", controllerServiceSchema.getName());
+            addTextElement(serviceElement, "comment", "");
+            addTextElement(serviceElement, "class", controllerServiceSchema.getServiceClass());
+
+            addTextElement(serviceElement, "enabled", "true");
+
+            Map<String, Object> attributes = controllerServiceSchema.getProperties();
+
+            addConfiguration(serviceElement, attributes);
+
+            String annotationData = controllerServiceSchema.getAnnotationData();
+            if(annotationData != null && !annotationData.isEmpty()) {
+                addTextElement(element, "annotationData", annotationData);
+            }
+
+            element.appendChild(serviceElement);
+        } catch (Exception e) {
+            throw new ConfigurationChangeException("Failed to parse the config YAML while trying to create an SSL Controller Service", e);
+        }
+    }
+
     protected static void addProcessGroup(Document doc, Element element, ProcessGroupSchema processGroupSchema, ParentGroupIdResolver parentGroupIdResolver) throws ConfigurationChangeException {
         try {
             String processGroupId = processGroupSchema.getId();
@@ -393,6 +423,10 @@ public final class ConfigTransformer {
             for (ConnectionSchema connectionConfig : processGroupSchema.getConnections()) {
                 addConnection(element, connectionConfig, parentGroupIdResolver);
             }
+
+            for (ControllerServiceSchema controllerServiceSchema : processGroupSchema.getControllerServices()) {
+                addControllerService(element, controllerServiceSchema);
+            }
         } catch (ConfigurationChangeException e) {
             throw e;
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformerTest.java
----------------------------------------------------------------------
diff --git a/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformerTest.java b/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformerTest.java
index 726b686..be88cb4 100644
--- a/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformerTest.java
+++ b/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformerTest.java
@@ -20,6 +20,7 @@ package org.apache.nifi.minifi.bootstrap.util;
 import org.apache.nifi.minifi.bootstrap.configuration.ConfigurationChangeException;
 import org.apache.nifi.minifi.commons.schema.ConfigSchema;
 import org.apache.nifi.minifi.commons.schema.ConnectionSchema;
+import org.apache.nifi.minifi.commons.schema.ControllerServiceSchema;
 import org.apache.nifi.minifi.commons.schema.FunnelSchema;
 import org.apache.nifi.minifi.commons.schema.PortSchema;
 import org.apache.nifi.minifi.commons.schema.ProcessGroupSchema;
@@ -140,6 +141,11 @@ public class ConfigTransformerTest {
         for (int i = 0; i < processorElements.getLength(); i++) {
             testProcessor((Element) processorElements.item(i), processGroupSchema.getProcessors().get(i));
         }
+        NodeList controllerServiceElements = (NodeList) xPathFactory.newXPath().evaluate("controllerService", element, XPathConstants.NODESET);
+        assertEquals(processGroupSchema.getControllerServices().size(), controllerServiceElements.getLength());
+        for (int i = 0; i < controllerServiceElements.getLength(); i++) {
+            testControllerService((Element) controllerServiceElements.item(i), processGroupSchema.getControllerServices().get(i));
+        }
 
         NodeList remoteProcessGroupElements = (NodeList) xPathFactory.newXPath().evaluate("remoteProcessGroup", element, XPathConstants.NODESET);
         assertEquals(processGroupSchema.getRemoteProcessGroups().size(), remoteProcessGroupElements.getLength());
@@ -188,10 +194,20 @@ public class ConfigTransformerTest {
         assertEquals(processorSchema.getYieldPeriod(), getText(element, "yieldPeriod"));
         assertEquals(processorSchema.getSchedulingStrategy(), getText(element, "schedulingStrategy"));
         assertEquals(processorSchema.getRunDurationNanos().toString(), getText(element, "runDurationNanos"));
+        assertEquals(processorSchema.getAnnotationData(), getText(element, "annotationData"));
 
         testProperties(element, processorSchema.getProperties());
     }
 
+    private void testControllerService(Element element, ControllerServiceSchema controllerServiceSchema) throws XPathExpressionException {
+        assertEquals(controllerServiceSchema.getId(), getText(element, "id"));
+        assertEquals(controllerServiceSchema.getName(), getText(element, "name"));
+        assertEquals(controllerServiceSchema.getServiceClass(), getText(element, "class"));
+        assertEquals(controllerServiceSchema.getAnnotationData(), getText(element, "annotationData"));
+
+        testProperties(element, controllerServiceSchema.getProperties());
+    }
+
     private void testRemoteProcessGroups(Element element, RemoteProcessGroupSchema remoteProcessingGroupSchema) throws XPathExpressionException {
         assertEquals(remoteProcessingGroupSchema.getId(), getText(element, "id"));
         assertEquals(remoteProcessingGroupSchema.getName(), getText(element, "name"));

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ConfigSchema.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ConfigSchema.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ConfigSchema.java
index 0f5d7e9..7a9bf09 100644
--- a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ConfigSchema.java
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ConfigSchema.java
@@ -42,7 +42,7 @@ import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PR
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SECURITY_PROPS_KEY;
 
 public class ConfigSchema extends BaseSchema implements WritableSchema, ConvertableSchema<ConfigSchema> {
-    public static final int CONFIG_VERSION = 2;
+    public static final int CONFIG_VERSION = 3;
     public static final String VERSION = "MiNiFi Config Version";
     public static final String FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_INPUT_PORT_IDS = "Found the following duplicate remote input port ids: ";
     public static final String FOUND_THE_FOLLOWING_DUPLICATE_INPUT_PORT_IDS = "Found the following duplicate input port ids: ";
@@ -52,6 +52,7 @@ public class ConfigSchema extends BaseSchema implements WritableSchema, Converta
     public static final String HAS_INVALID_SOURCE_ID = " has invalid source id ";
     public static final String HAS_INVALID_DESTINATION_ID = " has invalid destination id ";
     public static final String FOUND_THE_FOLLOWING_DUPLICATE_PROCESSOR_IDS = "Found the following duplicate processor ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_CONTROLLER_SERVICE_IDS = "Found the following duplicate controller service ids: ";
     public static final String FOUND_THE_FOLLOWING_DUPLICATE_CONNECTION_IDS = "Found the following duplicate connection ids: ";
     public static final String FOUND_THE_FOLLOWING_DUPLICATE_FUNNEL_IDS = "Found the following duplicate funnel ids: ";
     public static final String FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_PROCESS_GROUP_NAMES = "Found the following duplicate remote process group names: ";
@@ -101,6 +102,7 @@ public class ConfigSchema extends BaseSchema implements WritableSchema, Converta
         List<RemoteProcessGroupSchema> allRemoteProcessGroups = allProcessGroups.stream().flatMap(p -> p.getRemoteProcessGroups().stream()).collect(Collectors.toList());
 
         List<String> allProcessorIds = allProcessGroups.stream().flatMap(p -> p.getProcessors().stream()).map(ProcessorSchema::getId).collect(Collectors.toList());
+        List<String> allControllerServiceIds = allProcessGroups.stream().flatMap(p -> p.getControllerServices().stream()).map(ControllerServiceSchema::getId).collect(Collectors.toList());
         List<String> allFunnelIds = allProcessGroups.stream().flatMap(p -> p.getFunnels().stream()).map(FunnelSchema::getId).collect(Collectors.toList());
         List<String> allConnectionIds = allConnectionSchemas.stream().map(ConnectionSchema::getId).collect(Collectors.toList());
         List<String> allRemoteProcessGroupNames = allRemoteProcessGroups.stream().map(RemoteProcessGroupSchema::getName).collect(Collectors.toList());
@@ -110,6 +112,7 @@ public class ConfigSchema extends BaseSchema implements WritableSchema, Converta
         List<String> allOutputPortIds = allProcessGroups.stream().flatMap(p -> p.getOutputPortSchemas().stream()).map(PortSchema::getId).collect(Collectors.toList());
 
         checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_PROCESSOR_IDS, allProcessorIds);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_CONTROLLER_SERVICE_IDS, allControllerServiceIds);
         checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_FUNNEL_IDS, allFunnelIds);
         checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_CONNECTION_IDS, allConnectionIds);
         checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_PROCESS_GROUP_NAMES, allRemoteProcessGroupNames);

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ControllerServiceSchema.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ControllerServiceSchema.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ControllerServiceSchema.java
new file mode 100644
index 0000000..cc3a85c
--- /dev/null
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ControllerServiceSchema.java
@@ -0,0 +1,69 @@
+/*
+ * 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.minifi.commons.schema;
+
+import org.apache.nifi.minifi.commons.schema.common.BaseSchemaWithIdAndName;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ANNOTATION_DATA_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.DEFAULT_PROPERTIES;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.TYPE_KEY;
+
+public class ControllerServiceSchema extends BaseSchemaWithIdAndName {
+
+    private Map<String, Object> properties = DEFAULT_PROPERTIES;
+    private String annotationData = "";
+    private String serviceClass;
+
+    public ControllerServiceSchema(Map map) {
+        super(map, "Controller Service(id: {id}, name: {name})");
+        String wrapperName = getWrapperName();
+        serviceClass = getRequiredKeyAsType(map, TYPE_KEY, String.class, wrapperName);
+        properties = getOptionalKeyAsType(map, PROPERTIES_KEY, Map.class, wrapperName, DEFAULT_PROPERTIES);
+        annotationData = getOptionalKeyAsType(map, ANNOTATION_DATA_KEY, String.class, wrapperName, "");
+    }
+
+
+    @Override
+    public Map<String, Object> toMap() {
+        Map<String, Object> result = super.toMap();
+        result.put(TYPE_KEY, serviceClass);
+        result.put(PROPERTIES_KEY, new TreeMap<>(properties));
+
+        if(annotationData != null && !annotationData.isEmpty()) {
+            result.put(ANNOTATION_DATA_KEY, annotationData);
+        }
+
+        return result;
+    }
+
+    public String getAnnotationData() {
+        return annotationData;
+    }
+
+    public String getServiceClass() {
+        return serviceClass;
+    }
+
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessGroupSchema.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessGroupSchema.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessGroupSchema.java
index 028f666..56e6af8 100644
--- a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessGroupSchema.java
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessGroupSchema.java
@@ -31,6 +31,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CONNECTIONS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CONTROLLER_SERVICES_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.FUNNELS_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.INPUT_PORTS_KEY;
@@ -46,6 +47,7 @@ public class ProcessGroupSchema extends BaseSchemaWithIdAndName implements Writa
 
     private String comment;
     private List<ProcessorSchema> processors;
+    private List<ControllerServiceSchema> controllerServiceSchemas;
     private List<FunnelSchema> funnels;
     private List<ConnectionSchema> connections;
     private List<RemoteProcessGroupSchema> remoteProcessGroups;
@@ -57,6 +59,7 @@ public class ProcessGroupSchema extends BaseSchemaWithIdAndName implements Writa
         super(map, wrapperName);
 
         processors = getOptionalKeyAsList(map, PROCESSORS_KEY, ProcessorSchema::new, wrapperName);
+        controllerServiceSchemas = getOptionalKeyAsList(map, CONTROLLER_SERVICES_KEY, ControllerServiceSchema::new, wrapperName);
         funnels = getOptionalKeyAsList(map, FUNNELS_KEY, FunnelSchema::new, wrapperName);
         remoteProcessGroups = getOptionalKeyAsList(map, REMOTE_PROCESS_GROUPS_KEY, RemoteProcessGroupSchema::new, wrapperName);
         connections = getOptionalKeyAsList(map, CONNECTIONS_KEY, ConnectionSchema::new, wrapperName);
@@ -83,6 +86,7 @@ public class ProcessGroupSchema extends BaseSchemaWithIdAndName implements Writa
         connections.stream().filter(c -> funnelIds.contains(c.getSourceId())).forEachOrdered(c -> c.setNeedsSourceRelationships(false));
 
         addIssuesIfNotNull(processors);
+        addIssuesIfNotNull(controllerServiceSchemas);
         addIssuesIfNotNull(remoteProcessGroups);
         addIssuesIfNotNull(processGroupSchemas);
         addIssuesIfNotNull(funnels);
@@ -97,6 +101,7 @@ public class ProcessGroupSchema extends BaseSchemaWithIdAndName implements Writa
         }
         StringUtil.doIfNotNullOrEmpty(getName(), name -> result.put(NAME_KEY, name));
         putListIfNotNull(result, PROCESSORS_KEY, processors);
+        putListIfNotNull(result, CONTROLLER_SERVICES_KEY, controllerServiceSchemas);
         putListIfNotNull(result, PROCESS_GROUPS_KEY, processGroupSchemas);
         putListIfNotNull(result, INPUT_PORTS_KEY, inputPortSchemas);
         putListIfNotNull(result, OUTPUT_PORTS_KEY, outputPortSchemas);
@@ -110,6 +115,10 @@ public class ProcessGroupSchema extends BaseSchemaWithIdAndName implements Writa
         return processors;
     }
 
+    public List<ControllerServiceSchema> getControllerServices() {
+        return controllerServiceSchemas;
+    }
+
     public List<FunnelSchema> getFunnels() {
         return funnels;
     }

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessorSchema.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessorSchema.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessorSchema.java
index 6f2ff8e..00eb9c5 100644
--- a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessorSchema.java
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/ProcessorSchema.java
@@ -25,25 +25,25 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ANNOTATION_DATA_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CLASS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.DEFAULT_PROPERTIES;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.MAX_CONCURRENT_TASKS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_PERIOD_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_STRATEGY_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.YIELD_PERIOD_KEY;
 
 public class ProcessorSchema extends BaseSchemaWithIdAndName {
-    public static final String CLASS_KEY = "class";
     public static final String PENALIZATION_PERIOD_KEY = "penalization period";
     public static final String RUN_DURATION_NANOS_KEY = "run duration nanos";
     public static final String AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY = "auto-terminated relationships list";
-    public static final String PROCESSOR_PROPS_KEY = "Properties";
-    public static final String ANNOTATION_DATA_KEY = "annotation data";
 
     public static final int DEFAULT_MAX_CONCURRENT_TASKS = 1;
     public static final String DEFAULT_PENALIZATION_PERIOD = "30 sec";
     public static final String DEFAULT_YIELD_DURATION = "1 sec";
     public static final long DEFAULT_RUN_DURATION_NANOS = 0;
     public static final List<String> DEFAULT_AUTO_TERMINATED_RELATIONSHIPS_LIST = Collections.emptyList();
-    public static final Map<String, Object> DEFAULT_PROPERTIES = Collections.emptyMap();
     public static final String IT_IS_NOT_A_VALID_SCHEDULING_STRATEGY = "it is not a valid scheduling strategy";
 
     private String processorClass;
@@ -72,7 +72,7 @@ public class ProcessorSchema extends BaseSchemaWithIdAndName {
         yieldPeriod = getOptionalKeyAsType(map, YIELD_PERIOD_KEY, String.class, wrapperName, DEFAULT_YIELD_DURATION);
         runDurationNanos = getOptionalKeyAsType(map, RUN_DURATION_NANOS_KEY, Number.class, wrapperName, DEFAULT_RUN_DURATION_NANOS);
         autoTerminatedRelationshipsList = getOptionalKeyAsType(map, AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, List.class, wrapperName, DEFAULT_AUTO_TERMINATED_RELATIONSHIPS_LIST);
-        properties = getOptionalKeyAsType(map, PROCESSOR_PROPS_KEY, Map.class, wrapperName, DEFAULT_PROPERTIES);
+        properties = getOptionalKeyAsType(map, PROPERTIES_KEY, Map.class, wrapperName, DEFAULT_PROPERTIES);
 
         annotationData = getOptionalKeyAsType(map, ANNOTATION_DATA_KEY, String.class, wrapperName, "");
     }
@@ -97,7 +97,7 @@ public class ProcessorSchema extends BaseSchemaWithIdAndName {
         result.put(YIELD_PERIOD_KEY, yieldPeriod);
         result.put(RUN_DURATION_NANOS_KEY, runDurationNanos);
         result.put(AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, autoTerminatedRelationshipsList);
-        result.put(PROCESSOR_PROPS_KEY, new TreeMap<>(properties));
+        result.put(PROPERTIES_KEY, new TreeMap<>(properties));
 
         if(annotationData != null && !annotationData.isEmpty()) {
             result.put(ANNOTATION_DATA_KEY, annotationData);

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/common/CommonPropertyKeys.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/common/CommonPropertyKeys.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/common/CommonPropertyKeys.java
index 4efb258..05ad607 100644
--- a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/common/CommonPropertyKeys.java
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/common/CommonPropertyKeys.java
@@ -17,6 +17,9 @@
 
 package org.apache.nifi.minifi.commons.schema.common;
 
+import java.util.Collections;
+import java.util.Map;
+
 public class CommonPropertyKeys {
     public static final String CORE_PROPS_KEY = "Core Properties";
     public static final String FLOWFILE_REPO_KEY = "FlowFile Repository";
@@ -32,6 +35,7 @@ public class CommonPropertyKeys {
     public static final String REMOTE_PROCESS_GROUPS_KEY = "Remote Process Groups";
     public static final String INPUT_PORTS_KEY = "Input Ports";
     public static final String OUTPUT_PORTS_KEY = "Output Ports";
+    public static final String CONTROLLER_SERVICES_KEY = "Controller Services";
     public static final String FUNNELS_KEY = "Funnels";
     public static final String PROVENANCE_REPO_KEY = "Provenance Repository";
 
@@ -46,7 +50,12 @@ public class CommonPropertyKeys {
     public static final String SCHEDULING_STRATEGY_KEY = "scheduling strategy";
     public static final String SCHEDULING_PERIOD_KEY = "scheduling period";
     public static final String USE_COMPRESSION_KEY = "use compression";
+    public static final String PROPERTIES_KEY = "Properties";
+    public static final String CLASS_KEY = "class";
+    public static final String TYPE_KEY = "type";
+    public static final String ANNOTATION_DATA_KEY = "annotation data";
 
+    public static final Map<String, Object> DEFAULT_PROPERTIES = Collections.emptyMap();
     private CommonPropertyKeys() {
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoader.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoader.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoader.java
index 331f40d..d3eb766 100644
--- a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoader.java
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoader.java
@@ -22,6 +22,7 @@ import org.apache.nifi.minifi.commons.schema.common.ConvertableSchema;
 import org.apache.nifi.minifi.commons.schema.common.StringUtil;
 import org.apache.nifi.minifi.commons.schema.exception.SchemaLoaderException;
 import org.apache.nifi.minifi.commons.schema.v1.ConfigSchemaV1;
+import org.apache.nifi.minifi.commons.schema.v2.ConfigSchemaV2;
 import org.yaml.snakeyaml.Yaml;
 import org.yaml.snakeyaml.error.YAMLException;
 
@@ -40,6 +41,7 @@ public class SchemaLoader {
         result.put(String.valueOf((Object) null), ConfigSchemaV1::new);
         result.put("", ConfigSchemaV1::new);
         result.put(Integer.toString(ConfigSchemaV1.CONFIG_VERSION), ConfigSchemaV1::new);
+        result.put(Integer.toString(ConfigSchemaV2.CONFIG_VERSION), ConfigSchemaV2::new);
         result.put(Integer.toString(ConfigSchema.CONFIG_VERSION), ConfigSchema::new);
         return result;
     }

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1.java
index d64c98b..42b4050 100644
--- a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1.java
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1.java
@@ -28,21 +28,21 @@ import java.util.List;
 import java.util.Map;
 
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY;
-import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.CLASS_KEY;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_AUTO_TERMINATED_RELATIONSHIPS_LIST;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_MAX_CONCURRENT_TASKS;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_PENALIZATION_PERIOD;
-import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_PROPERTIES;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_RUN_DURATION_NANOS;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_YIELD_DURATION;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.IT_IS_NOT_A_VALID_SCHEDULING_STRATEGY;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.PENALIZATION_PERIOD_KEY;
-import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.PROCESSOR_PROPS_KEY;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.RUN_DURATION_NANOS_KEY;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.isSchedulingStrategy;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CLASS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.DEFAULT_PROPERTIES;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.MAX_CONCURRENT_TASKS_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROCESSORS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_PERIOD_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_STRATEGY_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.YIELD_PERIOD_KEY;
@@ -73,7 +73,7 @@ public class ProcessorSchemaV1 extends BaseSchema implements ConvertableSchema<P
         yieldPeriod = getOptionalKeyAsType(map, YIELD_PERIOD_KEY, String.class, PROCESSORS_KEY, DEFAULT_YIELD_DURATION);
         runDurationNanos = getOptionalKeyAsType(map, RUN_DURATION_NANOS_KEY, Number.class, PROCESSORS_KEY, DEFAULT_RUN_DURATION_NANOS);
         autoTerminatedRelationshipsList = getOptionalKeyAsType(map, AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, List.class, PROCESSORS_KEY, DEFAULT_AUTO_TERMINATED_RELATIONSHIPS_LIST);
-        properties = getOptionalKeyAsType(map, PROCESSOR_PROPS_KEY, Map.class, PROCESSORS_KEY, DEFAULT_PROPERTIES);
+        properties = getOptionalKeyAsType(map, PROPERTIES_KEY, Map.class, PROCESSORS_KEY, DEFAULT_PROPERTIES);
     }
 
     @Override
@@ -88,7 +88,7 @@ public class ProcessorSchemaV1 extends BaseSchema implements ConvertableSchema<P
         map.put(YIELD_PERIOD_KEY, yieldPeriod);
         map.put(RUN_DURATION_NANOS_KEY, runDurationNanos);
         map.put(AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, autoTerminatedRelationshipsList);
-        map.put(PROCESSOR_PROPS_KEY, new HashMap<>(properties));
+        map.put(PROPERTIES_KEY, new HashMap<>(properties));
         return new ProcessorSchema(map);
     }
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ConfigSchemaV2.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ConfigSchemaV2.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ConfigSchemaV2.java
new file mode 100644
index 0000000..20a9da2
--- /dev/null
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ConfigSchemaV2.java
@@ -0,0 +1,242 @@
+/*
+ * 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.minifi.commons.schema.v2;
+
+import org.apache.nifi.minifi.commons.schema.ComponentStatusRepositorySchema;
+import org.apache.nifi.minifi.commons.schema.ConfigSchema;
+import org.apache.nifi.minifi.commons.schema.ConnectionSchema;
+import org.apache.nifi.minifi.commons.schema.ContentRepositorySchema;
+import org.apache.nifi.minifi.commons.schema.CorePropertiesSchema;
+import org.apache.nifi.minifi.commons.schema.FlowControllerSchema;
+import org.apache.nifi.minifi.commons.schema.FlowFileRepositorySchema;
+import org.apache.nifi.minifi.commons.schema.FunnelSchema;
+import org.apache.nifi.minifi.commons.schema.PortSchema;
+import org.apache.nifi.minifi.commons.schema.ProcessorSchema;
+import org.apache.nifi.minifi.commons.schema.ProvenanceReportingSchema;
+import org.apache.nifi.minifi.commons.schema.ProvenanceRepositorySchema;
+import org.apache.nifi.minifi.commons.schema.RemoteInputPortSchema;
+import org.apache.nifi.minifi.commons.schema.RemoteProcessGroupSchema;
+import org.apache.nifi.minifi.commons.schema.SecurityPropertiesSchema;
+import org.apache.nifi.minifi.commons.schema.common.BaseSchema;
+import org.apache.nifi.minifi.commons.schema.common.ConvertableSchema;
+import org.apache.nifi.minifi.commons.schema.common.StringUtil;
+import org.apache.nifi.minifi.commons.schema.common.WritableSchema;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.COMPONENT_STATUS_REPO_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CONTENT_REPO_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CORE_PROPS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.FLOWFILE_REPO_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.FLOW_CONTROLLER_PROPS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROVENANCE_REPORTING_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROVENANCE_REPO_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SECURITY_PROPS_KEY;
+
+public class ConfigSchemaV2 extends BaseSchema implements WritableSchema, ConvertableSchema<ConfigSchema> {
+    public static final int CONFIG_VERSION = 2;
+    public static final String VERSION = "MiNiFi Config Version";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_INPUT_PORT_IDS = "Found the following duplicate remote input port ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_INPUT_PORT_IDS = "Found the following duplicate input port ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_OUTPUT_PORT_IDS = "Found the following duplicate output port ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_IDS = "Found the following ids that occur both in more than one Processor(s), Input Port(s), Output Port(s) and/or Remote Input Port(s): ";
+    public static final String CONNECTION_WITH_ID = "Connection with id ";
+    public static final String HAS_INVALID_SOURCE_ID = " has invalid source id ";
+    public static final String HAS_INVALID_DESTINATION_ID = " has invalid destination id ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_PROCESSOR_IDS = "Found the following duplicate processor ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_CONNECTION_IDS = "Found the following duplicate connection ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_FUNNEL_IDS = "Found the following duplicate funnel ids: ";
+    public static final String FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_PROCESS_GROUP_NAMES = "Found the following duplicate remote process group names: ";
+    public static String TOP_LEVEL_NAME = "top level";
+    private FlowControllerSchema flowControllerProperties;
+    private CorePropertiesSchema coreProperties;
+    private FlowFileRepositorySchema flowfileRepositoryProperties;
+    private ContentRepositorySchema contentRepositoryProperties;
+    private ComponentStatusRepositorySchema componentStatusRepositoryProperties;
+    private SecurityPropertiesSchema securityProperties;
+    private ProcessGroupSchemaV2 processGroupSchema;
+    private ProvenanceReportingSchema provenanceReportingProperties;
+
+    private ProvenanceRepositorySchema provenanceRepositorySchema;
+
+    public ConfigSchemaV2(Map map) {
+        this(map, Collections.emptyList());
+    }
+
+    public ConfigSchemaV2(Map map, List<String> validationIssues) {
+        validationIssues.stream().forEach(this::addValidationIssue);
+        flowControllerProperties = getMapAsType(map, FLOW_CONTROLLER_PROPS_KEY, FlowControllerSchema.class, TOP_LEVEL_NAME, true);
+
+        coreProperties = getMapAsType(map, CORE_PROPS_KEY, CorePropertiesSchema.class, TOP_LEVEL_NAME, false);
+        flowfileRepositoryProperties = getMapAsType(map, FLOWFILE_REPO_KEY, FlowFileRepositorySchema.class, TOP_LEVEL_NAME, false);
+        contentRepositoryProperties = getMapAsType(map, CONTENT_REPO_KEY, ContentRepositorySchema.class, TOP_LEVEL_NAME, false);
+        provenanceRepositorySchema = getMapAsType(map, PROVENANCE_REPO_KEY, ProvenanceRepositorySchema.class, TOP_LEVEL_NAME, false);
+        componentStatusRepositoryProperties = getMapAsType(map, COMPONENT_STATUS_REPO_KEY, ComponentStatusRepositorySchema.class, TOP_LEVEL_NAME, false);
+        securityProperties = getMapAsType(map, SECURITY_PROPS_KEY, SecurityPropertiesSchema.class, TOP_LEVEL_NAME, false);
+
+        processGroupSchema = new ProcessGroupSchemaV2(map, TOP_LEVEL_NAME);
+
+        provenanceReportingProperties = getMapAsType(map, PROVENANCE_REPORTING_KEY, ProvenanceReportingSchema.class, TOP_LEVEL_NAME, false, false);
+
+        addIssuesIfNotNull(flowControllerProperties);
+        addIssuesIfNotNull(coreProperties);
+        addIssuesIfNotNull(flowfileRepositoryProperties);
+        addIssuesIfNotNull(contentRepositoryProperties);
+        addIssuesIfNotNull(componentStatusRepositoryProperties);
+        addIssuesIfNotNull(securityProperties);
+        addIssuesIfNotNull(processGroupSchema);
+        addIssuesIfNotNull(provenanceReportingProperties);
+        addIssuesIfNotNull(provenanceRepositorySchema);
+
+        List<ProcessGroupSchemaV2> allProcessGroups = getAllProcessGroups(processGroupSchema);
+        List<ConnectionSchema> allConnectionSchemas = allProcessGroups.stream().flatMap(p -> p.getConnections().stream()).collect(Collectors.toList());
+        List<RemoteProcessGroupSchema> allRemoteProcessGroups = allProcessGroups.stream().flatMap(p -> p.getRemoteProcessGroups().stream()).collect(Collectors.toList());
+
+        List<String> allProcessorIds = allProcessGroups.stream().flatMap(p -> p.getProcessors().stream()).map(ProcessorSchema::getId).collect(Collectors.toList());
+        List<String> allFunnelIds = allProcessGroups.stream().flatMap(p -> p.getFunnels().stream()).map(FunnelSchema::getId).collect(Collectors.toList());
+        List<String> allConnectionIds = allConnectionSchemas.stream().map(ConnectionSchema::getId).collect(Collectors.toList());
+        List<String> allRemoteProcessGroupNames = allRemoteProcessGroups.stream().map(RemoteProcessGroupSchema::getName).collect(Collectors.toList());
+        List<String> allRemoteInputPortIds = allRemoteProcessGroups.stream().filter(r -> r.getInputPorts() != null)
+                .flatMap(r -> r.getInputPorts().stream()).map(RemoteInputPortSchema::getId).collect(Collectors.toList());
+        List<String> allInputPortIds = allProcessGroups.stream().flatMap(p -> p.getInputPortSchemas().stream()).map(PortSchema::getId).collect(Collectors.toList());
+        List<String> allOutputPortIds = allProcessGroups.stream().flatMap(p -> p.getOutputPortSchemas().stream()).map(PortSchema::getId).collect(Collectors.toList());
+
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_PROCESSOR_IDS, allProcessorIds);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_FUNNEL_IDS, allFunnelIds);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_CONNECTION_IDS, allConnectionIds);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_PROCESS_GROUP_NAMES, allRemoteProcessGroupNames);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_REMOTE_INPUT_PORT_IDS, allRemoteInputPortIds);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_INPUT_PORT_IDS, allInputPortIds);
+        checkForDuplicates(this::addValidationIssue, FOUND_THE_FOLLOWING_DUPLICATE_OUTPUT_PORT_IDS, allOutputPortIds);
+
+        // Potential connection sources and destinations need to have unique ids
+        OverlapResults<String> overlapResults = findOverlap(new HashSet<>(allProcessorIds), new HashSet<>(allRemoteInputPortIds), new HashSet<>(allInputPortIds), new HashSet<>(allOutputPortIds),
+                new HashSet<>(allFunnelIds));
+        if (overlapResults.duplicates.size() > 0) {
+            addValidationIssue(FOUND_THE_FOLLOWING_DUPLICATE_IDS + overlapResults.duplicates.stream().sorted().collect(Collectors.joining(", ")));
+        }
+
+        allConnectionSchemas.forEach(c -> {
+            String destinationId = c.getDestinationId();
+            if (!StringUtil.isNullOrEmpty(destinationId) && !overlapResults.seen.contains(destinationId)) {
+                addValidationIssue(CONNECTION_WITH_ID + c.getId() + HAS_INVALID_DESTINATION_ID + destinationId);
+            }
+            String sourceId = c.getSourceId();
+            if (!StringUtil.isNullOrEmpty(sourceId) && !overlapResults.seen.contains(sourceId)) {
+                addValidationIssue(CONNECTION_WITH_ID + c.getId() + HAS_INVALID_SOURCE_ID + sourceId);
+            }
+        });
+    }
+
+    protected static <T> OverlapResults<T> findOverlap(Collection<T>... collections) {
+        Set<T> seen = new HashSet<>();
+        return new OverlapResults<>(seen, Arrays.stream(collections).flatMap(c -> c.stream()).sequential().filter(s -> !seen.add(s)).collect(Collectors.toSet()));
+    }
+
+    public static List<ProcessGroupSchemaV2> getAllProcessGroups(ProcessGroupSchemaV2 processGroupSchema) {
+        List<ProcessGroupSchemaV2> result = new ArrayList<>();
+        addProcessGroups(processGroupSchema, result);
+        return result;
+    }
+
+    private static void addProcessGroups(ProcessGroupSchemaV2 processGroupSchema, List<ProcessGroupSchemaV2> result) {
+        result.add(processGroupSchema);
+        processGroupSchema.getProcessGroupSchemas().forEach(p -> addProcessGroups(p, result));
+    }
+
+    public Map<String, Object> toMap() {
+        Map<String, Object> result = mapSupplier.get();
+        result.put(VERSION, getVersion());
+        putIfNotNull(result, FLOW_CONTROLLER_PROPS_KEY, flowControllerProperties);
+        putIfNotNull(result, CORE_PROPS_KEY, coreProperties);
+        putIfNotNull(result, FLOWFILE_REPO_KEY, flowfileRepositoryProperties);
+        putIfNotNull(result, CONTENT_REPO_KEY, contentRepositoryProperties);
+        putIfNotNull(result, PROVENANCE_REPO_KEY, provenanceRepositorySchema);
+        putIfNotNull(result, COMPONENT_STATUS_REPO_KEY, componentStatusRepositoryProperties);
+        putIfNotNull(result, SECURITY_PROPS_KEY, securityProperties);
+        result.putAll(processGroupSchema.toMap());
+        putIfNotNull(result, PROVENANCE_REPORTING_KEY, provenanceReportingProperties);
+        return result;
+    }
+
+    public FlowControllerSchema getFlowControllerProperties() {
+        return flowControllerProperties;
+    }
+
+    public CorePropertiesSchema getCoreProperties() {
+        return coreProperties;
+    }
+
+    public FlowFileRepositorySchema getFlowfileRepositoryProperties() {
+        return flowfileRepositoryProperties;
+    }
+
+    public ContentRepositorySchema getContentRepositoryProperties() {
+        return contentRepositoryProperties;
+    }
+
+    public SecurityPropertiesSchema getSecurityProperties() {
+        return securityProperties;
+    }
+
+    public ProcessGroupSchemaV2 getProcessGroupSchema() {
+        return processGroupSchema;
+    }
+
+    public ProvenanceReportingSchema getProvenanceReportingProperties() {
+        return provenanceReportingProperties;
+    }
+
+    public ComponentStatusRepositorySchema getComponentStatusRepositoryProperties() {
+        return componentStatusRepositoryProperties;
+    }
+
+    public ProvenanceRepositorySchema getProvenanceRepositorySchema() {
+        return provenanceRepositorySchema;
+    }
+
+    @Override
+    public int getVersion() {
+        return CONFIG_VERSION;
+    }
+
+    @Override
+    public ConfigSchema convert() {
+        Map<String, Object> map = this.toMap();
+        List<String> validationIssues = getValidationIssues();
+        return new ConfigSchema(map, validationIssues);
+    }
+
+    private static class OverlapResults<T> {
+        private final Set<T> seen;
+        private final Set<T> duplicates;
+
+        private OverlapResults(Set<T> seen, Set<T> duplicates) {
+            this.seen = seen;
+            this.duplicates = duplicates;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ProcessGroupSchemaV2.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ProcessGroupSchemaV2.java b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ProcessGroupSchemaV2.java
new file mode 100644
index 0000000..a9f0449
--- /dev/null
+++ b/minifi-commons/minifi-commons-schema/src/main/java/org/apache/nifi/minifi/commons/schema/v2/ProcessGroupSchemaV2.java
@@ -0,0 +1,186 @@
+/*
+ *
+ *  * 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.minifi.commons.schema.v2;
+
+import org.apache.nifi.minifi.commons.schema.ConfigSchema;
+import org.apache.nifi.minifi.commons.schema.ConnectionSchema;
+import org.apache.nifi.minifi.commons.schema.FunnelSchema;
+import org.apache.nifi.minifi.commons.schema.PortSchema;
+import org.apache.nifi.minifi.commons.schema.ProcessGroupSchema;
+import org.apache.nifi.minifi.commons.schema.ProcessorSchema;
+import org.apache.nifi.minifi.commons.schema.RemoteProcessGroupSchema;
+import org.apache.nifi.minifi.commons.schema.common.BaseSchemaWithIdAndName;
+import org.apache.nifi.minifi.commons.schema.common.ConvertableSchema;
+import org.apache.nifi.minifi.commons.schema.common.StringUtil;
+import org.apache.nifi.minifi.commons.schema.common.WritableSchema;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CONNECTIONS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CONTROLLER_SERVICES_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.DEFAULT_PROPERTIES;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.FUNNELS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.INPUT_PORTS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.OUTPUT_PORTS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROCESSORS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.REMOTE_PROCESS_GROUPS_KEY;
+
+public class ProcessGroupSchemaV2 extends BaseSchemaWithIdAndName implements WritableSchema, ConvertableSchema<ProcessGroupSchema> {
+
+    public static final String PROCESS_GROUPS_KEY = "Process Groups";
+    public static final String ID_DEFAULT = "Root-Group";
+
+    private String comment;
+    private List<ProcessorSchema> processors;
+    private List<FunnelSchema> funnels;
+    private List<ConnectionSchema> connections;
+    private List<RemoteProcessGroupSchema> remoteProcessGroups;
+    private List<ProcessGroupSchemaV2> processGroupSchemas;
+    private List<PortSchema> inputPortSchemas;
+    private List<PortSchema> outputPortSchemas;
+
+    public ProcessGroupSchemaV2(Map map, String wrapperName) {
+        super(map, wrapperName);
+
+        processors = getOptionalKeyAsList(map, PROCESSORS_KEY, ProcessorSchema::new, wrapperName);
+        funnels = getOptionalKeyAsList(map, FUNNELS_KEY, FunnelSchema::new, wrapperName);
+        remoteProcessGroups = getOptionalKeyAsList(map, REMOTE_PROCESS_GROUPS_KEY, RemoteProcessGroupSchema::new, wrapperName);
+        connections = getOptionalKeyAsList(map, CONNECTIONS_KEY, ConnectionSchema::new, wrapperName);
+        inputPortSchemas = getOptionalKeyAsList(map, INPUT_PORTS_KEY, m -> new PortSchema(m, "InputPort(id: {id}, name: {name})"), wrapperName);
+        outputPortSchemas = getOptionalKeyAsList(map, OUTPUT_PORTS_KEY, m -> new PortSchema(m, "OutputPort(id: {id}, name: {name})"), wrapperName);
+        processGroupSchemas = getOptionalKeyAsList(map, PROCESS_GROUPS_KEY, m -> new ProcessGroupSchemaV2(m, "ProcessGroup(id: {id}, name: {name})"), wrapperName);
+
+        if (ConfigSchema.TOP_LEVEL_NAME.equals(wrapperName)) {
+            if (inputPortSchemas.size() > 0) {
+                addValidationIssue(INPUT_PORTS_KEY, wrapperName, "must be empty in root group as external input/output ports are currently unsupported");
+            }
+            if (outputPortSchemas.size() > 0) {
+                addValidationIssue(OUTPUT_PORTS_KEY, wrapperName, "must be empty in root group as external input/output ports are currently unsupported");
+            }
+        } else if (ID_DEFAULT.equals(getId())) {
+            addValidationIssue(ID_KEY, wrapperName, "must be set to a value not " + ID_DEFAULT + " if not in root group");
+        }
+
+        Set<String> portIds = getPortIds();
+        connections.stream().filter(c -> portIds.contains(c.getSourceId())).forEachOrdered(c -> c.setNeedsSourceRelationships(false));
+
+
+        Set<String> funnelIds = new HashSet<>(funnels.stream().map(FunnelSchema::getId).collect(Collectors.toList()));
+        connections.stream().filter(c -> funnelIds.contains(c.getSourceId())).forEachOrdered(c -> c.setNeedsSourceRelationships(false));
+
+        addIssuesIfNotNull(processors);
+        addIssuesIfNotNull(remoteProcessGroups);
+        addIssuesIfNotNull(processGroupSchemas);
+        addIssuesIfNotNull(funnels);
+        addIssuesIfNotNull(connections);
+    }
+
+    public Map<String, Object> toMap() {
+        Map<String, Object> result = mapSupplier.get();
+        String id = getId();
+        if (!ID_DEFAULT.equals(id)) {
+            result.put(ID_KEY, id);
+        }
+        StringUtil.doIfNotNullOrEmpty(getName(), name -> result.put(NAME_KEY, name));
+        putListIfNotNull(result, PROCESSORS_KEY, processors);
+        putListIfNotNull(result, PROCESS_GROUPS_KEY, processGroupSchemas);
+        putListIfNotNull(result, INPUT_PORTS_KEY, inputPortSchemas);
+        putListIfNotNull(result, OUTPUT_PORTS_KEY, outputPortSchemas);
+        putListIfNotNull(result, FUNNELS_KEY, funnels);
+        putListIfNotNull(result, CONNECTIONS_KEY, connections);
+        putListIfNotNull(result, REMOTE_PROCESS_GROUPS_KEY, remoteProcessGroups);
+        return result;
+    }
+
+    public List<ProcessorSchema> getProcessors() {
+        return processors;
+    }
+
+    public List<FunnelSchema> getFunnels() {
+        return funnels;
+    }
+
+    public List<ConnectionSchema> getConnections() {
+        return connections;
+    }
+
+    public List<RemoteProcessGroupSchema> getRemoteProcessGroups() {
+        return remoteProcessGroups;
+    }
+
+    public List<ProcessGroupSchemaV2> getProcessGroupSchemas() {
+        return processGroupSchemas;
+    }
+
+    public Set<String> getPortIds() {
+        Set<String> result = new HashSet<>();
+        inputPortSchemas.stream().map(PortSchema::getId).forEachOrdered(result::add);
+        outputPortSchemas.stream().map(PortSchema::getId).forEachOrdered(result::add);
+        processGroupSchemas.stream().flatMap(p -> p.getPortIds().stream()).forEachOrdered(result::add);
+        return result;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    @Override
+    protected String getId(Map map, String wrapperName) {
+        return getOptionalKeyAsType(map, ID_KEY, String.class, wrapperName, ID_DEFAULT);
+    }
+
+    @Override
+    public ProcessGroupSchema convert() {
+        Map<String, Object> map = this.toMap();
+        map.put(CONTROLLER_SERVICES_KEY, DEFAULT_PROPERTIES);
+        return new ProcessGroupSchema(map, getWrapperName());
+    }
+
+    @Override
+    public int getVersion() {
+        return ConfigSchema.CONFIG_VERSION;
+    }
+
+    public List<PortSchema> getOutputPortSchemas() {
+        return outputPortSchemas;
+    }
+
+    public List<PortSchema> getInputPortSchemas() {
+        return inputPortSchemas;
+    }
+
+    @Override
+    protected boolean isValidId(String value) {
+        if (ID_DEFAULT.equals(value)) {
+            return true;
+        }
+        return super.isValidId(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoaderTest.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoaderTest.java b/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoaderTest.java
index 928bc03..045492e 100644
--- a/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoaderTest.java
+++ b/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/serialization/SchemaLoaderTest.java
@@ -65,6 +65,14 @@ public class SchemaLoaderTest {
     }
 
     @Test
+    public void testMinimalConfigV3Version() throws IOException, SchemaLoaderException {
+        Map<String, Object> yamlAsMap = SchemaLoader.loadYamlAsMap(SchemaLoaderTest.class.getClassLoader().getResourceAsStream("config-minimal-v3.yml"));
+        yamlAsMap.put(ConfigSchema.VERSION, ConfigSchema.CONFIG_VERSION);
+        ConfigSchema configSchema = SchemaLoader.loadConfigSchemaFromYaml(yamlAsMap);
+        validateMinimalConfigVersion1Parse(configSchema);
+    }
+
+    @Test
     public void testUnsupportedVersion() throws IOException, SchemaLoaderException {
         Map<String, Object> yamlAsMap = SchemaLoader.loadYamlAsMap(SchemaLoaderTest.class.getClassLoader().getResourceAsStream("config-minimal-v2.yml"));
         yamlAsMap.put(ConfigSchema.VERSION, "9999999");
@@ -72,7 +80,7 @@ public class SchemaLoaderTest {
             SchemaLoader.loadConfigSchemaFromYaml(yamlAsMap);
             fail();
         } catch (SchemaLoaderException e) {
-            assertEquals("YAML configuration version 9999999 not supported.  Supported versions: 1, 2", e.getMessage());
+            assertEquals("YAML configuration version 9999999 not supported.  Supported versions: 1, 2, 3", e.getMessage());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1Test.java
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1Test.java b/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1Test.java
index 3668c0e..f23145e 100644
--- a/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1Test.java
+++ b/minifi-commons/minifi-commons-schema/src/test/java/org/apache/nifi/minifi/commons/schema/v1/ProcessorSchemaV1Test.java
@@ -30,18 +30,18 @@ import java.util.List;
 import java.util.Map;
 
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY;
-import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.CLASS_KEY;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_AUTO_TERMINATED_RELATIONSHIPS_LIST;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_MAX_CONCURRENT_TASKS;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_PENALIZATION_PERIOD;
-import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_PROPERTIES;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_RUN_DURATION_NANOS;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.DEFAULT_YIELD_DURATION;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.PENALIZATION_PERIOD_KEY;
-import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.PROCESSOR_PROPS_KEY;
 import static org.apache.nifi.minifi.commons.schema.ProcessorSchema.RUN_DURATION_NANOS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.CLASS_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.DEFAULT_PROPERTIES;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.MAX_CONCURRENT_TASKS_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.PROPERTIES_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_PERIOD_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.SCHEDULING_STRATEGY_KEY;
 import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.YIELD_PERIOD_KEY;
@@ -109,7 +109,7 @@ public class ProcessorSchemaV1Test {
         map.put(YIELD_PERIOD_KEY, testYieldPeriod);
         map.put(RUN_DURATION_NANOS_KEY, testRunDurationNanos);
         map.put(AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, testAutoTerminatedRelationships);
-        map.put(PROCESSOR_PROPS_KEY, testProperties);
+        map.put(PROPERTIES_KEY, testProperties);
         return map;
     }
 
@@ -235,7 +235,7 @@ public class ProcessorSchemaV1Test {
     @Test
     public void testNoProperties() {
         Map<String, Object> map = createMap();
-        map.remove(PROCESSOR_PROPS_KEY);
+        map.remove(PROPERTIES_KEY);
         assertEquals(DEFAULT_PROPERTIES, createSchema(map, 0).convert().getProperties());
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-commons/minifi-commons-schema/src/test/resources/config-minimal-v3.yml
----------------------------------------------------------------------
diff --git a/minifi-commons/minifi-commons-schema/src/test/resources/config-minimal-v3.yml b/minifi-commons/minifi-commons-schema/src/test/resources/config-minimal-v3.yml
new file mode 100644
index 0000000..9b4c397
--- /dev/null
+++ b/minifi-commons/minifi-commons-schema/src/test/resources/config-minimal-v3.yml
@@ -0,0 +1,38 @@
+# 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.
+
+# This is a minimal V3 config.
+MiNiFi Config Version: 3
+Flow Controller:
+    name: MiNiFi Flow
+
+# When running the Flow (not just doing the transform) these processors will be invalid due to not having the necesary properties/auto-terminated relationships
+Processors:
+    - id: d4b7c284-882c-39e2-88bb-65e8abd5f4c8
+      class: org.apache.nifi.processors.standard.TailFile
+      scheduling strategy: TIMER_DRIVEN
+      scheduling period: 10 sec
+    - id: a256e6b3-36af-3c38-8564-789c399b516c
+      class: org.apache.nifi.processors.standard.PutFile
+      max concurrent tasks: 1
+      scheduling strategy: TIMER_DRIVEN
+      scheduling period: 0 sec
+
+Connections:
+    - id: 90015098-3cd2-3fb0-9696-3f7d28e17f72
+      source id: d4b7c284-882c-39e2-88bb-65e8abd5f4c8
+      source relationship names:
+      - success
+      destination id: a256e6b3-36af-3c38-8564-789c399b516c

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-docs/src/main/assembly/dependencies.xml
----------------------------------------------------------------------
diff --git a/minifi-docs/src/main/assembly/dependencies.xml b/minifi-docs/src/main/assembly/dependencies.xml
index 1ea6053..014b895 100644
--- a/minifi-docs/src/main/assembly/dependencies.xml
+++ b/minifi-docs/src/main/assembly/dependencies.xml
@@ -28,6 +28,13 @@
             <filtered>true</filtered>
         </file>
         <file>
+            <source>${project.build.directory}/markdown/minifi-java-agent-quick-start.md</source>
+            <outputDirectory>./</outputDirectory>
+            <destName>System_Admin_Guide.md</destName>
+            <fileMode>0644</fileMode>
+            <filtered>true</filtered>
+        </file>
+        <file>
             <source>./LICENSE</source>
             <outputDirectory>./</outputDirectory>
             <destName>LICENSE</destName>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-docs/src/main/markdown/System_Admin_Guide.md
----------------------------------------------------------------------
diff --git a/minifi-docs/src/main/markdown/System_Admin_Guide.md b/minifi-docs/src/main/markdown/System_Admin_Guide.md
index d65f8ed..d95cd84 100644
--- a/minifi-docs/src/main/markdown/System_Admin_Guide.md
+++ b/minifi-docs/src/main/markdown/System_Admin_Guide.md
@@ -37,7 +37,7 @@ After a new configuration has been pulled/received the Ingestors use a Different
 
 After a new config is determined to be new, the MiNiFi agent will attempt to restart. The bootstrap first saves the old config into a swap file. The bootstrap monitors the agent as it restarts and if it fails it will roll back to the old config. If it succeeds then the swap file will be deleted and the agent will start processing using the new config.
 
-Note: Data left in connections when the agent attempts to restart will either be mapped to a connection with the same ID in the new config, or orphaned and deleted.
+**Note:** Data left in connections when the agent attempts to restart will either be mapped to a connection with the same ID in the new config, or orphaned and deleted.
 
 The configuration for Warm-Redeploy is done in the bootstrap.conf and primarily revolve around the Config Change Ingestors. The configuration in the bootstrap.conf is done using the "nifi.minifi.notifier.ingestors" key followed by the full path name of the desired Ingestor implementation to run. Use a comma separated list  to define more than one Ingestor implementation. For example:
 
@@ -69,7 +69,7 @@ class name: org.apache.nifi.minifi.bootstrap.configuration.ingestors.RestChangeI
 
 This Config Change Ingestor sets up a light-weight Jetty HTTP(S) REST service in order to listen to HTTP(S) requests. A potential new configuration is sent via a POST request with the BODY being the potential new config.
 
-NOTE: The encoding is expected to be Unicode and the exact version specified by the BOM mark ('UTF-8','UTF-16BE' or 'UTF-16LE'). If there is no BOM mark, then UTF-8 is used.
+**Note:** The encoding is expected to be Unicode and the exact version specified by the BOM mark ('UTF-8','UTF-16BE' or 'UTF-16LE'). If there is no BOM mark, then UTF-8 is used.
 
 Here is an example post request using 'curl' hitting the local machine on pot 8338 and it is executed with the config file "config.yml" in the directory the command is run from:
 
@@ -330,7 +330,7 @@ Alternatively, the MiNiFi Toolkit Converter can aid in creating a config.yml fro
 tool can be downloaded from http://nifi.apache.org/minifi/download.html under the `MiNiFi Toolkit Binaries` section.  Information on the toolkit's usage is
 available at https://nifi.apache.org/minifi/minifi-toolkit.html.
 
-NOTE: Note that values for periods of time and data sizes must include the unit of measure,
+**Note:** Values for periods of time and data sizes must include the unit of measure,
 for example "10 sec" or "10 MB", not simply "10".
 
 ## Versioning
@@ -344,8 +344,11 @@ parses and upconverts to the current version without issue.
 
 1. Use ids instead of names for processors, connections.
 2. Allow multiple source relationships for connections.
-3. Support process groups, input ports, output ports
-4. Change Id Key for RPGs from "Remote Processing Groups" to the proper "Remote Process Groups" (not "ing")
+3. Added support for process groups, and internal input ports an output ports.
+4. Change Id Key for RPGs from "Remote Processing Groups" to the proper "Remote Process Groups" (not "ing").
+
+### Version 2 -> Version 3 changes
+1. Added support for Controller Services.
 
 ## Flow Controller
 
@@ -418,7 +421,7 @@ always sync                       | If set to _true_, any change to the reposito
 --------------------------------  | -------------
 provenance rollover time          | The amount of time to wait before rolling over the latest data provenance information so that it is available to be accessed by components. The default value is 1 min.
 
-## *Component Status Repository*
+## Component Status Repository
 
 The Component Status Repository contains the information for the Component Status History tool in the User Interface. These
 properties govern how that tool works.
@@ -434,7 +437,7 @@ of 576.
 buffer size       | Specifies the buffer size for the Component Status Repository. The default value is 1440.
 snapshot frequency | This value indicates how often to present a snapshot of the components' status history. The default value is 1 min.
 
-## *Security Properties*
+## Security Properties
 
 These properties pertain to various security features in NiFi. Many of these properties are covered in more detail in the
 Security Configuration section of this Administrator's Guide.
@@ -450,6 +453,8 @@ truststore type     | The truststore type. It is blank by default.
 truststore password | The truststore password. It is blank by default.
 ssl protocol        | The protocol to use when communicating via https. Necessary to transfer provenance securely.
 
+**Note:** A StandardSSLContextService will be made automatically with the ID "SSL-Context-Service" if "ssl protocol" is configured.
+
 #### Sensitive Properties Subsection
 
 Some properties for processors are marked as _sensitive_ and should be encrypted. These following properties will be used to encrypt the properties while in use by MiNiFi. This will currently *not* be used to encrypt properties in the config file.
@@ -462,7 +467,7 @@ provider   | The sensitive property provider. The default value is BC.
 
 ## Processors
 
-The current implementation of MiNiFi supports multiple processors. the "Processors" subsection is a list of these processors. Each processor must specify these properties. They are the basic configuration general to all processor implementations. Make sure that all relationships for a processor are accounted for in the auto-terminated relationship list or are used in a connection.
+The current implementation of MiNiFi supports multiple processors. The "Processors" subsection is a list of these processors. Each processor must specify these properties. They are the basic configuration general to all processor implementations. Make sure that all relationships for a processor are accounted for in the auto-terminated relationship list or are used in a connection.
 
 *Property*                          | *Description*
 ----------------------------------- | -------------
@@ -488,6 +493,35 @@ Within the Processor Configuration section, there is the `Properties` subsection
         State File: ./conf/state/tail-file
         Initial Start Position: Beginning of File
 
+
+### Controller Services
+
+The current implementation of MiNiFi supports Controller Services. The "Controller Services" subsection is a list of these services. Each Controller Service must specify the following properties. They are the basic configuration general to all Controller Service implementations.
+
+*Property* | *Description*
+------ | -----------
+name                                | The name of what this Controller Service will do. This is not used for any underlying implementation but solely for the users of this configuration and MiNiFi agent.
+id                                  | The id of this Controller Service. This must be a valid UUID. To reference this Controller Service in the properties of another component, this ID is used.
+type                                | The fully qualified java class name of the processor to run. For example for the standard StandardSSLContextService processor would be: org.apache.nifi.ssl.StandardSSLContextService
+
+**Note:** If the "Security Properties" is configured with an "ssl protocol" then a StandardSSLContextService will be made automatically with the ID "SSL-Context-Service".
+
+
+#### Controller Service Properties
+
+Within the Controller Service Configuration section, there is the `Properties` subsection. The keys and values in this section are the property names and values for the service. For example the StandardSSLContextService would have a section like this:
+
+    Properties:
+      Keystore Filename: /tmp/localhost/keystore.jks
+      Keystore Password: keystorePassword
+      Keystore Type: JKS
+      SSL Protocol: TLS
+      Truststore Filename: /tmp/truststore.jks
+      Truststore Password: truststorePassword
+      Truststore Type: JKS
+      key-password: keyPassword
+
+
 ## Process Groups
 
 Process groups can be nested from the top level.  They can contain other process groups as well and can be used to logically group related operations.
@@ -588,7 +622,7 @@ use compression      | Indicates whether or not to compress the events when bein
 timeout              | How long MiNiFi should wait before timing out the connection.
 batch size           | Specifies how many records to send in a single batch, at most. This should be significantly above the expected amount of records generated between scheduling. If it is not, then there is the potential for the Provenance reporting to lag behind event generation and never catch up.
 
-
+**Note:** In order to send via HTTPS, the "Security Properties" must be fully configured. A StandardSSLContextService will be made automatically with the ID "SSL-Context-Service" and used by the Provenance Reporting.
 
 # Example Config File
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-docs/src/main/markdown/minifi-java-agent-quick-start.md
----------------------------------------------------------------------
diff --git a/minifi-docs/src/main/markdown/minifi-java-agent-quick-start.md b/minifi-docs/src/main/markdown/minifi-java-agent-quick-start.md
index 63ee343..3fd7425 100644
--- a/minifi-docs/src/main/markdown/minifi-java-agent-quick-start.md
+++ b/minifi-docs/src/main/markdown/minifi-java-agent-quick-start.md
@@ -102,7 +102,7 @@ You can use the MiNiFi Toolkit, located in your MiNiFi installation directory, a
 1. Launch NiFi
 2. Create a dataflow.
 3. Convert your dataflow into a template.
-4. Download your template as an .xml file. For more information on working with templates, see the [Templates](http://docs.hortonworks.com/HDPDocuments/HDF2/HDF-2.0.0/bk_user-guide/content/templates.html) section in the *User Guide*.
+4. Download your template as an .xml file. For more information on working with templates, see the [Templates](https://nifi.apache.org/docs/nifi-docs/html/user-guide.html#templates) section in the *User Guide*.
 5. From the MiNiFi Toolkit, run the following command to turn your .xml file into a .yml file:
 ```
 config.sh transform input_file output_file
@@ -180,13 +180,28 @@ MiNiFi is able to use following processors out of the box:
 * UnpackContent
 * ValidateXml
 
+MiNiFi is able to use the StandardSSLContextService out of the box.
+
 If you want to create a dataflow with a processor not shipped with MiNiFi, you can do so.
 1. Set up your dataflow as described above.
 2. Copy the desired NAR file into the MiNiFi lib directory.
 3. Restart your MiNiFi instance.
 
-**Note:** Currently only the StandardSSLContextService is supported as a controller service. It is created automatically if the the "Security Properties" section is set and can be referenced in the processor configuration using the ID "SSL-Context-Service".
-
+**Note:** The following processors are also a part of the default distribution but require adding a NAR for a Controller Service not packaged by default. The processors are grouped by the NAR that is required.
+* nifi-dbcp-service-nar
+  * ConvertJSONToSQL
+  * PutSQL
+  * GenerateTableFetch
+  * ListDatabaseTable
+  * QueryDatabaseTable
+  * ExecuteSQL
+* nifi-distributed-cache-services-nar
+  * DetectDuplicate
+  * FetchDistributedMapCache
+  * PutDistributedMapCache
+* nifi-http-context-map-nar
+  * HandleHttpRequest
+  * HandleHttpResponse
 
 
 # Securing your Dataflow

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-framework-bundle/minifi-framework-nar/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework-nar/pom.xml b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework-nar/pom.xml
index cbdce76..8a161a8 100644
--- a/minifi-nar-bundles/minifi-framework-bundle/minifi-framework-nar/pom.xml
+++ b/minifi-nar-bundles/minifi-framework-bundle/minifi-framework-nar/pom.xml
@@ -112,10 +112,12 @@ limitations under the License.
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
+            <scope>provided</scope>
         </dependency>
 
     </dependencies>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-provenance-reporting-bundle/minifi-provenance-reporting-nar/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-provenance-reporting-bundle/minifi-provenance-reporting-nar/pom.xml b/minifi-nar-bundles/minifi-provenance-reporting-bundle/minifi-provenance-reporting-nar/pom.xml
index f187920..a70fd37 100644
--- a/minifi-nar-bundles/minifi-provenance-reporting-bundle/minifi-provenance-reporting-nar/pom.xml
+++ b/minifi-nar-bundles/minifi-provenance-reporting-bundle/minifi-provenance-reporting-nar/pom.xml
@@ -30,11 +30,10 @@
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-site-to-site-reporting-task</artifactId>
-            <version>1.0.0</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.nifi.minifi</groupId>
-            <artifactId>minifi-standard-services-api-nar</artifactId>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-services-api-nar</artifactId>
             <type>nar</type>
         </dependency>
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-ssl-context-service-nar/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-ssl-context-service-nar/pom.xml b/minifi-nar-bundles/minifi-ssl-context-service-nar/pom.xml
index 475195a..73a07b6 100644
--- a/minifi-nar-bundles/minifi-ssl-context-service-nar/pom.xml
+++ b/minifi-nar-bundles/minifi-ssl-context-service-nar/pom.xml
@@ -28,8 +28,8 @@
     </properties>
     <dependencies>
         <dependency>
-            <groupId>org.apache.nifi.minifi</groupId>
-            <artifactId>minifi-standard-services-api-nar</artifactId>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-services-api-nar</artifactId>
             <type>nar</type>
             <exclusions>
                 <exclusion>
@@ -71,10 +71,12 @@
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
+            <scope>provided</scope>
         </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-ssl-context-service-nar/src/main/resources/META-INF/NOTICE
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-ssl-context-service-nar/src/main/resources/META-INF/NOTICE b/minifi-nar-bundles/minifi-ssl-context-service-nar/src/main/resources/META-INF/NOTICE
index b7d1e8b..41dd8dd 100644
--- a/minifi-nar-bundles/minifi-ssl-context-service-nar/src/main/resources/META-INF/NOTICE
+++ b/minifi-nar-bundles/minifi-ssl-context-service-nar/src/main/resources/META-INF/NOTICE
@@ -3,22 +3,3 @@ Copyright 2014-2016 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
-
-******************
-Apache Software License v2
-******************
-
-The following binary components are provided under the Apache Software License v2
-
-  (ASLv2) Apache Commons IO
-    The following NOTICE information applies:
-      Apache Commons IO
-      Copyright 2002-2012 The Apache Software Foundation
-
-  (ASLv2) Apache Commons Lang
-    The following NOTICE information applies:
-      Apache Commons Lang
-      Copyright 2001-2015 The Apache Software Foundation
-
-      This product includes software from the Spring Framework,
-      under the Apache License 2.0 (see: StringUtils.containsWhitespace())

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/cbb2bdd8/minifi-nar-bundles/minifi-standard-nar/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-nar-bundles/minifi-standard-nar/pom.xml b/minifi-nar-bundles/minifi-standard-nar/pom.xml
index 695ac7c..2d08698 100644
--- a/minifi-nar-bundles/minifi-standard-nar/pom.xml
+++ b/minifi-nar-bundles/minifi-standard-nar/pom.xml
@@ -32,8 +32,8 @@ limitations under the License.
     </properties>
     <dependencies>
         <dependency>
-            <groupId>org.apache.nifi.minifi</groupId>
-            <artifactId>minifi-standard-services-api-nar</artifactId>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-services-api-nar</artifactId>
             <type>nar</type>
         </dependency>
         <dependency>
@@ -70,7 +70,6 @@ limitations under the License.
         <dependency>
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcpg-jdk15on</artifactId>
-            <version>1.54</version>
             <scope>provided</scope>
         </dependency>
         <dependency>