You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2018/04/02 15:39:26 UTC

[1/2] nifi-minifi git commit: MINIFI-449 Support for converting VersionedFlowSnapshot to YAML via minifi-toolkit - Upgrading Jackson databind to 2.9.1 for consistency with other Jackson modules

Repository: nifi-minifi
Updated Branches:
  refs/heads/master 270a3081d -> 6e5b00a8f


http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.json
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.json b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.json
new file mode 100644
index 0000000..109b4b1
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.json
@@ -0,0 +1,770 @@
+{
+  "snapshotMetadata" : {
+    "version" : 2,
+    "timestamp" : 1522268768944,
+    "author" : "anonymous",
+    "comments" : "Moving ports to nested child group because MiNiFi doesn't allow ports in the top-level PG."
+  },
+  "flowContents" : {
+    "identifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b",
+    "name" : "YAML-Conversion-Test",
+    "comments" : "",
+    "position" : {
+      "x" : 298.0,
+      "y" : 44.0
+    },
+    "processGroups" : [ {
+      "identifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf",
+      "name" : "Child PG 1",
+      "comments" : "",
+      "position" : {
+        "x" : 1115.0,
+        "y" : 30.0
+      },
+      "processGroups" : [ ],
+      "remoteProcessGroups" : [ ],
+      "processors" : [ {
+        "identifier" : "19036357-7967-31bd-8f22-b79c47a1fb8c",
+        "name" : "GenerateFlowFile",
+        "comments" : "",
+        "position" : {
+          "x" : 937.0,
+          "y" : 774.0
+        },
+        "bundle" : {
+          "group" : "org.apache.nifi",
+          "artifact" : "nifi-standard-nar",
+          "version" : "1.6.0-SNAPSHOT"
+        },
+        "style" : { },
+        "type" : "org.apache.nifi.processors.standard.GenerateFlowFile",
+        "properties" : {
+          "character-set" : "UTF-8",
+          "File Size" : "0B",
+          "generate-ff-custom-text" : "Test 1",
+          "Batch Size" : "1",
+          "Unique FlowFiles" : "false",
+          "Data Format" : "Text"
+        },
+        "propertyDescriptors" : {
+          "character-set" : {
+            "name" : "character-set",
+            "displayName" : "Character Set",
+            "identifiesControllerService" : false
+          },
+          "File Size" : {
+            "name" : "File Size",
+            "displayName" : "File Size",
+            "identifiesControllerService" : false
+          },
+          "generate-ff-custom-text" : {
+            "name" : "generate-ff-custom-text",
+            "displayName" : "Custom Text",
+            "identifiesControllerService" : false
+          },
+          "Batch Size" : {
+            "name" : "Batch Size",
+            "displayName" : "Batch Size",
+            "identifiesControllerService" : false
+          },
+          "Unique FlowFiles" : {
+            "name" : "Unique FlowFiles",
+            "displayName" : "Unique FlowFiles",
+            "identifiesControllerService" : false
+          },
+          "Data Format" : {
+            "name" : "Data Format",
+            "displayName" : "Data Format",
+            "identifiesControllerService" : false
+          }
+        },
+        "schedulingPeriod" : "10 sec",
+        "schedulingStrategy" : "TIMER_DRIVEN",
+        "executionNode" : "ALL",
+        "penaltyDuration" : "30 sec",
+        "yieldDuration" : "1 sec",
+        "bulletinLevel" : "WARN",
+        "runDurationMillis" : 0,
+        "concurrentlySchedulableTaskCount" : 1,
+        "componentType" : "PROCESSOR",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      }, {
+        "identifier" : "e539129e-b02a-38cb-b441-95d5e37ac78a",
+        "name" : "GenerateFlowFile",
+        "comments" : "",
+        "position" : {
+          "x" : 1314.0,
+          "y" : 778.0
+        },
+        "bundle" : {
+          "group" : "org.apache.nifi",
+          "artifact" : "nifi-standard-nar",
+          "version" : "1.6.0-SNAPSHOT"
+        },
+        "style" : { },
+        "type" : "org.apache.nifi.processors.standard.GenerateFlowFile",
+        "properties" : {
+          "character-set" : "UTF-8",
+          "File Size" : "0B",
+          "generate-ff-custom-text" : "Test 2",
+          "Batch Size" : "1",
+          "Unique FlowFiles" : "false",
+          "Data Format" : "Text"
+        },
+        "propertyDescriptors" : {
+          "character-set" : {
+            "name" : "character-set",
+            "displayName" : "Character Set",
+            "identifiesControllerService" : false
+          },
+          "File Size" : {
+            "name" : "File Size",
+            "displayName" : "File Size",
+            "identifiesControllerService" : false
+          },
+          "generate-ff-custom-text" : {
+            "name" : "generate-ff-custom-text",
+            "displayName" : "Custom Text",
+            "identifiesControllerService" : false
+          },
+          "Batch Size" : {
+            "name" : "Batch Size",
+            "displayName" : "Batch Size",
+            "identifiesControllerService" : false
+          },
+          "Unique FlowFiles" : {
+            "name" : "Unique FlowFiles",
+            "displayName" : "Unique FlowFiles",
+            "identifiesControllerService" : false
+          },
+          "Data Format" : {
+            "name" : "Data Format",
+            "displayName" : "Data Format",
+            "identifiesControllerService" : false
+          }
+        },
+        "schedulingPeriod" : "0 sec",
+        "schedulingStrategy" : "TIMER_DRIVEN",
+        "executionNode" : "ALL",
+        "penaltyDuration" : "30 sec",
+        "yieldDuration" : "1 sec",
+        "bulletinLevel" : "WARN",
+        "runDurationMillis" : 0,
+        "concurrentlySchedulableTaskCount" : 1,
+        "componentType" : "PROCESSOR",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      }, {
+        "identifier" : "b53d856b-9837-3e67-b312-95da56562bad",
+        "name" : "UpdateAttribute",
+        "comments" : "",
+        "position" : {
+          "x" : 1083.0,
+          "y" : 1150.0
+        },
+        "bundle" : {
+          "group" : "org.apache.nifi",
+          "artifact" : "nifi-update-attribute-nar",
+          "version" : "1.6.0-SNAPSHOT"
+        },
+        "style" : { },
+        "type" : "org.apache.nifi.processors.attributes.UpdateAttribute",
+        "properties" : {
+          "Store State" : "Do not store state"
+        },
+        "propertyDescriptors" : {
+          "Delete Attributes Expression" : {
+            "name" : "Delete Attributes Expression",
+            "displayName" : "Delete Attributes Expression",
+            "identifiesControllerService" : false
+          },
+          "Store State" : {
+            "name" : "Store State",
+            "displayName" : "Store State",
+            "identifiesControllerService" : false
+          },
+          "Stateful Variables Initial Value" : {
+            "name" : "Stateful Variables Initial Value",
+            "displayName" : "Stateful Variables Initial Value",
+            "identifiesControllerService" : false
+          }
+        },
+        "schedulingPeriod" : "0 sec",
+        "schedulingStrategy" : "TIMER_DRIVEN",
+        "executionNode" : "ALL",
+        "penaltyDuration" : "30 sec",
+        "yieldDuration" : "1 sec",
+        "bulletinLevel" : "WARN",
+        "runDurationMillis" : 0,
+        "concurrentlySchedulableTaskCount" : 1,
+        "autoTerminatedRelationships" : [ "success" ],
+        "componentType" : "PROCESSOR",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      } ],
+      "inputPorts" : [ {
+        "identifier" : "2f237f38-11d8-3fd7-bb89-356153922df6",
+        "name" : "Data-In",
+        "position" : {
+          "x" : 1809.0,
+          "y" : 776.0
+        },
+        "type" : "INPUT_PORT",
+        "concurrentlySchedulableTaskCount" : 1,
+        "componentType" : "INPUT_PORT",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      } ],
+      "outputPorts" : [ {
+        "identifier" : "f0a9fd96-9be0-32a0-84b7-6871daceb0ee",
+        "name" : "Data-Out",
+        "position" : {
+          "x" : 1819.0,
+          "y" : 1044.0
+        },
+        "type" : "OUTPUT_PORT",
+        "concurrentlySchedulableTaskCount" : 1,
+        "componentType" : "OUTPUT_PORT",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      } ],
+      "connections" : [ {
+        "identifier" : "736b18a1-c523-3345-b2e9-bb54e2aeec25",
+        "name" : "",
+        "source" : {
+          "id" : "e539129e-b02a-38cb-b441-95d5e37ac78a",
+          "type" : "PROCESSOR",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "GenerateFlowFile",
+          "comments" : ""
+        },
+        "destination" : {
+          "id" : "ecae133a-5087-3bff-a1bf-e1d1e9589eb5",
+          "type" : "FUNNEL",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "Funnel",
+          "comments" : ""
+        },
+        "labelIndex" : 1,
+        "zIndex" : 0,
+        "selectedRelationships" : [ "success" ],
+        "backPressureObjectThreshold" : 10000,
+        "backPressureDataSizeThreshold" : "1 GB",
+        "flowFileExpiration" : "0 sec",
+        "bends" : [ {
+          "x" : 1480.0,
+          "y" : 981.0
+        } ],
+        "componentType" : "CONNECTION",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      }, {
+        "identifier" : "7d55b640-16e3-3c25-bf06-3750f1a538db",
+        "name" : "",
+        "source" : {
+          "id" : "2f237f38-11d8-3fd7-bb89-356153922df6",
+          "type" : "INPUT_PORT",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "Data-In"
+        },
+        "destination" : {
+          "id" : "f0a9fd96-9be0-32a0-84b7-6871daceb0ee",
+          "type" : "OUTPUT_PORT",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "Data-Out"
+        },
+        "labelIndex" : 1,
+        "zIndex" : 0,
+        "selectedRelationships" : [ "" ],
+        "backPressureObjectThreshold" : 10000,
+        "backPressureDataSizeThreshold" : "1 GB",
+        "flowFileExpiration" : "0 sec",
+        "componentType" : "CONNECTION",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      }, {
+        "identifier" : "7ca3c908-1eb7-33ed-89b1-94ac376c22aa",
+        "name" : "",
+        "source" : {
+          "id" : "19036357-7967-31bd-8f22-b79c47a1fb8c",
+          "type" : "PROCESSOR",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "GenerateFlowFile",
+          "comments" : ""
+        },
+        "destination" : {
+          "id" : "ecae133a-5087-3bff-a1bf-e1d1e9589eb5",
+          "type" : "FUNNEL",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "Funnel",
+          "comments" : ""
+        },
+        "labelIndex" : 1,
+        "zIndex" : 0,
+        "selectedRelationships" : [ "success" ],
+        "backPressureObjectThreshold" : 10000,
+        "backPressureDataSizeThreshold" : "1 GB",
+        "flowFileExpiration" : "0 sec",
+        "bends" : [ {
+          "x" : 1113.0,
+          "y" : 982.0
+        } ],
+        "componentType" : "CONNECTION",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      }, {
+        "identifier" : "61c76ad1-d4c7-3ca1-baed-bc4d6a906b23",
+        "name" : "",
+        "source" : {
+          "id" : "ecae133a-5087-3bff-a1bf-e1d1e9589eb5",
+          "type" : "FUNNEL",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "Funnel",
+          "comments" : ""
+        },
+        "destination" : {
+          "id" : "b53d856b-9837-3e67-b312-95da56562bad",
+          "type" : "PROCESSOR",
+          "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+          "name" : "UpdateAttribute",
+          "comments" : ""
+        },
+        "labelIndex" : 1,
+        "zIndex" : 0,
+        "selectedRelationships" : [ "" ],
+        "backPressureObjectThreshold" : 10000,
+        "backPressureDataSizeThreshold" : "1 GB",
+        "flowFileExpiration" : "0 sec",
+        "componentType" : "CONNECTION",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      } ],
+      "labels" : [ ],
+      "funnels" : [ {
+        "identifier" : "ecae133a-5087-3bff-a1bf-e1d1e9589eb5",
+        "position" : {
+          "x" : 1234.0,
+          "y" : 1024.0
+        },
+        "componentType" : "FUNNEL",
+        "groupIdentifier" : "2b941c90-41c5-30fb-aee4-af56e9b161cf"
+      } ],
+      "controllerServices" : [ ],
+      "variables" : { },
+      "componentType" : "PROCESS_GROUP",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    } ],
+    "remoteProcessGroups" : [ {
+      "identifier" : "2cb9cb6f-492c-327f-af03-4c0f9f75722b",
+      "name" : "NiFi Flow",
+      "comments" : "",
+      "position" : {
+        "x" : 441.0,
+        "y" : 662.0
+      },
+      "targetUri" : "http://localhost:8080/nifi",
+      "targetUris" : "http://localhost:8080/nifi",
+      "communicationsTimeout" : "30 sec",
+      "yieldDuration" : "10 sec",
+      "transportProtocol" : "HTTP",
+      "proxyHost" : "",
+      "proxyUser" : "",
+      "inputPorts" : [ {
+        "identifier" : "0dfdea1b-379b-30b5-8d82-7d4b665af725",
+        "name" : "Remote-In",
+        "remoteGroupId" : "2cb9cb6f-492c-327f-af03-4c0f9f75722b",
+        "concurrentlySchedulableTaskCount" : 1,
+        "useCompression" : false,
+        "batchSize" : { },
+        "componentType" : "REMOTE_INPUT_PORT",
+        "targetId" : "01621001-e0d3-1e29-565c-5af8d1aeb56f",
+        "groupIdentifier" : "2cb9cb6f-492c-327f-af03-4c0f9f75722b"
+      } ],
+      "componentType" : "REMOTE_PROCESS_GROUP",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    } ],
+    "processors" : [ {
+      "identifier" : "86a11150-4365-345f-b0f9-354723b24a83",
+      "name" : "UpdateAttribute",
+      "comments" : "",
+      "position" : {
+        "x" : 445.0,
+        "y" : 420.0
+      },
+      "bundle" : {
+        "group" : "org.apache.nifi",
+        "artifact" : "nifi-update-attribute-nar",
+        "version" : "1.6.0-SNAPSHOT"
+      },
+      "style" : { },
+      "type" : "org.apache.nifi.processors.attributes.UpdateAttribute",
+      "properties" : {
+        "Store State" : "Do not store state"
+      },
+      "propertyDescriptors" : {
+        "Delete Attributes Expression" : {
+          "name" : "Delete Attributes Expression",
+          "displayName" : "Delete Attributes Expression",
+          "identifiesControllerService" : false
+        },
+        "Store State" : {
+          "name" : "Store State",
+          "displayName" : "Store State",
+          "identifiesControllerService" : false
+        },
+        "Stateful Variables Initial Value" : {
+          "name" : "Stateful Variables Initial Value",
+          "displayName" : "Stateful Variables Initial Value",
+          "identifiesControllerService" : false
+        }
+      },
+      "schedulingPeriod" : "0 sec",
+      "schedulingStrategy" : "TIMER_DRIVEN",
+      "executionNode" : "ALL",
+      "penaltyDuration" : "30 sec",
+      "yieldDuration" : "1 sec",
+      "bulletinLevel" : "WARN",
+      "runDurationMillis" : 0,
+      "concurrentlySchedulableTaskCount" : 1,
+      "componentType" : "PROCESSOR",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    }, {
+      "identifier" : "ad1c2a39-528a-3d19-a5d9-19d057d2a5ff",
+      "name" : "GenerateFlowFile",
+      "comments" : "",
+      "position" : {
+        "x" : 299.0,
+        "y" : 44.0
+      },
+      "bundle" : {
+        "group" : "org.apache.nifi",
+        "artifact" : "nifi-standard-nar",
+        "version" : "1.6.0-SNAPSHOT"
+      },
+      "style" : { },
+      "type" : "org.apache.nifi.processors.standard.GenerateFlowFile",
+      "properties" : {
+        "character-set" : "UTF-8",
+        "File Size" : "0B",
+        "generate-ff-custom-text" : "Test 1",
+        "Batch Size" : "1",
+        "Unique FlowFiles" : "false",
+        "Data Format" : "Text"
+      },
+      "propertyDescriptors" : {
+        "character-set" : {
+          "name" : "character-set",
+          "displayName" : "Character Set",
+          "identifiesControllerService" : false
+        },
+        "File Size" : {
+          "name" : "File Size",
+          "displayName" : "File Size",
+          "identifiesControllerService" : false
+        },
+        "generate-ff-custom-text" : {
+          "name" : "generate-ff-custom-text",
+          "displayName" : "Custom Text",
+          "identifiesControllerService" : false
+        },
+        "Batch Size" : {
+          "name" : "Batch Size",
+          "displayName" : "Batch Size",
+          "identifiesControllerService" : false
+        },
+        "Unique FlowFiles" : {
+          "name" : "Unique FlowFiles",
+          "displayName" : "Unique FlowFiles",
+          "identifiesControllerService" : false
+        },
+        "Data Format" : {
+          "name" : "Data Format",
+          "displayName" : "Data Format",
+          "identifiesControllerService" : false
+        }
+      },
+      "schedulingPeriod" : "10 sec",
+      "schedulingStrategy" : "TIMER_DRIVEN",
+      "executionNode" : "ALL",
+      "penaltyDuration" : "30 sec",
+      "yieldDuration" : "1 sec",
+      "bulletinLevel" : "WARN",
+      "runDurationMillis" : 0,
+      "concurrentlySchedulableTaskCount" : 1,
+      "componentType" : "PROCESSOR",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    }, {
+      "identifier" : "dff4abc1-cc2e-3b31-a389-fa133f71be54",
+      "name" : "GenerateFlowFile",
+      "comments" : "",
+      "position" : {
+        "x" : 676.0,
+        "y" : 48.0
+      },
+      "bundle" : {
+        "group" : "org.apache.nifi",
+        "artifact" : "nifi-standard-nar",
+        "version" : "1.6.0-SNAPSHOT"
+      },
+      "style" : { },
+      "type" : "org.apache.nifi.processors.standard.GenerateFlowFile",
+      "properties" : {
+        "character-set" : "UTF-8",
+        "File Size" : "0B",
+        "generate-ff-custom-text" : "Test 2",
+        "Batch Size" : "1",
+        "Unique FlowFiles" : "false",
+        "Data Format" : "Text"
+      },
+      "propertyDescriptors" : {
+        "character-set" : {
+          "name" : "character-set",
+          "displayName" : "Character Set",
+          "identifiesControllerService" : false
+        },
+        "File Size" : {
+          "name" : "File Size",
+          "displayName" : "File Size",
+          "identifiesControllerService" : false
+        },
+        "generate-ff-custom-text" : {
+          "name" : "generate-ff-custom-text",
+          "displayName" : "Custom Text",
+          "identifiesControllerService" : false
+        },
+        "Batch Size" : {
+          "name" : "Batch Size",
+          "displayName" : "Batch Size",
+          "identifiesControllerService" : false
+        },
+        "Unique FlowFiles" : {
+          "name" : "Unique FlowFiles",
+          "displayName" : "Unique FlowFiles",
+          "identifiesControllerService" : false
+        },
+        "Data Format" : {
+          "name" : "Data Format",
+          "displayName" : "Data Format",
+          "identifiesControllerService" : false
+        }
+      },
+      "schedulingPeriod" : "0 sec",
+      "schedulingStrategy" : "TIMER_DRIVEN",
+      "executionNode" : "ALL",
+      "penaltyDuration" : "30 sec",
+      "yieldDuration" : "1 sec",
+      "bulletinLevel" : "WARN",
+      "runDurationMillis" : 0,
+      "concurrentlySchedulableTaskCount" : 1,
+      "componentType" : "PROCESSOR",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    } ],
+    "inputPorts" : [ ],
+    "outputPorts" : [ ],
+    "connections" : [ {
+      "identifier" : "87c2a77d-31be-3e84-a6c5-2f96cde3e0bd",
+      "name" : "",
+      "source" : {
+        "id" : "ad1c2a39-528a-3d19-a5d9-19d057d2a5ff",
+        "type" : "PROCESSOR",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "GenerateFlowFile",
+        "comments" : ""
+      },
+      "destination" : {
+        "id" : "b3ba295c-5947-3628-8991-930415e3e44d",
+        "type" : "FUNNEL",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "Funnel",
+        "comments" : ""
+      },
+      "labelIndex" : 0,
+      "zIndex" : 0,
+      "selectedRelationships" : [ "success" ],
+      "backPressureObjectThreshold" : 10000,
+      "backPressureDataSizeThreshold" : "1 GB",
+      "flowFileExpiration" : "0 sec",
+      "bends" : [ {
+        "x" : 475.0,
+        "y" : 252.0
+      } ],
+      "componentType" : "CONNECTION",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    }, {
+      "identifier" : "eca663c9-0f25-30d2-a509-122c8fa5ce30",
+      "name" : "",
+      "source" : {
+        "id" : "dff4abc1-cc2e-3b31-a389-fa133f71be54",
+        "type" : "PROCESSOR",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "GenerateFlowFile",
+        "comments" : ""
+      },
+      "destination" : {
+        "id" : "b3ba295c-5947-3628-8991-930415e3e44d",
+        "type" : "FUNNEL",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "Funnel",
+        "comments" : ""
+      },
+      "labelIndex" : 0,
+      "zIndex" : 0,
+      "selectedRelationships" : [ "success" ],
+      "backPressureObjectThreshold" : 10000,
+      "backPressureDataSizeThreshold" : "1 GB",
+      "flowFileExpiration" : "0 sec",
+      "bends" : [ {
+        "x" : 842.0,
+        "y" : 251.0
+      } ],
+      "componentType" : "CONNECTION",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    }, {
+      "identifier" : "89e5dc19-de02-330d-b1cf-8062c14a24f9",
+      "name" : "",
+      "source" : {
+        "id" : "86a11150-4365-345f-b0f9-354723b24a83",
+        "type" : "PROCESSOR",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "UpdateAttribute",
+        "comments" : ""
+      },
+      "destination" : {
+        "id" : "0dfdea1b-379b-30b5-8d82-7d4b665af725",
+        "type" : "REMOTE_INPUT_PORT",
+        "groupId" : "2cb9cb6f-492c-327f-af03-4c0f9f75722b",
+        "name" : "Remote-In"
+      },
+      "labelIndex" : 1,
+      "zIndex" : 0,
+      "selectedRelationships" : [ "success" ],
+      "backPressureObjectThreshold" : 10000,
+      "backPressureDataSizeThreshold" : "1 GB",
+      "flowFileExpiration" : "0 sec",
+      "componentType" : "CONNECTION",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    }, {
+      "identifier" : "4be3a5c4-9c05-3080-8e86-0b90f369fc54",
+      "name" : "",
+      "source" : {
+        "id" : "f0a9fd96-9be0-32a0-84b7-6871daceb0ee",
+        "type" : "OUTPUT_PORT",
+        "groupId" : "01621009-5a05-1e29-3931-5f0e9dd1e095",
+        "name" : "Data-Out"
+      },
+      "destination" : {
+        "id" : "86a11150-4365-345f-b0f9-354723b24a83",
+        "type" : "PROCESSOR",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "UpdateAttribute",
+        "comments" : ""
+      },
+      "labelIndex" : 0,
+      "zIndex" : 0,
+      "selectedRelationships" : [ "" ],
+      "backPressureObjectThreshold" : 10000,
+      "backPressureDataSizeThreshold" : "1 GB",
+      "flowFileExpiration" : "0 sec",
+      "bends" : [ {
+        "x" : 1308.0,
+        "y" : 341.0
+      } ],
+      "componentType" : "CONNECTION",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    }, {
+      "identifier" : "e45a831d-1eb0-3adb-acf1-cbe8d8a95a79",
+      "name" : "",
+      "source" : {
+        "id" : "b3ba295c-5947-3628-8991-930415e3e44d",
+        "type" : "FUNNEL",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "Funnel",
+        "comments" : ""
+      },
+      "destination" : {
+        "id" : "86a11150-4365-345f-b0f9-354723b24a83",
+        "type" : "PROCESSOR",
+        "groupId" : "6e28c86e-0162-1000-fcc2-72c845c909fa",
+        "name" : "UpdateAttribute",
+        "comments" : ""
+      },
+      "labelIndex" : 1,
+      "zIndex" : 0,
+      "selectedRelationships" : [ "" ],
+      "backPressureObjectThreshold" : 10000,
+      "backPressureDataSizeThreshold" : "1 GB",
+      "flowFileExpiration" : "0 sec",
+      "componentType" : "CONNECTION",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    } ],
+    "labels" : [ ],
+    "funnels" : [ {
+      "identifier" : "b3ba295c-5947-3628-8991-930415e3e44d",
+      "position" : {
+        "x" : 596.0,
+        "y" : 294.0
+      },
+      "componentType" : "FUNNEL",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    } ],
+    "controllerServices" : [ {
+      "identifier" : "d4fd9704-a03e-3c1b-8537-96ff8bee3a83",
+      "name" : "StandardSSLContextService",
+      "type" : "org.apache.nifi.ssl.StandardSSLContextService",
+      "bundle" : {
+        "group" : "org.apache.nifi",
+        "artifact" : "nifi-ssl-context-service-nar",
+        "version" : "1.6.0-SNAPSHOT"
+      },
+      "controllerServiceApis" : [ {
+        "type" : "org.apache.nifi.ssl.SSLContextService",
+        "bundle" : {
+          "group" : "org.apache.nifi",
+          "artifact" : "nifi-standard-services-api-nar",
+          "version" : "1.6.0-SNAPSHOT"
+        }
+      } ],
+      "properties" : {
+        "SSL Protocol" : "TLS"
+      },
+      "propertyDescriptors" : {
+        "Truststore Type" : {
+          "name" : "Truststore Type",
+          "displayName" : "Truststore Type",
+          "identifiesControllerService" : false
+        },
+        "SSL Protocol" : {
+          "name" : "SSL Protocol",
+          "displayName" : "TLS Protocol",
+          "identifiesControllerService" : false
+        },
+        "Keystore Type" : {
+          "name" : "Keystore Type",
+          "displayName" : "Keystore Type",
+          "identifiesControllerService" : false
+        },
+        "Truststore Filename" : {
+          "name" : "Truststore Filename",
+          "displayName" : "Truststore Filename",
+          "identifiesControllerService" : false
+        },
+        "Keystore Password" : {
+          "name" : "Keystore Password",
+          "displayName" : "Keystore Password",
+          "identifiesControllerService" : false
+        },
+        "key-password" : {
+          "name" : "key-password",
+          "displayName" : "Key Password",
+          "identifiesControllerService" : false
+        },
+        "Truststore Password" : {
+          "name" : "Truststore Password",
+          "displayName" : "Truststore Password",
+          "identifiesControllerService" : false
+        },
+        "Keystore Filename" : {
+          "name" : "Keystore Filename",
+          "displayName" : "Keystore Filename",
+          "identifiesControllerService" : false
+        }
+      },
+      "componentType" : "CONTROLLER_SERVICE",
+      "groupIdentifier" : "87bd701d-3c27-350d-a6fa-c5144c5ec79b"
+    } ],
+    "variables" : { },
+    "componentType" : "PROCESS_GROUP"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.yml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.yml b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.yml
new file mode 100644
index 0000000..28ed652
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/test/resources/VersionedFlowSnapshot-Simple.yml
@@ -0,0 +1,291 @@
+# 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: YAML-Conversion-Test
+  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
+  variable registry properties: ''
+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
+  implementation: org.apache.nifi.provenance.MiNiFiPersistentProvenanceRepository
+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: ad1c2a39-528a-3d19-a5d9-19d057d2a5ff
+  name: GenerateFlowFile
+  class: org.apache.nifi.processors.standard.GenerateFlowFile
+  max concurrent tasks: 1
+  scheduling strategy: TIMER_DRIVEN
+  scheduling period: 10 sec
+  penalization period: 30 sec
+  yield period: 1 sec
+  run duration nanos: 0
+  auto-terminated relationships list: []
+  Properties:
+    Batch Size: '1'
+    Data Format: Text
+    File Size: 0B
+    Unique FlowFiles: 'false'
+    character-set: UTF-8
+    generate-ff-custom-text: Test 1
+- id: dff4abc1-cc2e-3b31-a389-fa133f71be54
+  name: GenerateFlowFile
+  class: org.apache.nifi.processors.standard.GenerateFlowFile
+  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:
+    Batch Size: '1'
+    Data Format: Text
+    File Size: 0B
+    Unique FlowFiles: 'false'
+    character-set: UTF-8
+    generate-ff-custom-text: Test 2
+- id: 86a11150-4365-345f-b0f9-354723b24a83
+  name: UpdateAttribute
+  class: org.apache.nifi.processors.attributes.UpdateAttribute
+  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:
+    Store State: Do not store state
+Controller Services:
+- id: d4fd9704-a03e-3c1b-8537-96ff8bee3a83
+  name: StandardSSLContextService
+  type: org.apache.nifi.ssl.StandardSSLContextService
+  Properties:
+    SSL Protocol: TLS
+Process Groups:
+- id: 2b941c90-41c5-30fb-aee4-af56e9b161cf
+  name: Child PG 1
+  Processors:
+  - id: 19036357-7967-31bd-8f22-b79c47a1fb8c
+    name: GenerateFlowFile
+    class: org.apache.nifi.processors.standard.GenerateFlowFile
+    max concurrent tasks: 1
+    scheduling strategy: TIMER_DRIVEN
+    scheduling period: 10 sec
+    penalization period: 30 sec
+    yield period: 1 sec
+    run duration nanos: 0
+    auto-terminated relationships list: []
+    Properties:
+      Batch Size: '1'
+      Data Format: Text
+      File Size: 0B
+      Unique FlowFiles: 'false'
+      character-set: UTF-8
+      generate-ff-custom-text: Test 1
+  - id: e539129e-b02a-38cb-b441-95d5e37ac78a
+    name: GenerateFlowFile
+    class: org.apache.nifi.processors.standard.GenerateFlowFile
+    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:
+      Batch Size: '1'
+      Data Format: Text
+      File Size: 0B
+      Unique FlowFiles: 'false'
+      character-set: UTF-8
+      generate-ff-custom-text: Test 2
+  - id: b53d856b-9837-3e67-b312-95da56562bad
+    name: UpdateAttribute
+    class: org.apache.nifi.processors.attributes.UpdateAttribute
+    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:
+      Store State: Do not store state
+  Controller Services: []
+  Process Groups: []
+  Input Ports:
+  - id: 2f237f38-11d8-3fd7-bb89-356153922df6
+    name: Data-In
+  Output Ports:
+  - id: f0a9fd96-9be0-32a0-84b7-6871daceb0ee
+    name: Data-Out
+  Funnels:
+  - id: ecae133a-5087-3bff-a1bf-e1d1e9589eb5
+  Connections:
+  - id: 7d55b640-16e3-3c25-bf06-3750f1a538db
+    name: Data-In//Data-Out
+    source id: 2f237f38-11d8-3fd7-bb89-356153922df6
+    source relationship names:
+    - ''
+    destination id: f0a9fd96-9be0-32a0-84b7-6871daceb0ee
+    max work queue size: 10000
+    max work queue data size: 1 GB
+    flowfile expiration: 0 sec
+    queue prioritizer class: ''
+  - id: 61c76ad1-d4c7-3ca1-baed-bc4d6a906b23
+    name: Funnel//UpdateAttribute
+    source id: ecae133a-5087-3bff-a1bf-e1d1e9589eb5
+    source relationship names:
+    - ''
+    destination id: b53d856b-9837-3e67-b312-95da56562bad
+    max work queue size: 10000
+    max work queue data size: 1 GB
+    flowfile expiration: 0 sec
+    queue prioritizer class: ''
+  - id: 736b18a1-c523-3345-b2e9-bb54e2aeec25
+    name: GenerateFlowFile/success/Funnel
+    source id: e539129e-b02a-38cb-b441-95d5e37ac78a
+    source relationship names:
+    - success
+    destination id: ecae133a-5087-3bff-a1bf-e1d1e9589eb5
+    max work queue size: 10000
+    max work queue data size: 1 GB
+    flowfile expiration: 0 sec
+    queue prioritizer class: ''
+  - id: 7ca3c908-1eb7-33ed-89b1-94ac376c22aa
+    name: GenerateFlowFile/success/Funnel
+    source id: 19036357-7967-31bd-8f22-b79c47a1fb8c
+    source relationship names:
+    - success
+    destination id: ecae133a-5087-3bff-a1bf-e1d1e9589eb5
+    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:
+- id: b3ba295c-5947-3628-8991-930415e3e44d
+Connections:
+- id: 4be3a5c4-9c05-3080-8e86-0b90f369fc54
+  name: Data-Out//UpdateAttribute
+  source id: f0a9fd96-9be0-32a0-84b7-6871daceb0ee
+  source relationship names:
+  - ''
+  destination id: 86a11150-4365-345f-b0f9-354723b24a83
+  max work queue size: 10000
+  max work queue data size: 1 GB
+  flowfile expiration: 0 sec
+  queue prioritizer class: ''
+- id: e45a831d-1eb0-3adb-acf1-cbe8d8a95a79
+  name: Funnel//UpdateAttribute
+  source id: b3ba295c-5947-3628-8991-930415e3e44d
+  source relationship names:
+  - ''
+  destination id: 86a11150-4365-345f-b0f9-354723b24a83
+  max work queue size: 10000
+  max work queue data size: 1 GB
+  flowfile expiration: 0 sec
+  queue prioritizer class: ''
+- id: 87c2a77d-31be-3e84-a6c5-2f96cde3e0bd
+  name: GenerateFlowFile/success/Funnel
+  source id: ad1c2a39-528a-3d19-a5d9-19d057d2a5ff
+  source relationship names:
+  - success
+  destination id: b3ba295c-5947-3628-8991-930415e3e44d
+  max work queue size: 10000
+  max work queue data size: 1 GB
+  flowfile expiration: 0 sec
+  queue prioritizer class: ''
+- id: eca663c9-0f25-30d2-a509-122c8fa5ce30
+  name: GenerateFlowFile/success/Funnel
+  source id: dff4abc1-cc2e-3b31-a389-fa133f71be54
+  source relationship names:
+  - success
+  destination id: b3ba295c-5947-3628-8991-930415e3e44d
+  max work queue size: 10000
+  max work queue data size: 1 GB
+  flowfile expiration: 0 sec
+  queue prioritizer class: ''
+- id: 89e5dc19-de02-330d-b1cf-8062c14a24f9
+  name: UpdateAttribute/success/01621001-e0d3-1e29-565c-5af8d1aeb56f
+  source id: 86a11150-4365-345f-b0f9-354723b24a83
+  source relationship names:
+  - success
+  destination id: 01621001-e0d3-1e29-565c-5af8d1aeb56f
+  max work queue size: 10000
+  max work queue data size: 1 GB
+  flowfile expiration: 0 sec
+  queue prioritizer class: ''
+Remote Process Groups:
+- id: 2cb9cb6f-492c-327f-af03-4c0f9f75722b
+  name: NiFi Flow
+  url: http://localhost:8080/nifi
+  comment: ''
+  timeout: 30 sec
+  yield period: 10 sec
+  transport protocol: HTTP
+  proxy host: ''
+  proxy port: ''
+  proxy user: ''
+  proxy password: ''
+  local network interface: ''
+  Input Ports:
+  - id: 01621001-e0d3-1e29-565c-5af8d1aeb56f
+    name: Remote-In
+    comment: ''
+    max concurrent tasks: 1
+    use compression: false
+  Output Ports: []
+NiFi Properties Overrides: {}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 72437d1..9b52f2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1131,7 +1131,7 @@ limitations under the License.
             <dependency>
                 <groupId>com.fasterxml.jackson.core</groupId>
                 <artifactId>jackson-databind</artifactId>
-                <version>2.6.1</version>
+                <version>2.9.1</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.spark</groupId>


[2/2] nifi-minifi git commit: MINIFI-449 Support for converting VersionedFlowSnapshot to YAML via minifi-toolkit - Upgrading Jackson databind to 2.9.1 for consistency with other Jackson modules

Posted by al...@apache.org.
MINIFI-449 Support for converting VersionedFlowSnapshot to YAML via minifi-toolkit
- Upgrading Jackson databind to 2.9.1 for consistency with other Jackson modules

This closes #121.

Signed-off-by: Aldrin Piri <al...@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/6e5b00a8
Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi/tree/6e5b00a8
Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi/diff/6e5b00a8

Branch: refs/heads/master
Commit: 6e5b00a8fb818b9b98d261bbafed32efb0b4871c
Parents: 270a308
Author: Bryan Bende <bb...@apache.org>
Authored: Wed Mar 28 13:24:58 2018 -0400
Committer: Aldrin Piri <al...@apache.org>
Committed: Mon Apr 2 11:38:53 2018 -0400

----------------------------------------------------------------------
 .../minifi-toolkit-configuration/pom.xml        |  14 +
 .../toolkit/configuration/ConfigMain.java       | 176 +----
 .../dto/FlowSnippetDTOEnricher.java             | 165 ++++
 .../registry/NiFiRegConfigSchemaFunction.java   | 158 ++++
 .../NiFiRegConnectionSchemaFunction.java        |  63 ++
 .../NiFiRegControllerServiceSchemaFunction.java |  51 ++
 .../NiFiRegFlowControllerSchemaFunction.java    |  51 ++
 .../registry/NiFiRegFunnelSchemaFunction.java   |  35 +
 .../registry/NiFiRegPortSchemaFunction.java     |  43 ++
 .../NiFiRegProcessorSchemaFunction.java         |  68 ++
 .../NiFiRegRemotePortSchemaFunction.java        |  45 ++
 ...NiFiRegRemoteProcessGroupSchemaFunction.java |  76 ++
 .../registry/VersionedProcessGroupEnricher.java | 159 ++++
 .../toolkit/configuration/ConfigMainTest.java   |  13 +
 .../resources/VersionedFlowSnapshot-Simple.json | 770 +++++++++++++++++++
 .../resources/VersionedFlowSnapshot-Simple.yml  | 291 +++++++
 pom.xml                                         |   2 +-
 17 files changed, 2042 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/pom.xml
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/pom.xml b/minifi-toolkit/minifi-toolkit-configuration/pom.xml
index c265a9b..d0c4362 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/pom.xml
+++ b/minifi-toolkit/minifi-toolkit-configuration/pom.xml
@@ -36,4 +36,18 @@ limitations under the License.
             <artifactId>nifi-framework-core</artifactId>
         </dependency>
     </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes combine.children="append">
+                        <exclude>src/test/resources/VersionedFlowSnapshot-Simple.json</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMain.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMain.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMain.java
index fef276b..1be6480 100644
--- a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMain.java
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/ConfigMain.java
@@ -17,25 +17,20 @@
 
 package org.apache.nifi.minifi.toolkit.configuration;
 
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.connectable.ConnectableType;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
 import org.apache.nifi.minifi.commons.schema.ConfigSchema;
 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.serialization.SchemaLoader;
 import org.apache.nifi.minifi.commons.schema.serialization.SchemaSaver;
 import org.apache.nifi.minifi.toolkit.configuration.dto.ConfigSchemaFunction;
-import org.apache.nifi.web.api.dto.ComponentDTO;
-import org.apache.nifi.web.api.dto.ConnectableDTO;
-import org.apache.nifi.web.api.dto.ConnectionDTO;
-import org.apache.nifi.web.api.dto.FlowSnippetDTO;
-import org.apache.nifi.web.api.dto.PortDTO;
-import org.apache.nifi.web.api.dto.ProcessGroupDTO;
-import org.apache.nifi.web.api.dto.ProcessorDTO;
-import org.apache.nifi.web.api.dto.RemoteProcessGroupContentsDTO;
-import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
-import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
+import org.apache.nifi.minifi.toolkit.configuration.dto.FlowSnippetDTOEnricher;
+import org.apache.nifi.minifi.toolkit.configuration.registry.NiFiRegConfigSchemaFunction;
+import org.apache.nifi.minifi.toolkit.configuration.registry.VersionedProcessGroupEnricher;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
 import org.apache.nifi.web.api.dto.TemplateDTO;
 
 import javax.xml.bind.JAXBContext;
@@ -46,21 +41,10 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
 import java.util.TreeMap;
 import java.util.function.BiFunction;
 import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static org.apache.nifi.minifi.commons.schema.common.CollectionUtil.nullToEmpty;
 
 public class ConfigMain {
     public static final int ERR_INVALID_ARGS = 1;
@@ -75,6 +59,7 @@ public class ConfigMain {
     public static final int SUCCESS = 0;
 
     public static final String TRANSFORM = "transform";
+    public static final String TRANSFORM_VFS = "transform-vfs";
     public static final String VALIDATE = "validate";
     public static final String UPGRADE = "upgrade";
     public static final String THERE_ARE_VALIDATION_ERRORS_WITH_THE_TEMPLATE_STILL_OUTPUTTING_YAML_BUT_IT_WILL_NEED_TO_BE_EDITED =
@@ -144,105 +129,13 @@ public class ConfigMain {
         System.out.println();
     }
 
-    private static void enrichFlowSnippetDTO(FlowSnippetDTO flowSnippetDTO, final String encodingVersion) {
-        List<FlowSnippetDTO> allFlowSnippets = getAllFlowSnippets(flowSnippetDTO);
-
-        Set<RemoteProcessGroupDTO> remoteProcessGroups = getAll(allFlowSnippets, FlowSnippetDTO::getRemoteProcessGroups).collect(Collectors.toSet());
-
-        Map<String, String> connectableNameMap = getAll(allFlowSnippets, FlowSnippetDTO::getProcessors).collect(Collectors.toMap(ComponentDTO::getId, ProcessorDTO::getName));
-        Map<String, String> rpgIdToTargetIdMap = new HashMap<>();
-
-        for (RemoteProcessGroupDTO remoteProcessGroupDTO : remoteProcessGroups) {
-            final RemoteProcessGroupContentsDTO contents = remoteProcessGroupDTO.getContents();
-            final Set<RemoteProcessGroupPortDTO> rpgInputPortDtos = nullToEmpty(contents.getInputPorts());
-            final Set<RemoteProcessGroupPortDTO> rpgOutputPortDtos = nullToEmpty(contents.getOutputPorts());
-
-            switch (encodingVersion) {
-                case "1.2":
-                    // Map all port DTOs to their respective targetIds
-                    rpgIdToTargetIdMap.putAll(
-                            Stream.concat(rpgInputPortDtos.stream(), rpgOutputPortDtos.stream())
-                                    .collect(Collectors.toMap(RemoteProcessGroupPortDTO::getId, RemoteProcessGroupPortDTO::getTargetId)));
-                    break;
-                default:
-                    break;
-            }
-
-            addConnectables(connectableNameMap, rpgInputPortDtos, RemoteProcessGroupPortDTO::getId, RemoteProcessGroupPortDTO::getId);
-            addConnectables(connectableNameMap, rpgOutputPortDtos, RemoteProcessGroupPortDTO::getId, RemoteProcessGroupPortDTO::getId);
-        }
-
-
-        addConnectables(connectableNameMap, getAll(allFlowSnippets, FlowSnippetDTO::getInputPorts).collect(Collectors.toList()), PortDTO::getId, PortDTO::getName);
-        addConnectables(connectableNameMap, getAll(allFlowSnippets, FlowSnippetDTO::getOutputPorts).collect(Collectors.toList()), PortDTO::getId, PortDTO::getName);
-
-        final Set<ConnectionDTO> connections = getAll(allFlowSnippets, FlowSnippetDTO::getConnections).collect(Collectors.toSet());
-
-        // Enrich connection endpoints using known names and overriding with targetIds for remote ports
-        for (ConnectionDTO connection : connections) {
-            setName(connectableNameMap, connection.getSource(), rpgIdToTargetIdMap);
-            setName(connectableNameMap, connection.getDestination(), rpgIdToTargetIdMap);
-        }
-
-        // Override any ids that are for Remote Ports to use their target Ids where available
-        connections.stream()
-                .flatMap(connectionDTO -> Stream.of(connectionDTO.getSource(), connectionDTO.getDestination()))
-                .filter(connectable -> connectable.getType().equals(ConnectableType.REMOTE_OUTPUT_PORT.toString()) || connectable.getType().equals(ConnectableType.REMOTE_INPUT_PORT.toString()))
-                .forEach(connectable -> connectable.setId(Optional.ofNullable(rpgIdToTargetIdMap.get(connectable.getId())).orElse(connectable.getId())));
-
-        // Establish unique names for connections
-        for (ConnectionDTO connection : connections) {
-            if (StringUtil.isNullOrEmpty(connection.getName())) {
-                StringBuilder name = new StringBuilder();
-                ConnectableDTO connectionSource = connection.getSource();
-                name.append(determineValueForConnectable(connectionSource, rpgIdToTargetIdMap));
-
-                name.append("/");
-                if (connection.getSelectedRelationships() != null && connection.getSelectedRelationships().size() > 0) {
-                    name.append(connection.getSelectedRelationships().iterator().next());
-                }
-
-                name.append("/");
-                ConnectableDTO connectionDestination = connection.getDestination();
-                name.append(determineValueForConnectable(connectionDestination, rpgIdToTargetIdMap));
-
-                connection.setName(name.toString());
-            }
-        }
-        nullToEmpty(flowSnippetDTO.getProcessGroups()).stream().map(ProcessGroupDTO::getContents).forEach(snippetDTO -> ConfigMain.enrichFlowSnippetDTO(snippetDTO, encodingVersion));
-    }
-
-    private static String determineValueForConnectable(ConnectableDTO connectable, Map<String, String> idOverrideMap) {
-        String connectionName = "";
-        if (connectable != null) {
-            connectionName = connectable.getName();
-            // If no name is specified, determine the appropriate id to use, preferring any overrides specified
-            if (StringUtils.isBlank(connectionName)) {
-                connectionName = idOverrideMap.containsKey(connectable.getId()) ? idOverrideMap.get(connectable.getId()) : connectable.getId();
-            }
-        }
-        return connectionName;
-    }
-
-    private static <T> Stream<T> getAll(List<FlowSnippetDTO> allFlowSnippets, Function<FlowSnippetDTO, Collection<T>> accessor) {
-        return allFlowSnippets.stream().flatMap(f -> accessor.apply(f).stream()).filter(Objects::nonNull);
-    }
-
-    private static List<FlowSnippetDTO> getAllFlowSnippets(FlowSnippetDTO flowSnippetDTO) {
-        List<FlowSnippetDTO> result = new ArrayList<>();
-        getAllFlowSnippets(flowSnippetDTO, result);
-        return result;
-    }
-
-    private static void getAllFlowSnippets(FlowSnippetDTO flowSnippetDTO, List<FlowSnippetDTO> result) {
-        result.add(flowSnippetDTO);
-        nullToEmpty(flowSnippetDTO.getProcessGroups()).stream().map(ProcessGroupDTO::getContents).forEach(f -> getAllFlowSnippets(f, result));
-    }
-
     public static ConfigSchema transformTemplateToSchema(InputStream source) throws JAXBException, IOException {
         try {
             TemplateDTO templateDTO = (TemplateDTO) JAXBContext.newInstance(TemplateDTO.class).createUnmarshaller().unmarshal(source);
-            enrichFlowSnippetDTO(templateDTO.getSnippet(), templateDTO.getEncodingVersion());
+
+            FlowSnippetDTOEnricher enricher = new FlowSnippetDTOEnricher();
+            enricher.enrich(templateDTO.getSnippet(), templateDTO.getEncodingVersion());
+
             ConfigSchema configSchema = new ConfigSchemaFunction().apply(templateDTO);
             return configSchema;
         } finally {
@@ -250,27 +143,29 @@ public class ConfigMain {
         }
     }
 
-    private static void setName(Map<String, String> connectableNameMap, ConnectableDTO connectableDTO, Map<String, String> nameOverrides) {
-        if (connectableDTO != null) {
-            final String name = connectableNameMap.get(connectableDTO.getId());
-            if (name != null) {
-                connectableDTO.setName(Optional.ofNullable(nameOverrides.get(connectableDTO.getId())).orElse(name));
-            }
+    public static ConfigSchema transformVersionedFlowSnapshotToSchema(InputStream source) throws IOException {
+        try {
+            final ObjectMapper objectMapper = new ObjectMapper();
+            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+            objectMapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(objectMapper.getTypeFactory()));
+            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+            final VersionedFlowSnapshot versionedFlowSnapshot = objectMapper.readValue(source, VersionedFlowSnapshot.class);
+            return transformVersionedFlowSnapshotToSchema(versionedFlowSnapshot);
+        } finally {
+            source.close();
         }
     }
 
-    private static <T> void addConnectables(Map<String, String> connectableNameMap, Collection<T> hasIdAndNames, Function<T, String> idGetter, Function<T, String> nameGetter) {
-        if (hasIdAndNames != null) {
-            for (T hasIdAndName : hasIdAndNames) {
-                String id = idGetter.apply(hasIdAndName);
-                String name = nameGetter.apply(hasIdAndName);
-                if (!StringUtil.isNullOrEmpty(name)) {
-                    connectableNameMap.put(id, name);
-                }
-            }
-        }
+    public static ConfigSchema transformVersionedFlowSnapshotToSchema(VersionedFlowSnapshot versionedFlowSnapshot) {
+        VersionedProcessGroupEnricher enricher = new VersionedProcessGroupEnricher();
+        enricher.enrich(versionedFlowSnapshot.getFlowContents());
+
+        ConfigSchema configSchema = new NiFiRegConfigSchemaFunction().apply(versionedFlowSnapshot);
+        return configSchema;
     }
 
+
     public int upgrade(String[] args) {
         if (args.length != 3) {
             printUpgradeUsage();
@@ -347,7 +242,13 @@ public class ConfigMain {
         ConfigSchema configSchema = null;
         try (InputStream inputStream = pathInputStreamFactory.create(args[1])) {
             try {
-                configSchema = transformTemplateToSchema(inputStream);
+                // both transform commands call this method, so determine which transform is being done
+                if (TRANSFORM_VFS.equals(args[0])) {
+                    configSchema = transformVersionedFlowSnapshotToSchema(inputStream);
+                }  else {
+                    configSchema = transformTemplateToSchema(inputStream);
+                }
+
                 if (!configSchema.isValid()) {
                     System.out.println(THERE_ARE_VALIDATION_ERRORS_WITH_THE_TEMPLATE_STILL_OUTPUTTING_YAML_BUT_IT_WILL_NEED_TO_BE_EDITED);
                     configSchema.getValidationIssues().forEach(System.out::println);
@@ -430,6 +331,7 @@ public class ConfigMain {
     public Map<String, Command> createCommandMap() {
         Map<String, Command> result = new TreeMap<>();
         result.put(TRANSFORM, new Command(this::transform, "Transform template xml into MiNiFi config YAML"));
+        result.put(TRANSFORM_VFS, new Command(this::transform, "Transform VersionedFlowSnapshot JSON into MiNiFi config YAML"));
         result.put(VALIDATE, new Command(this::validate, "Validate config YAML"));
         result.put(UPGRADE, new Command(this::upgrade, "Upgrade config YAML to current version (" + ConfigSchema.CONFIG_VERSION + ")"));
         return result;

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/FlowSnippetDTOEnricher.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/FlowSnippetDTOEnricher.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/FlowSnippetDTOEnricher.java
new file mode 100644
index 0000000..487db2d
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/dto/FlowSnippetDTOEnricher.java
@@ -0,0 +1,165 @@
+/*
+ * 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.commons.lang3.StringUtils;
+import org.apache.nifi.connectable.ConnectableType;
+import org.apache.nifi.minifi.commons.schema.common.StringUtil;
+import org.apache.nifi.web.api.dto.ComponentDTO;
+import org.apache.nifi.web.api.dto.ConnectableDTO;
+import org.apache.nifi.web.api.dto.ConnectionDTO;
+import org.apache.nifi.web.api.dto.FlowSnippetDTO;
+import org.apache.nifi.web.api.dto.PortDTO;
+import org.apache.nifi.web.api.dto.ProcessGroupDTO;
+import org.apache.nifi.web.api.dto.ProcessorDTO;
+import org.apache.nifi.web.api.dto.RemoteProcessGroupContentsDTO;
+import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
+import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.apache.nifi.minifi.commons.schema.common.CollectionUtil.nullToEmpty;
+
+public class FlowSnippetDTOEnricher {
+
+    public void enrich(FlowSnippetDTO flowSnippetDTO, final String encodingVersion) {
+        List<FlowSnippetDTO> allFlowSnippets = getAllFlowSnippets(flowSnippetDTO);
+
+        Set<RemoteProcessGroupDTO> remoteProcessGroups = getAll(allFlowSnippets, FlowSnippetDTO::getRemoteProcessGroups).collect(Collectors.toSet());
+
+        Map<String, String> connectableNameMap = getAll(allFlowSnippets, FlowSnippetDTO::getProcessors).collect(Collectors.toMap(ComponentDTO::getId, ProcessorDTO::getName));
+        Map<String, String> rpgIdToTargetIdMap = new HashMap<>();
+
+        for (RemoteProcessGroupDTO remoteProcessGroupDTO : remoteProcessGroups) {
+            final RemoteProcessGroupContentsDTO contents = remoteProcessGroupDTO.getContents();
+            final Set<RemoteProcessGroupPortDTO> rpgInputPortDtos = nullToEmpty(contents.getInputPorts());
+            final Set<RemoteProcessGroupPortDTO> rpgOutputPortDtos = nullToEmpty(contents.getOutputPorts());
+
+            switch (encodingVersion) {
+                case "1.2":
+                    // Map all port DTOs to their respective targetIds
+                    rpgIdToTargetIdMap.putAll(
+                            Stream.concat(rpgInputPortDtos.stream(), rpgOutputPortDtos.stream())
+                                    .collect(Collectors.toMap(RemoteProcessGroupPortDTO::getId, RemoteProcessGroupPortDTO::getTargetId)));
+                    break;
+                default:
+                    break;
+            }
+
+            addConnectables(connectableNameMap, rpgInputPortDtos, RemoteProcessGroupPortDTO::getId, RemoteProcessGroupPortDTO::getId);
+            addConnectables(connectableNameMap, rpgOutputPortDtos, RemoteProcessGroupPortDTO::getId, RemoteProcessGroupPortDTO::getId);
+        }
+
+
+        addConnectables(connectableNameMap, getAll(allFlowSnippets, FlowSnippetDTO::getInputPorts).collect(Collectors.toList()), PortDTO::getId, PortDTO::getName);
+        addConnectables(connectableNameMap, getAll(allFlowSnippets, FlowSnippetDTO::getOutputPorts).collect(Collectors.toList()), PortDTO::getId, PortDTO::getName);
+
+        final Set<ConnectionDTO> connections = getAll(allFlowSnippets, FlowSnippetDTO::getConnections).collect(Collectors.toSet());
+
+        // Enrich connection endpoints using known names and overriding with targetIds for remote ports
+        for (ConnectionDTO connection : connections) {
+            setName(connectableNameMap, connection.getSource(), rpgIdToTargetIdMap);
+            setName(connectableNameMap, connection.getDestination(), rpgIdToTargetIdMap);
+        }
+
+        // Override any ids that are for Remote Ports to use their target Ids where available
+        connections.stream()
+                .flatMap(connectionDTO -> Stream.of(connectionDTO.getSource(), connectionDTO.getDestination()))
+                .filter(connectable -> connectable.getType().equals(ConnectableType.REMOTE_OUTPUT_PORT.toString()) || connectable.getType().equals(ConnectableType.REMOTE_INPUT_PORT.toString()))
+                .forEach(connectable -> connectable.setId(Optional.ofNullable(rpgIdToTargetIdMap.get(connectable.getId())).orElse(connectable.getId())));
+
+        // Establish unique names for connections
+        for (ConnectionDTO connection : connections) {
+            if (StringUtil.isNullOrEmpty(connection.getName())) {
+                StringBuilder name = new StringBuilder();
+                ConnectableDTO connectionSource = connection.getSource();
+                name.append(determineValueForConnectable(connectionSource, rpgIdToTargetIdMap));
+
+                name.append("/");
+                if (connection.getSelectedRelationships() != null && connection.getSelectedRelationships().size() > 0) {
+                    name.append(connection.getSelectedRelationships().iterator().next());
+                }
+
+                name.append("/");
+                ConnectableDTO connectionDestination = connection.getDestination();
+                name.append(determineValueForConnectable(connectionDestination, rpgIdToTargetIdMap));
+
+                connection.setName(name.toString());
+            }
+        }
+        nullToEmpty(flowSnippetDTO.getProcessGroups()).stream().map(ProcessGroupDTO::getContents).forEach(snippetDTO -> enrich(snippetDTO, encodingVersion));
+    }
+
+    private static String determineValueForConnectable(ConnectableDTO connectable, Map<String, String> idOverrideMap) {
+        String connectionName = "";
+        if (connectable != null) {
+            connectionName = connectable.getName();
+            // If no name is specified, determine the appropriate id to use, preferring any overrides specified
+            if (StringUtils.isBlank(connectionName)) {
+                connectionName = idOverrideMap.containsKey(connectable.getId()) ? idOverrideMap.get(connectable.getId()) : connectable.getId();
+            }
+        }
+        return connectionName;
+    }
+
+    private static <T> Stream<T> getAll(List<FlowSnippetDTO> allFlowSnippets, Function<FlowSnippetDTO, Collection<T>> accessor) {
+        return allFlowSnippets.stream().flatMap(f -> accessor.apply(f).stream()).filter(Objects::nonNull);
+    }
+
+    private static List<FlowSnippetDTO> getAllFlowSnippets(FlowSnippetDTO flowSnippetDTO) {
+        List<FlowSnippetDTO> result = new ArrayList<>();
+        getAllFlowSnippets(flowSnippetDTO, result);
+        return result;
+    }
+
+    private static void getAllFlowSnippets(FlowSnippetDTO flowSnippetDTO, List<FlowSnippetDTO> result) {
+        result.add(flowSnippetDTO);
+        nullToEmpty(flowSnippetDTO.getProcessGroups()).stream().map(ProcessGroupDTO::getContents).forEach(f -> getAllFlowSnippets(f, result));
+    }
+
+    private static void setName(Map<String, String> connectableNameMap, ConnectableDTO connectableDTO, Map<String, String> nameOverrides) {
+        if (connectableDTO != null) {
+            final String name = connectableNameMap.get(connectableDTO.getId());
+            if (name != null) {
+                connectableDTO.setName(Optional.ofNullable(nameOverrides.get(connectableDTO.getId())).orElse(name));
+            }
+        }
+    }
+
+    private static <T> void addConnectables(Map<String, String> connectableNameMap, Collection<T> hasIdAndNames, Function<T, String> idGetter, Function<T, String> nameGetter) {
+        if (hasIdAndNames != null) {
+            for (T hasIdAndName : hasIdAndNames) {
+                String id = idGetter.apply(hasIdAndName);
+                String name = nameGetter.apply(hasIdAndName);
+                if (!StringUtil.isNullOrEmpty(name)) {
+                    connectableNameMap.put(id, name);
+                }
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConfigSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConfigSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConfigSchemaFunction.java
new file mode 100644
index 0000000..e2c8bdf
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConfigSchemaFunction.java
@@ -0,0 +1,158 @@
+/*
+ * 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.registry;
+
+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;
+import org.apache.nifi.minifi.commons.schema.ProcessorSchema;
+import org.apache.nifi.minifi.commons.schema.RemoteProcessGroupSchema;
+import org.apache.nifi.minifi.commons.schema.common.CollectionUtil;
+import org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys;
+import org.apache.nifi.minifi.commons.schema.common.StringUtil;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
+import org.apache.nifi.registry.flow.VersionedProcessGroup;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+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.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;
+
+public class NiFiRegConfigSchemaFunction implements Function<VersionedFlowSnapshot, ConfigSchema> {
+
+    private final NiFiRegFlowControllerSchemaFunction flowControllerSchemaFunction;
+    private final NiFiRegProcessorSchemaFunction processorSchemaFunction;
+    private final NiFiRegControllerServiceSchemaFunction controllerServiceSchemaFunction;
+    private final NiFiRegConnectionSchemaFunction connectionSchemaFunction;
+    private final NiFiRegFunnelSchemaFunction funnelSchemaFunction;
+    private final NiFiRegRemoteProcessGroupSchemaFunction remoteProcessGroupSchemaFunction;
+    private final NiFiRegPortSchemaFunction inputPortSchemaFunction;
+    private final NiFiRegPortSchemaFunction outputPortSchemaFunction;
+
+    public NiFiRegConfigSchemaFunction() {
+        this(
+            new NiFiRegFlowControllerSchemaFunction(),
+            new NiFiRegProcessorSchemaFunction(),
+            new NiFiRegControllerServiceSchemaFunction(),
+            new NiFiRegConnectionSchemaFunction(),
+            new NiFiRegFunnelSchemaFunction(),
+            new NiFiRegRemoteProcessGroupSchemaFunction(new NiFiRegRemotePortSchemaFunction()),
+            new NiFiRegPortSchemaFunction(INPUT_PORTS_KEY),
+            new NiFiRegPortSchemaFunction(OUTPUT_PORTS_KEY)
+        );
+    }
+
+    public NiFiRegConfigSchemaFunction(final NiFiRegFlowControllerSchemaFunction flowControllerSchemaFunction,
+                                       final NiFiRegProcessorSchemaFunction processorSchemaFunction,
+                                       final NiFiRegControllerServiceSchemaFunction controllerServiceSchemaFunction,
+                                       final NiFiRegConnectionSchemaFunction connectionSchemaFunction,
+                                       final NiFiRegFunnelSchemaFunction funnelSchemaFunction,
+                                       final NiFiRegRemoteProcessGroupSchemaFunction remoteProcessGroupSchemaFunction,
+                                       final NiFiRegPortSchemaFunction inputPortSchemaFunction,
+                                       final NiFiRegPortSchemaFunction outputPortSchemaFunction) {
+        this.flowControllerSchemaFunction = flowControllerSchemaFunction;
+        this.processorSchemaFunction = processorSchemaFunction;
+        this.controllerServiceSchemaFunction = controllerServiceSchemaFunction;
+        this.connectionSchemaFunction = connectionSchemaFunction;
+        this.funnelSchemaFunction = funnelSchemaFunction;
+        this.remoteProcessGroupSchemaFunction = remoteProcessGroupSchemaFunction;
+        this.inputPortSchemaFunction = inputPortSchemaFunction;
+        this.outputPortSchemaFunction = outputPortSchemaFunction;
+    }
+
+    @Override
+    public ConfigSchema apply(final VersionedFlowSnapshot versionedFlowSnapshot) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(CommonPropertyKeys.FLOW_CONTROLLER_PROPS_KEY, flowControllerSchemaFunction.apply(versionedFlowSnapshot).toMap());
+
+        VersionedProcessGroup versionedProcessGroup = versionedFlowSnapshot.getFlowContents();
+        addVersionedProcessGroup(map, versionedProcessGroup);
+
+        return new ConfigSchema(map);
+    }
+
+    protected void addVersionedProcessGroup(Map<String, Object> map, VersionedProcessGroup versionedProcessGroup) {
+        addVersionedProcessGroup(map, null, null, versionedProcessGroup);
+    }
+
+    protected Map<String, Object> addVersionedProcessGroup(Map<String, Object> map, String id, String name, VersionedProcessGroup versionedProcessGroup) {
+        if (!StringUtil.isNullOrEmpty(id)) {
+            map.put(ID_KEY, id);
+        }
+
+        if (!StringUtil.isNullOrEmpty(name)) {
+            map.put(NAME_KEY, name);
+        }
+
+        map.put(CommonPropertyKeys.PROCESSORS_KEY, nullToEmpty(versionedProcessGroup.getProcessors()).stream()
+                .map(processorSchemaFunction)
+                .sorted(Comparator.comparing(ProcessorSchema::getName))
+                .map(ProcessorSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(CommonPropertyKeys.CONTROLLER_SERVICES_KEY, nullToEmpty(versionedProcessGroup.getControllerServices()).stream()
+                .map(controllerServiceSchemaFunction)
+                .sorted(Comparator.comparing(ControllerServiceSchema::getName))
+                .map(ControllerServiceSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(CommonPropertyKeys.CONNECTIONS_KEY, nullToEmpty(versionedProcessGroup.getConnections()).stream()
+                .map(connectionSchemaFunction)
+                .sorted(Comparator.comparing(ConnectionSchema::getName))
+                .map(ConnectionSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(CommonPropertyKeys.FUNNELS_KEY, CollectionUtil.nullToEmpty(versionedProcessGroup.getFunnels()).stream()
+                .map(funnelSchemaFunction)
+                .sorted(Comparator.comparing(FunnelSchema::getId))
+                .map(FunnelSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(CommonPropertyKeys.REMOTE_PROCESS_GROUPS_KEY, nullToEmpty(versionedProcessGroup.getRemoteProcessGroups()).stream()
+                .map(remoteProcessGroupSchemaFunction)
+                .sorted(Comparator.comparing(RemoteProcessGroupSchema::getName))
+                .map(RemoteProcessGroupSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(INPUT_PORTS_KEY, nullToEmpty(versionedProcessGroup.getInputPorts()).stream()
+                .map(inputPortSchemaFunction)
+                .sorted(Comparator.comparing(PortSchema::getName))
+                .map(PortSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(OUTPUT_PORTS_KEY, nullToEmpty(versionedProcessGroup.getOutputPorts()).stream()
+                .map(outputPortSchemaFunction)
+                .sorted(Comparator.comparing(PortSchema::getName))
+                .map(PortSchema::toMap)
+                .collect(Collectors.toList()));
+
+        map.put(ProcessGroupSchema.PROCESS_GROUPS_KEY, nullToEmpty(versionedProcessGroup.getProcessGroups()).stream()
+                .map(p -> addVersionedProcessGroup(new HashMap<>(), p.getIdentifier(), p.getName(), p)).collect(Collectors.toList()));
+
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConnectionSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConnectionSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConnectionSchemaFunction.java
new file mode 100644
index 0000000..669d9ce
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegConnectionSchemaFunction.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.minifi.toolkit.configuration.registry;
+
+import org.apache.nifi.connectable.ConnectableType;
+import org.apache.nifi.minifi.commons.schema.ConnectionSchema;
+import org.apache.nifi.registry.flow.VersionedConnection;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+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.CONNECTIONS_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;
+
+public class NiFiRegConnectionSchemaFunction implements Function<VersionedConnection, ConnectionSchema> {
+
+    @Override
+    public ConnectionSchema apply(final VersionedConnection versionedConnection) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(ID_KEY, versionedConnection.getIdentifier());
+        map.put(NAME_KEY, versionedConnection.getName());
+        map.put(ConnectionSchema.SOURCE_ID_KEY, versionedConnection.getSource().getId());
+        Set<String> selectedRelationships = nullToEmpty(versionedConnection.getSelectedRelationships());
+        map.put(ConnectionSchema.SOURCE_RELATIONSHIP_NAMES_KEY, selectedRelationships.stream().sorted().collect(Collectors.toList()));
+        map.put(ConnectionSchema.DESTINATION_ID_KEY, versionedConnection.getDestination().getId());
+
+        map.put(ConnectionSchema.MAX_WORK_QUEUE_SIZE_KEY, versionedConnection.getBackPressureObjectThreshold());
+        map.put(ConnectionSchema.MAX_WORK_QUEUE_DATA_SIZE_KEY, versionedConnection.getBackPressureDataSizeThreshold());
+        map.put(ConnectionSchema.FLOWFILE_EXPIRATION__KEY, versionedConnection.getFlowFileExpiration());
+        List<String> queuePrioritizers = nullToEmpty(versionedConnection.getPrioritizers());
+        if (queuePrioritizers.size() > 0) {
+            map.put(ConnectionSchema.QUEUE_PRIORITIZER_CLASS_KEY, queuePrioritizers.get(0));
+        }
+        ConnectionSchema connectionSchema = new ConnectionSchema(map);
+        if (ConnectableType.FUNNEL.name().equals(versionedConnection.getSource().getType())) {
+            connectionSchema.addValidationIssue("Connection " + versionedConnection.getName() + " has type " + ConnectableType.FUNNEL.name() + " which is not supported by MiNiFi");
+        }
+        if (queuePrioritizers.size() > 1) {
+            connectionSchema.addValidationIssue(ConnectionSchema.QUEUE_PRIORITIZER_CLASS_KEY, CONNECTIONS_KEY, " has more than one queue prioritizer");
+        }
+        return connectionSchema;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegControllerServiceSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegControllerServiceSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegControllerServiceSchemaFunction.java
new file mode 100644
index 0000000..1081dac
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegControllerServiceSchemaFunction.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.registry;
+
+import org.apache.nifi.minifi.commons.schema.ControllerServiceSchema;
+import org.apache.nifi.registry.flow.VersionedControllerService;
+
+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 NiFiRegControllerServiceSchemaFunction implements Function<VersionedControllerService, ControllerServiceSchema> {
+
+    @Override
+    public ControllerServiceSchema apply(final VersionedControllerService versionedControllerService) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(NAME_KEY, versionedControllerService.getName());
+        map.put(ID_KEY, versionedControllerService.getIdentifier());
+        map.put(TYPE_KEY, versionedControllerService.getType());
+
+        map.put(PROPERTIES_KEY, new HashMap<>(nullToEmpty(versionedControllerService.getProperties())));
+
+        String annotationData = versionedControllerService.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/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFlowControllerSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFlowControllerSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFlowControllerSchemaFunction.java
new file mode 100644
index 0000000..d1caef9
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFlowControllerSchemaFunction.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.registry;
+
+import org.apache.nifi.minifi.commons.schema.FlowControllerSchema;
+import org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+public class NiFiRegFlowControllerSchemaFunction implements Function<VersionedFlowSnapshot, FlowControllerSchema> {
+
+    @Override
+    public FlowControllerSchema apply(final VersionedFlowSnapshot versionedFlowSnapshot) {
+
+        // If the VersionedFlowSnapshot came directly from NiFi Registry without modification, as would be the
+        // case with C2 server, then we should have a non-null VersionedFlow, but if we're using a snapshot that
+        // was export from another tool like the CLI, the flow may be null'd out, so fall back to root group.
+
+        String name;
+        String description;
+        if (versionedFlowSnapshot.getFlow() == null) {
+            name = versionedFlowSnapshot.getFlowContents().getName();
+            description = versionedFlowSnapshot.getFlowContents().getComments();
+        } else {
+            name = versionedFlowSnapshot.getFlow().getName();
+            description = versionedFlowSnapshot.getFlow().getDescription();
+        }
+
+        Map<String, Object> map = new HashMap<>();
+        map.put(CommonPropertyKeys.NAME_KEY, name);
+        map.put(CommonPropertyKeys.COMMENT_KEY, description);
+        return new FlowControllerSchema(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFunnelSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFunnelSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFunnelSchemaFunction.java
new file mode 100644
index 0000000..79df397
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegFunnelSchemaFunction.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.minifi.toolkit.configuration.registry;
+
+import org.apache.nifi.minifi.commons.schema.FunnelSchema;
+import org.apache.nifi.registry.flow.VersionedFunnel;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
+
+public class NiFiRegFunnelSchemaFunction implements Function<VersionedFunnel, FunnelSchema> {
+    @Override
+    public FunnelSchema apply(VersionedFunnel versionedFunnel) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(ID_KEY, versionedFunnel.getIdentifier());
+        return new FunnelSchema(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegPortSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegPortSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegPortSchemaFunction.java
new file mode 100644
index 0000000..de86387
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegPortSchemaFunction.java
@@ -0,0 +1,43 @@
+/*
+ * 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.registry;
+
+import org.apache.nifi.minifi.commons.schema.PortSchema;
+import org.apache.nifi.registry.flow.VersionedPort;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
+
+public class NiFiRegPortSchemaFunction implements Function<VersionedPort, PortSchema> {
+    private final String wrapperName;
+
+    public NiFiRegPortSchemaFunction(String wrapperName) {
+        this.wrapperName = wrapperName;
+    }
+
+    @Override
+    public PortSchema apply(VersionedPort versionedPort) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(ID_KEY, versionedPort.getIdentifier());
+        map.put(NAME_KEY, versionedPort.getName());
+        return new PortSchema(map, wrapperName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegProcessorSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegProcessorSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegProcessorSchemaFunction.java
new file mode 100644
index 0000000..536e8d0
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegProcessorSchemaFunction.java
@@ -0,0 +1,68 @@
+/*
+ * 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.registry;
+
+import org.apache.nifi.minifi.commons.schema.ProcessorSchema;
+import org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys;
+import org.apache.nifi.registry.flow.VersionedProcessor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+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.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;
+
+public class NiFiRegProcessorSchemaFunction implements Function<VersionedProcessor, ProcessorSchema> {
+    @Override
+    public ProcessorSchema apply(final VersionedProcessor versionedProcessor) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(NAME_KEY, versionedProcessor.getName());
+        map.put(ID_KEY, versionedProcessor.getIdentifier());
+        map.put(CLASS_KEY, versionedProcessor.getType());
+        map.put(SCHEDULING_STRATEGY_KEY, versionedProcessor.getSchedulingStrategy());
+        map.put(SCHEDULING_PERIOD_KEY, versionedProcessor.getSchedulingPeriod());
+
+        map.put(CommonPropertyKeys.MAX_CONCURRENT_TASKS_KEY, versionedProcessor.getConcurrentlySchedulableTaskCount());
+        map.put(ProcessorSchema.PENALIZATION_PERIOD_KEY, versionedProcessor.getPenaltyDuration());
+        map.put(CommonPropertyKeys.YIELD_PERIOD_KEY, versionedProcessor.getYieldDuration());
+        Long runDurationMillis = versionedProcessor.getRunDurationMillis();
+        if (runDurationMillis != null) {
+            map.put(ProcessorSchema.RUN_DURATION_NANOS_KEY, runDurationMillis * 1000);
+        }
+
+        final List<String> autoTerminateRelationships = new ArrayList<>(nullToEmpty(versionedProcessor.getAutoTerminatedRelationships()));
+        map.put(ProcessorSchema.AUTO_TERMINATED_RELATIONSHIPS_LIST_KEY, autoTerminateRelationships);
+
+        map.put(PROPERTIES_KEY, new HashMap<>(nullToEmpty(versionedProcessor.getProperties())));
+
+        String annotationData = versionedProcessor.getAnnotationData();
+        if(annotationData != null && !annotationData.isEmpty()) {
+            map.put(ANNOTATION_DATA_KEY, annotationData);
+        }
+
+        return new ProcessorSchema(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemotePortSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemotePortSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemotePortSchemaFunction.java
new file mode 100644
index 0000000..6034e30
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemotePortSchemaFunction.java
@@ -0,0 +1,45 @@
+/*
+ * 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.registry;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.minifi.commons.schema.RemotePortSchema;
+import org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys;
+import org.apache.nifi.registry.flow.VersionedRemoteGroupPort;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.ID_KEY;
+import static org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys.NAME_KEY;
+
+public class NiFiRegRemotePortSchemaFunction implements Function<VersionedRemoteGroupPort, RemotePortSchema> {
+    @Override
+    public RemotePortSchema apply(VersionedRemoteGroupPort versionedRemoteGroupPort) {
+        Map<String, Object> map = new HashMap<>();
+        // If a targetId is specified, it takes precedence over the original id
+        final String targetId = versionedRemoteGroupPort.getTargetId();
+        map.put(ID_KEY, StringUtils.isNotBlank(targetId) ? targetId : versionedRemoteGroupPort.getIdentifier());
+        map.put(NAME_KEY, versionedRemoteGroupPort.getName());
+
+        map.put(CommonPropertyKeys.COMMENT_KEY, versionedRemoteGroupPort.getComments());
+        map.put(CommonPropertyKeys.MAX_CONCURRENT_TASKS_KEY, versionedRemoteGroupPort.getConcurrentlySchedulableTaskCount());
+        map.put(CommonPropertyKeys.USE_COMPRESSION_KEY, versionedRemoteGroupPort.isUseCompression());
+        return new RemotePortSchema(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemoteProcessGroupSchemaFunction.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemoteProcessGroupSchemaFunction.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemoteProcessGroupSchemaFunction.java
new file mode 100644
index 0000000..a8a5248
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/NiFiRegRemoteProcessGroupSchemaFunction.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.minifi.toolkit.configuration.registry;
+
+import org.apache.nifi.minifi.commons.schema.RemotePortSchema;
+import org.apache.nifi.minifi.commons.schema.RemoteProcessGroupSchema;
+import org.apache.nifi.minifi.commons.schema.common.CommonPropertyKeys;
+import org.apache.nifi.registry.flow.VersionedRemoteGroupPort;
+import org.apache.nifi.registry.flow.VersionedRemoteProcessGroup;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class NiFiRegRemoteProcessGroupSchemaFunction implements Function<VersionedRemoteProcessGroup, RemoteProcessGroupSchema> {
+
+    private final NiFiRegRemotePortSchemaFunction remotePortSchemaFunction;
+
+    public NiFiRegRemoteProcessGroupSchemaFunction(NiFiRegRemotePortSchemaFunction remotePortSchemaFunction) {
+        this.remotePortSchemaFunction = remotePortSchemaFunction;
+    }
+    @Override
+    public RemoteProcessGroupSchema apply(VersionedRemoteProcessGroup versionedRemoteProcessGroup) {
+        Map<String, Object> map = new HashMap<>();
+        map.put(CommonPropertyKeys.ID_KEY, versionedRemoteProcessGroup.getIdentifier());
+        map.put(CommonPropertyKeys.NAME_KEY, versionedRemoteProcessGroup.getName());
+        map.put(RemoteProcessGroupSchema.URL_KEY, versionedRemoteProcessGroup.getTargetUri());
+
+        Set<VersionedRemoteGroupPort> inputPorts = versionedRemoteProcessGroup.getInputPorts();
+        if (inputPorts != null) {
+            map.put(CommonPropertyKeys.INPUT_PORTS_KEY, inputPorts.stream()
+                    .map(remotePortSchemaFunction)
+                    .map(RemotePortSchema::toMap)
+                    .collect(Collectors.toList()));
+        }
+
+        Set<VersionedRemoteGroupPort> outputPorts = versionedRemoteProcessGroup.getOutputPorts();
+        if (outputPorts != null) {
+            map.put(CommonPropertyKeys.OUTPUT_PORTS_KEY, outputPorts.stream()
+                    .map(remotePortSchemaFunction)
+                    .map(RemotePortSchema::toMap)
+                    .collect(Collectors.toList()));
+        }
+
+
+        map.put(CommonPropertyKeys.COMMENT_KEY, versionedRemoteProcessGroup.getComments());
+        map.put(RemoteProcessGroupSchema.TIMEOUT_KEY, versionedRemoteProcessGroup.getCommunicationsTimeout());
+        map.put(CommonPropertyKeys.YIELD_PERIOD_KEY, versionedRemoteProcessGroup.getYieldDuration());
+        map.put(RemoteProcessGroupSchema.TRANSPORT_PROTOCOL_KEY, versionedRemoteProcessGroup.getTransportProtocol());
+        map.put(RemoteProcessGroupSchema.PROXY_HOST_KEY, versionedRemoteProcessGroup.getProxyHost());
+        map.put(RemoteProcessGroupSchema.PROXY_PORT_KEY, versionedRemoteProcessGroup.getProxyPort());
+        map.put(RemoteProcessGroupSchema.PROXY_USER_KEY, versionedRemoteProcessGroup.getProxyUser());
+
+        // TODO - we don't have this in registry data model, most likely templates blank it out too?
+        //map.put(RemoteProcessGroupSchema.PROXY_PASSWORD_KEY, versionedRemoteProcessGroup.getProxyPassword());
+
+        map.put(RemoteProcessGroupSchema.LOCAL_NETWORK_INTERFACE_KEY, versionedRemoteProcessGroup.getLocalNetworkInterface());
+        return new RemoteProcessGroupSchema(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/VersionedProcessGroupEnricher.java
----------------------------------------------------------------------
diff --git a/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/VersionedProcessGroupEnricher.java b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/VersionedProcessGroupEnricher.java
new file mode 100644
index 0000000..29449aa
--- /dev/null
+++ b/minifi-toolkit/minifi-toolkit-configuration/src/main/java/org/apache/nifi/minifi/toolkit/configuration/registry/VersionedProcessGroupEnricher.java
@@ -0,0 +1,159 @@
+/*
+ * 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.registry;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.minifi.commons.schema.common.StringUtil;
+import org.apache.nifi.registry.flow.ConnectableComponent;
+import org.apache.nifi.registry.flow.ConnectableComponentType;
+import org.apache.nifi.registry.flow.VersionedComponent;
+import org.apache.nifi.registry.flow.VersionedConnection;
+import org.apache.nifi.registry.flow.VersionedPort;
+import org.apache.nifi.registry.flow.VersionedProcessGroup;
+import org.apache.nifi.registry.flow.VersionedRemoteGroupPort;
+import org.apache.nifi.registry.flow.VersionedRemoteProcessGroup;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.apache.nifi.minifi.commons.schema.common.CollectionUtil.nullToEmpty;
+
+public class VersionedProcessGroupEnricher {
+
+    public void enrich(final VersionedProcessGroup versionedProcessGroup) {
+        List<VersionedProcessGroup> allVersionedProcessGroups = getAllVersionedProcessGroups(versionedProcessGroup);
+
+        Set<VersionedRemoteProcessGroup> remoteProcessGroups = getAll(allVersionedProcessGroups, VersionedProcessGroup::getRemoteProcessGroups).collect(Collectors.toSet());
+
+        Map<String, String> connectableNameMap = getAll(allVersionedProcessGroups, VersionedProcessGroup::getProcessors)
+                .collect(Collectors.toMap(VersionedComponent::getIdentifier, VersionedComponent::getName));
+
+        Map<String, String> rpgIdToTargetIdMap = new HashMap<>();
+
+        for (VersionedRemoteProcessGroup remoteProcessGroup : remoteProcessGroups) {
+            final Set<VersionedRemoteGroupPort> rpgInputPorts = nullToEmpty(remoteProcessGroup.getInputPorts());
+            final Set<VersionedRemoteGroupPort> rpgOutputPorts = nullToEmpty(remoteProcessGroup.getOutputPorts());
+
+            // Map all port DTOs to their respective targetIds
+            rpgIdToTargetIdMap.putAll(
+                    Stream.concat(rpgInputPorts.stream(), rpgOutputPorts.stream())
+                            .collect(Collectors.toMap(VersionedRemoteGroupPort::getIdentifier, VersionedRemoteGroupPort::getTargetId)));
+
+            addConnectables(connectableNameMap, rpgInputPorts, VersionedRemoteGroupPort::getIdentifier, VersionedRemoteGroupPort::getIdentifier);
+            addConnectables(connectableNameMap, rpgOutputPorts, VersionedRemoteGroupPort::getIdentifier, VersionedRemoteGroupPort::getIdentifier);
+        }
+
+        addConnectables(connectableNameMap, getAll(allVersionedProcessGroups, VersionedProcessGroup::getInputPorts)
+                .collect(Collectors.toList()), VersionedPort::getIdentifier, VersionedPort::getName);
+
+        addConnectables(connectableNameMap, getAll(allVersionedProcessGroups, VersionedProcessGroup::getOutputPorts)
+                .collect(Collectors.toList()), VersionedPort::getIdentifier, VersionedPort::getName);
+
+        final Set<VersionedConnection> connections = getAll(allVersionedProcessGroups, VersionedProcessGroup::getConnections).collect(Collectors.toSet());
+
+        // Enrich connection endpoints using known names and overriding with targetIds for remote ports
+        for (VersionedConnection connection : connections) {
+            setName(connectableNameMap, connection.getSource(), rpgIdToTargetIdMap);
+            setName(connectableNameMap, connection.getDestination(), rpgIdToTargetIdMap);
+        }
+
+        // Override any ids that are for Remote Ports to use their target Ids where available
+        connections.stream()
+                .flatMap(connectionDTO -> Stream.of(connectionDTO.getSource(), connectionDTO.getDestination()))
+                .filter(connectable -> (connectable.getType() == ConnectableComponentType.REMOTE_OUTPUT_PORT || connectable.getType() == ConnectableComponentType.REMOTE_INPUT_PORT))
+                .forEach(connectable -> connectable.setId(Optional.ofNullable(rpgIdToTargetIdMap.get(connectable.getId())).orElse(connectable.getId())));
+
+        // Establish unique names for connections
+        for (VersionedConnection connection : connections) {
+            if (StringUtil.isNullOrEmpty(connection.getName())) {
+                StringBuilder name = new StringBuilder();
+                ConnectableComponent connectionSource = connection.getSource();
+                name.append(determineValueForConnectable(connectionSource, rpgIdToTargetIdMap));
+
+                name.append("/");
+                if (connection.getSelectedRelationships() != null && connection.getSelectedRelationships().size() > 0) {
+                    name.append(connection.getSelectedRelationships().iterator().next());
+                }
+
+                name.append("/");
+                ConnectableComponent connectionDestination = connection.getDestination();
+                name.append(determineValueForConnectable(connectionDestination, rpgIdToTargetIdMap));
+
+                connection.setName(name.toString());
+            }
+        }
+        nullToEmpty(versionedProcessGroup.getProcessGroups()).stream().forEach(pg -> enrich(pg));
+    }
+
+    private static String determineValueForConnectable(ConnectableComponent connectable, Map<String, String> idOverrideMap) {
+        String connectionName = "";
+        if (connectable != null) {
+            connectionName = connectable.getName();
+            // If no name is specified, determine the appropriate id to use, preferring any overrides specified
+            if (StringUtils.isBlank(connectionName)) {
+                connectionName = idOverrideMap.containsKey(connectable.getId()) ? idOverrideMap.get(connectable.getId()) : connectable.getId();
+            }
+        }
+        return connectionName;
+    }
+
+    private static <T> Stream<T> getAll(List<VersionedProcessGroup> allVersionedProcessGroups, Function<VersionedProcessGroup, Collection<T>> accessor) {
+        return allVersionedProcessGroups.stream().flatMap(f -> accessor.apply(f).stream()).filter(Objects::nonNull);
+    }
+
+    private static List<VersionedProcessGroup> getAllVersionedProcessGroups(VersionedProcessGroup versionedProcessGroup) {
+        List<VersionedProcessGroup> result = new ArrayList<>();
+        getAllVersionedProcessGroups(versionedProcessGroup, result);
+        return result;
+    }
+
+    private static void getAllVersionedProcessGroups(VersionedProcessGroup versionedProcessGroup, List<VersionedProcessGroup> result) {
+        result.add(versionedProcessGroup);
+        nullToEmpty(versionedProcessGroup.getProcessGroups()).stream().forEach(f -> getAllVersionedProcessGroups(f, result));
+    }
+
+    private static void setName(Map<String, String> connectableNameMap, ConnectableComponent connectable, Map<String, String> nameOverrides) {
+        if (connectable != null) {
+            final String name = connectableNameMap.get(connectable.getId());
+            if (name != null) {
+                connectable.setName(Optional.ofNullable(nameOverrides.get(connectable.getId())).orElse(name));
+            }
+        }
+    }
+
+    private static <T> void addConnectables(Map<String, String> connectableNameMap, Collection<T> hasIdAndNames, Function<T, String> idGetter, Function<T, String> nameGetter) {
+        if (hasIdAndNames != null) {
+            for (T hasIdAndName : hasIdAndNames) {
+                String id = idGetter.apply(hasIdAndName);
+                String name = nameGetter.apply(hasIdAndName);
+                if (!StringUtil.isNullOrEmpty(name)) {
+                    connectableNameMap.put(id, name);
+                }
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi/blob/6e5b00a8/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 12e44e3..ab940cf 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
@@ -282,6 +282,11 @@ public class ConfigMainTest {
         assertEquals(ConfigMain.ERR_INVALID_ARGS, configMain.execute(new String[]{ConfigMain.UPGRADE}));
     }
 
+    @Test
+    public void testTransformVersionedFlowSnapshotSimple() throws IOException, SchemaLoaderException {
+        transformVsfRoundTrip("VersionedFlowSnapshot-Simple");
+    }
+
     private void transformRoundTrip(String name) throws JAXBException, IOException, SchemaLoaderException {
         Map<String, Object> templateMap = ConfigMain.transformTemplateToSchema(getClass().getClassLoader().getResourceAsStream(name + ".xml")).toMap();
         Map<String, Object> yamlMap = SchemaLoader.loadYamlAsMap(getClass().getClassLoader().getResourceAsStream(name + ".yml"));
@@ -290,6 +295,14 @@ public class ConfigMainTest {
         testV1YmlIfPresent(name, yamlMap);
     }
 
+    private void transformVsfRoundTrip(String name) throws IOException, SchemaLoaderException {
+        Map<String, Object> templateMap = ConfigMain.transformVersionedFlowSnapshotToSchema(getClass().getClassLoader().getResourceAsStream(name + ".json")).toMap();
+        Map<String, Object> yamlMap = SchemaLoader.loadYamlAsMap(getClass().getClassLoader().getResourceAsStream(name + ".yml"));
+        assertNoMapDifferences(templateMap, yamlMap);
+        testV2YmlIfPresent(name, yamlMap);
+        testV1YmlIfPresent(name, yamlMap);
+    }
+
     private InputStream upgradeAndReturn(String name) throws FileNotFoundException {
         InputStream yamlV1Stream = getClass().getClassLoader().getResourceAsStream(name);
         if (yamlV1Stream == null) {