You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2017/08/22 19:51:00 UTC

[4/5] nifi-registry git commit: NIFIREG-7 Defining Provider API and framework for loading providers - Renaming nifi-registry-flow-data-model to nifi-registry-data-model - Implementing FileSystemFlowProvider & FileSystemMetadataProvider - Adding unit test

NIFIREG-7 Defining Provider API and framework for loading providers
- Renaming nifi-registry-flow-data-model to nifi-registry-data-model
- Implementing FileSystemFlowProvider & FileSystemMetadataProvider
- Adding unit tests for file system providers
- Injecting providers into test REST resource


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

Branch: refs/heads/master
Commit: 9eb0cef0169e084002725420415c57b327e86559
Parents: a520c75
Author: Bryan Bende <bb...@apache.org>
Authored: Tue Aug 8 17:19:59 2017 -0400
Committer: Bryan Bende <bb...@apache.org>
Committed: Mon Aug 21 14:18:40 2017 -0400

----------------------------------------------------------------------
 nifi-registry-assembly/pom.xml                  |   3 +
 nifi-registry-data-model/pom.xml                |  31 ++
 .../org/apache/nifi/registry/bucket/Bucket.java | 114 +++++
 .../nifi/registry/bucket/BucketObject.java      |  55 +++
 .../apache/nifi/registry/flow/BatchSize.java    |  53 +++
 .../org/apache/nifi/registry/flow/Bundle.java   |  83 ++++
 .../nifi/registry/flow/ComponentType.java       |  49 ++
 .../registry/flow/ConnectableComponent.java     |  73 +++
 .../registry/flow/ConnectableComponentType.java |  27 ++
 .../registry/flow/ControllerServiceAPI.java     |  65 +++
 .../org/apache/nifi/registry/flow/PortType.java |  23 +
 .../org/apache/nifi/registry/flow/Position.java |  58 +++
 .../flow/SiteToSiteTransportProtocol.java       |  23 +
 .../nifi/registry/flow/VersionedComponent.java  |  67 +++
 .../nifi/registry/flow/VersionedConnection.java | 139 ++++++
 .../flow/VersionedControllerService.java        | 108 +++++
 .../nifi/registry/flow/VersionedFlow.java       | 120 +++++
 .../registry/flow/VersionedFlowSnapshot.java    | 113 +++++
 .../nifi/registry/flow/VersionedFunnel.java     |  25 +
 .../nifi/registry/flow/VersionedLabel.java      |  75 +++
 .../nifi/registry/flow/VersionedPort.java       |  52 +++
 .../registry/flow/VersionedProcessGroup.java    | 123 +++++
 .../nifi/registry/flow/VersionedProcessor.java  | 169 +++++++
 .../registry/flow/VersionedRemoteGroupPort.java |  98 ++++
 .../flow/VersionedRemoteProcessGroup.java       | 177 ++++++++
 nifi-registry-flow-data-model/pom.xml           |  31 --
 .../apache/nifi/registry/flow/BatchSize.java    |  53 ---
 .../org/apache/nifi/registry/flow/Bucket.java   |  96 ----
 .../apache/nifi/registry/flow/BucketObject.java |  35 --
 .../org/apache/nifi/registry/flow/Bundle.java   |  83 ----
 .../nifi/registry/flow/ComponentType.java       |  49 --
 .../registry/flow/ConnectableComponent.java     |  73 ---
 .../registry/flow/ConnectableComponentType.java |  27 --
 .../registry/flow/ControllerServiceAPI.java     |  65 ---
 .../org/apache/nifi/registry/flow/PortType.java |  23 -
 .../org/apache/nifi/registry/flow/Position.java |  58 ---
 .../flow/SiteToSiteTransportProtocol.java       |  23 -
 .../nifi/registry/flow/VersionedComponent.java  |  67 ---
 .../nifi/registry/flow/VersionedConnection.java | 139 ------
 .../flow/VersionedControllerService.java        | 108 -----
 .../nifi/registry/flow/VersionedFlow.java       | 136 ------
 .../registry/flow/VersionedFlowSnapshot.java    |  93 ----
 .../nifi/registry/flow/VersionedFunnel.java     |  25 -
 .../nifi/registry/flow/VersionedLabel.java      |  75 ---
 .../nifi/registry/flow/VersionedPort.java       |  52 ---
 .../registry/flow/VersionedProcessGroup.java    | 123 -----
 .../nifi/registry/flow/VersionedProcessor.java  | 169 -------
 .../registry/flow/VersionedRemoteGroupPort.java |  98 ----
 .../flow/VersionedRemoteProcessGroup.java       | 177 --------
 nifi-registry-framework/pom.xml                 |  80 ++++
 .../flow/StandardFlowSnapshotContext.java       | 140 ++++++
 .../nifi/registry/provider/ProviderFactory.java |  44 ++
 .../provider/ProviderFactoryException.java      |  38 ++
 .../StandardProviderConfigurationContext.java   |  39 ++
 .../provider/StandardProviderFactory.java       | 178 ++++++++
 .../src/main/xsd/providers.xsd                  |  51 +++
 .../flow/TestStandardFlowSnapshotContext.java   |  53 +++
 .../provider/MockFlowPersistenceProvider.java   |  57 +++
 .../registry/provider/MockMetadataProvider.java | 109 +++++
 .../provider/TestStandardProviderFactory.java   | 105 +++++
 .../provider/providers-class-not-found.xml      |  30 ++
 .../test/resources/provider/providers-good.xml  |  30 ++
 .../properties/NiFiRegistryProperties.java      |  11 +
 nifi-registry-provider-api/pom.xml              |  40 ++
 .../registry/flow/FlowPersistenceException.java |  31 ++
 .../registry/flow/FlowPersistenceProvider.java  |  68 +++
 .../nifi/registry/flow/FlowSnapshotContext.java |  59 +++
 .../registry/metadata/MetadataProvider.java     | 146 ++++++
 .../metadata/MetadataProviderException.java     |  35 ++
 .../apache/nifi/registry/provider/Provider.java |  32 ++
 .../provider/ProviderConfigurationContext.java  |  36 ++
 .../provider/ProviderCreationException.java     |  39 ++
 nifi-registry-provider-impl/pom.xml             |  90 ++++
 .../flow/FileSystemFlowPersistenceProvider.java | 166 +++++++
 .../metadata/FileSystemMetadataProvider.java    | 451 ++++++++++++++++++
 .../nifi/registry/metadata/MetadataHolder.java  | 141 ++++++
 .../src/main/xsd/metadata.xsd                   | 139 ++++++
 .../TestFileSystemFlowPersistenceProvider.java  | 202 +++++++++
 .../TestFileSystemMetadataProvider.java         | 454 +++++++++++++++++++
 .../metadata/metadata-empty-concise.xml         |  16 +
 .../test/resources/metadata/metadata-empty.xml  |  17 +
 .../resources/metadata/metadata-existing.xml    |  35 ++
 .../resources/conf/nifi-registry.properties     |   3 +
 .../src/main/resources/conf/providers.xml       |  28 ++
 nifi-registry-service-api/pom.xml               |  35 --
 .../apache/nifi/registry/util/StringUtils.java  |  99 ++++
 nifi-registry-web-api/pom.xml                   |   7 +-
 .../web/NiFiRegistryResourceConfig.java         |  13 +-
 .../nifi/registry/web/api/TestResource.java     |  19 +
 pom.xml                                         |  13 +-
 90 files changed, 5262 insertions(+), 1918 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-assembly/pom.xml b/nifi-registry-assembly/pom.xml
index 4e8b85b..b2403de 100644
--- a/nifi-registry-assembly/pom.xml
+++ b/nifi-registry-assembly/pom.xml
@@ -137,5 +137,8 @@
         <nifi.registry.security.needClientAuth />
         <nifi.registry.security.authorized.users>./conf/authorized-users.xml</nifi.registry.security.authorized.users>
 
+        <!-- nifi-registry.properties: provider properties -->
+        <nifi.registry.providers.configuration.file>./conf/providers.xml</nifi.registry.providers.configuration.file>
+
     </properties>
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/pom.xml b/nifi-registry-data-model/pom.xml
new file mode 100644
index 0000000..dbdda37
--- /dev/null
+++ b/nifi-registry-data-model/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+    license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to 
+    You under the Apache License, Version 2.0 (the "License"); you may not use 
+    this file except in compliance with the License. You may obtain a copy of 
+    the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+    by applicable law or agreed to in writing, software distributed under the 
+    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+    OF ANY KIND, either express or implied. See the License for the specific 
+    language governing permissions and limitations under the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi.registry</groupId>
+        <artifactId>nifi-registry</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    
+    <artifactId>nifi-registry-data-model</artifactId>
+    <packaging>jar</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.5.16</version>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/Bucket.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/Bucket.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/Bucket.java
new file mode 100644
index 0000000..d24e797
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/Bucket.java
@@ -0,0 +1,114 @@
+/*
+ * 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.registry.bucket;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+
+@ApiModel(value = "bucket")
+public class Bucket {
+
+    private String identifier;
+    private String name;
+    private long createdTimestamp;
+    private String description;
+    private Map<String, BucketObject> bucketObjectMap = new HashMap<>();
+
+    @ApiModelProperty("The id of the bucket. This is set by the server at creation time.")
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+    @ApiModelProperty("The name of the bucket.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @ApiModelProperty("The timestamp of when the bucket was first created. This is set by the server at creation time.")
+    public long getCreatedTimestamp() {
+        return createdTimestamp;
+    }
+
+    public void setCreatedTimestamp(long createdTimestamp) {
+        this.createdTimestamp = createdTimestamp;
+    }
+
+    @ApiModelProperty("A description of the bucket.")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * Add a new object version to this bucket.
+     *
+     * Note that this method has a potential side effect.
+     * If a BucketObject ID is not set, a random UUID string will be set.
+     *
+     * @param object  The object to add to this bucket.
+     */
+    public void addObject(BucketObject object) {
+        if(object.getIdentifier() == null) {
+            object.setIdentifier(UUID.randomUUID().toString());
+        }
+
+        this.bucketObjectMap.put(object.getIdentifier(), object);
+    }
+
+    protected Map<String, BucketObject> getBucketObjectMap() {
+        return bucketObjectMap;
+    }
+
+    protected void setBucketObjectMap(Map<String, BucketObject> bucketObjectMap) {
+        this.bucketObjectMap = bucketObjectMap;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.identifier);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final Bucket other = (Bucket) obj;
+        return Objects.equals(this.identifier, other.identifier);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketObject.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketObject.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketObject.java
new file mode 100644
index 0000000..bd3a9d9
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketObject.java
@@ -0,0 +1,55 @@
+/*
+ * 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.registry.bucket;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Objects;
+
+@ApiModel("bucketObject")
+public abstract class BucketObject {
+
+    private String identifier;
+
+    @ApiModelProperty("An ID to uniquely identify this object.")
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(String id) {
+        this.identifier = id;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.identifier);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final BucketObject other = (BucketObject) obj;
+        return Objects.equals(this.identifier, other.identifier);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/BatchSize.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/BatchSize.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/BatchSize.java
new file mode 100644
index 0000000..b0687b9
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/BatchSize.java
@@ -0,0 +1,53 @@
+/*
+ * 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.registry.flow;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class BatchSize {
+    private Integer count;
+    private String size;
+    private String duration;
+
+    @ApiModelProperty("Preferred number of flow files to include in a transaction.")
+    public Integer getCount() {
+        return count;
+    }
+
+    public void setCount(Integer count) {
+        this.count = count;
+    }
+
+    @ApiModelProperty("Preferred number of bytes to include in a transaction.")
+    public String getSize() {
+        return size;
+    }
+
+    public void setSize(String size) {
+        this.size = size;
+    }
+
+    @ApiModelProperty("Preferred amount of time that a transaction should span.")
+    public String getDuration() {
+        return duration;
+    }
+
+    public void setDuration(String duration) {
+        this.duration = duration;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Bundle.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Bundle.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Bundle.java
new file mode 100644
index 0000000..1050ac9
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Bundle.java
@@ -0,0 +1,83 @@
+/*
+ * 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.registry.flow;
+
+import java.util.Objects;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class Bundle {
+    private String group;
+    private String artifact;
+    private String version;
+
+    public Bundle() {
+    }
+
+    public Bundle(final String group, final String artifact, final String version) {
+        this.group = group;
+        this.artifact = artifact;
+        this.version = version;
+    }
+
+    @ApiModelProperty("The group of the bundle")
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
+
+    @ApiModelProperty("The artifact of the bundle")
+    public String getArtifact() {
+        return artifact;
+    }
+
+    public void setArtifact(String artifact) {
+        this.artifact = artifact;
+    }
+
+    @ApiModelProperty("The version of the bundle")
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final Bundle other = (Bundle) obj;
+        return Objects.equals(group, other.group) && Objects.equals(artifact, other.artifact) && Objects.equals(version, other.version);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(group, artifact, version);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ComponentType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ComponentType.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ComponentType.java
new file mode 100644
index 0000000..300c146
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ComponentType.java
@@ -0,0 +1,49 @@
+/*
+ * 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.registry.flow;
+
+public enum ComponentType {
+
+    CONNECTION("Connection"),
+    PROCESSOR("Processor"),
+    PROCESS_GROUP("Process Group"),
+    REMOTE_PROCESS_GROUP("Remote Process Group"),
+    INPUT_PORT("Input Port"),
+    OUTPUT_PORT("Output Port"),
+    REMOTE_INPUT_PORT("Remote Input Port"),
+    REMOTE_OUTPUT_PORT("Remote Output Port"),
+    FUNNEL("Funnel"),
+    LABEL("Label"),
+    CONTROLLER_SERVICE("Controller Service");
+
+
+    private final String typeName;
+
+    private ComponentType(final String typeName) {
+        this.typeName = typeName;
+    }
+
+    public String getTypeName() {
+        return typeName;
+    }
+
+    @Override
+    public String toString() {
+        return typeName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponent.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponent.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponent.java
new file mode 100644
index 0000000..abd34bf
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponent.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.registry.flow;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class ConnectableComponent {
+    private String id;
+    private ConnectableComponentType type;
+    private String groupId;
+    private String name;
+    private String comments;
+
+    @ApiModelProperty(value = "The id of the connectable component.", required = true)
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @ApiModelProperty(value = "The type of component the connectable is.", required = true)
+    public ConnectableComponentType getType() {
+        return type;
+    }
+
+    public void setType(ConnectableComponentType type) {
+        this.type = type;
+    }
+
+    @ApiModelProperty(value = "The id of the group that the connectable component resides in", required = true)
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    @ApiModelProperty("The name of the connectable component")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @ApiModelProperty("The comments for the connectable component.")
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponentType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponentType.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponentType.java
new file mode 100644
index 0000000..1b73cac
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ConnectableComponentType.java
@@ -0,0 +1,27 @@
+/*
+ * 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.registry.flow;
+
+public enum ConnectableComponentType {
+    PROCESSOR,
+    REMOTE_INPUT_PORT,
+    REMOTE_OUTPUT_PORT,
+    INPUT_PORT,
+    OUTPUT_PORT,
+    FUNNEL;
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ControllerServiceAPI.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ControllerServiceAPI.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ControllerServiceAPI.java
new file mode 100644
index 0000000..b46e87a
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/ControllerServiceAPI.java
@@ -0,0 +1,65 @@
+/*
+ * 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.registry.flow;
+
+import java.util.Objects;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class ControllerServiceAPI {
+    private String type;
+    private Bundle bundle;
+
+    @ApiModelProperty("The fully qualified name of the service interface.")
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    @ApiModelProperty("The details of the artifact that bundled this service interface.")
+    public Bundle getBundle() {
+        return bundle;
+    }
+
+    public void setBundle(Bundle bundle) {
+        this.bundle = bundle;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final ControllerServiceAPI other = (ControllerServiceAPI) o;
+        return Objects.equals(type, other.type) && Objects.equals(bundle, other.bundle);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, bundle);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/PortType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/PortType.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/PortType.java
new file mode 100644
index 0000000..6a32c11
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/PortType.java
@@ -0,0 +1,23 @@
+/*
+ * 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.registry.flow;
+
+public enum PortType {
+    INPUT_PORT,
+    OUTPUT_PORT;
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Position.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Position.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Position.java
new file mode 100644
index 0000000..0cbb12c
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/Position.java
@@ -0,0 +1,58 @@
+/*
+ * 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.registry.flow;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel("The position of a component on the graph")
+public class Position {
+    private double x;
+    private double y;
+
+    public Position() {
+    }
+
+    public Position(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    @ApiModelProperty("The x coordinate.")
+    public double getX() {
+        return x;
+    }
+
+    public void setX(double x) {
+        this.x = x;
+    }
+
+    @ApiModelProperty("The y coordinate.")
+    public double getY() {
+        return y;
+    }
+
+    public void setY(double y) {
+        this.y = y;
+    }
+
+    @Override
+    public String toString() {
+        return "[x=" + x + ", y=" + y + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/SiteToSiteTransportProtocol.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/SiteToSiteTransportProtocol.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/SiteToSiteTransportProtocol.java
new file mode 100644
index 0000000..9f94c1a
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/SiteToSiteTransportProtocol.java
@@ -0,0 +1,23 @@
+/*
+ * 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.registry.flow;
+
+public enum SiteToSiteTransportProtocol {
+    RAW,
+    HTTP;
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedComponent.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedComponent.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedComponent.java
new file mode 100644
index 0000000..bef9557
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedComponent.java
@@ -0,0 +1,67 @@
+/*
+ * 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.registry.flow;
+
+import io.swagger.annotations.ApiModelProperty;
+
+
+public abstract class VersionedComponent {
+
+    private String identifier;
+    private String name;
+    private String comments;
+    private Position position;
+
+    @ApiModelProperty("The component's unique identifier")
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+    @ApiModelProperty("The component's name")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @ApiModelProperty("The component's position on the graph")
+    public Position getPosition() {
+        return position;
+    }
+
+    public void setPosition(Position position) {
+        this.position = position;
+    }
+
+    @ApiModelProperty("The user-supplied comments for the component")
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
+
+    public abstract ComponentType getComponentType();
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedConnection.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedConnection.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedConnection.java
new file mode 100644
index 0000000..59740e9
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedConnection.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.registry.flow;
+
+import java.util.List;
+import java.util.Set;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedConnection extends VersionedComponent {
+    private ConnectableComponent source;
+    private ConnectableComponent destination;
+    private Integer labelIndex;
+    private Long zIndex;
+    private Set<String> selectedRelationships;
+
+    private Long backPressureObjectThreshold;
+    private String backPressureDataSizeThreshold;
+    private String flowFileExpiration;
+    private List<String> prioritizers;
+    private List<Position> bends;
+
+    @ApiModelProperty("The source of the connection.")
+    public ConnectableComponent getSource() {
+        return source;
+    }
+
+    public void setSource(ConnectableComponent source) {
+        this.source = source;
+    }
+
+    @ApiModelProperty("The destination of the connection.")
+    public ConnectableComponent getDestination() {
+        return destination;
+    }
+
+    public void setDestination(ConnectableComponent destination) {
+        this.destination = destination;
+    }
+
+    @ApiModelProperty("The bend points on the connection.")
+    public List<Position> getBends() {
+        return bends;
+    }
+
+    public void setBends(List<Position> bends) {
+        this.bends = bends;
+    }
+
+    @ApiModelProperty("The index of the bend point where to place the connection label.")
+    public Integer getLabelIndex() {
+        return labelIndex;
+    }
+
+    public void setLabelIndex(Integer labelIndex) {
+        this.labelIndex = labelIndex;
+    }
+
+    @ApiModelProperty("The z index of the connection.")
+    public Long getzIndex() {
+        return zIndex;
+    }
+
+    public void setzIndex(Long zIndex) {
+        this.zIndex = zIndex;
+    }
+
+    @ApiModelProperty("The selected relationship that comprise the connection.")
+    public Set<String> getSelectedRelationships() {
+        return selectedRelationships;
+    }
+
+    public void setSelectedRelationships(Set<String> relationships) {
+        this.selectedRelationships = relationships;
+    }
+
+
+    @ApiModelProperty("The object count threshold for determining when back pressure is applied. Updating this value is a passive change in the sense that it won't impact whether existing files "
+        + "over the limit are affected but it does help feeder processors to stop pushing too much into this work queue.")
+    public Long getBackPressureObjectThreshold() {
+        return backPressureObjectThreshold;
+    }
+
+    public void setBackPressureObjectThreshold(Long backPressureObjectThreshold) {
+        this.backPressureObjectThreshold = backPressureObjectThreshold;
+    }
+
+
+    @ApiModelProperty("The object data size threshold for determining when back pressure is applied. Updating this value is a passive change in the sense that it won't impact whether existing "
+        + "files over the limit are affected but it does help feeder processors to stop pushing too much into this work queue.")
+    public String getBackPressureDataSizeThreshold() {
+        return backPressureDataSizeThreshold;
+    }
+
+    public void setBackPressureDataSizeThreshold(String backPressureDataSizeThreshold) {
+        this.backPressureDataSizeThreshold = backPressureDataSizeThreshold;
+    }
+
+
+    @ApiModelProperty("The amount of time a flow file may be in the flow before it will be automatically aged out of the flow. Once a flow file reaches this age it will be terminated from "
+        + "the flow the next time a processor attempts to start work on it.")
+    public String getFlowFileExpiration() {
+        return flowFileExpiration;
+    }
+
+    public void setFlowFileExpiration(String flowFileExpiration) {
+        this.flowFileExpiration = flowFileExpiration;
+    }
+
+
+    @ApiModelProperty("The comparators used to prioritize the queue.")
+    public List<String> getPrioritizers() {
+        return prioritizers;
+    }
+
+    public void setPrioritizers(List<String> prioritizers) {
+        this.prioritizers = prioritizers;
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.CONNECTION;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedControllerService.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedControllerService.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedControllerService.java
new file mode 100644
index 0000000..2275e73
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedControllerService.java
@@ -0,0 +1,108 @@
+/*
+ * 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.registry.flow;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedControllerService extends VersionedComponent {
+
+    private String type;
+    private Bundle bundle;
+    private List<ControllerServiceAPI> controllerServiceApis;
+
+    private Map<String, String> properties;
+    private String annotationData;
+
+
+    @ApiModelProperty(value = "The type of the controller service.")
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    @ApiModelProperty(value = "The details of the artifact that bundled this processor type.")
+    public Bundle getBundle() {
+        return bundle;
+    }
+
+    public void setBundle(Bundle bundle) {
+        this.bundle = bundle;
+    }
+
+    @ApiModelProperty(value = "Lists the APIs this Controller Service implements.")
+    public List<ControllerServiceAPI> getControllerServiceApis() {
+        return controllerServiceApis;
+    }
+
+    public void setControllerServiceApis(List<ControllerServiceAPI> controllerServiceApis) {
+        this.controllerServiceApis = controllerServiceApis;
+    }
+
+    @ApiModelProperty(value = "The properties of the controller service.")
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    @ApiModelProperty(value = "The annotation for the controller service. This is how the custom UI relays configuration to the controller service.")
+    public String getAnnotationData() {
+        return annotationData;
+    }
+
+    public void setAnnotationData(String annotationData) {
+        this.annotationData = annotationData;
+    }
+
+    @Override
+    public int hashCode() {
+        final String id = getIdentifier();
+        return 37 + 3 * ((id == null) ? 0 : id.hashCode());
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj.getClass() != VersionedControllerService.class) {
+            return false;
+        }
+
+        final VersionedControllerService other = (VersionedControllerService) obj;
+        return Objects.equals(getIdentifier(), other.getIdentifier());
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.CONTROLLER_SERVICE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlow.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlow.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlow.java
new file mode 100644
index 0000000..4b8a910
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlow.java
@@ -0,0 +1,120 @@
+/*
+ * 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.registry.flow;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.bucket.BucketObject;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * Represents a versioned flow. A versioned flow is a named flow that is expected to change
+ * over time. This flow is saved to the registry with information such as its name, a description,
+ * and each version of the flow.
+ * </p>
+ *
+ * @see VersionedFlowSnapshot
+ */
+@ApiModel(value = "versionedFlow")
+public class VersionedFlow extends BucketObject {
+
+    private String name;
+    private long createdTimestamp;
+    private long modifiedTimestamp;
+    private String description;
+    private int currentMaxVersion = 0;
+    private ArrayList<VersionedFlowSnapshot> snapshots = new ArrayList<>();
+    private Map<Integer, VersionedFlowSnapshot> snapshotsByVersion = new HashMap<>(); // TODO, could use a third-party collection type that supports primitive keys.
+
+    @ApiModelProperty("The name of the flow.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @ApiModelProperty("The timestamp of when the flow was first created.")
+    public long getCreatedTimestamp() {
+        return createdTimestamp;
+    }
+
+    public void setCreatedTimestamp(long timestamp) {
+        this.createdTimestamp = timestamp;
+    }
+
+    @ApiModelProperty("The timestamp of when the flow was last modified, e.g., when a new version was saved.")
+    public long getModifiedTimestamp() {
+        return modifiedTimestamp;
+    }
+
+    public void setModifiedTimestamp(long modifiedTimestamp) {
+        this.modifiedTimestamp = modifiedTimestamp;
+    }
+
+    @ApiModelProperty("A description of the flow.")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public List<VersionedFlowSnapshot> getSnapshots() {
+        return snapshots;
+    }
+
+    public VersionedFlowSnapshot getSnapshot(int version) {
+        return snapshotsByVersion.get(Integer.valueOf(version));
+    }
+
+    /**
+     * Add a new snapshot version to this VersionedFlow.
+     *
+     * Note that this method has potential side effects.
+     * If a snapshot version number is not a positive integer,
+     * a new version number will be set as the current max version number + 1.
+     *
+     * @param snapshot  The snapshot to add to this versionedFlow
+     */
+    public void addVersionedFlowSnapshot(VersionedFlowSnapshot snapshot) {
+        if (snapshot == null) {
+            return;
+        }
+
+        int snapshotVersion = snapshot.getVersion();
+        if (snapshotVersion < 1) {
+            snapshotVersion = ++currentMaxVersion;
+            snapshot.setVersion(snapshotVersion);
+        } else if (snapshotsByVersion.containsKey(Integer.valueOf(snapshotVersion))) {
+            throw new IllegalStateException("Unable to add snapshot to VersionedFlow with duplicate version number '" + snapshotVersion + "'.");
+        } else {
+            currentMaxVersion = (snapshotVersion > currentMaxVersion) ? snapshotVersion : currentMaxVersion;
+        }
+
+        snapshots.add(snapshot);
+        snapshotsByVersion.put(Integer.valueOf(snapshotVersion), snapshot);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlowSnapshot.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlowSnapshot.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlowSnapshot.java
new file mode 100644
index 0000000..a1500a4
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFlowSnapshot.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.registry.flow;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Objects;
+
+/**
+ * <p>
+ * Represents a snapshot of a versioned flow. A versioned flow may change many times
+ * over the course of its life. Each of these versions that is saved to the registry
+ * is saved as a snapshot, representing information such as the name of the flow, the
+ * version of the flow, the timestamp when it was saved, the contents of the flow, etc.
+ * </p>
+ */
+@ApiModel(value = "versionedFlowSnapshot")
+public class VersionedFlowSnapshot {
+    private String flowIdentifier;
+    private String flowName;
+    private int version;
+    private long timestamp;
+    private String comments;
+    private VersionedProcessGroup flowContents;
+
+    @ApiModelProperty("The identifier of the flow this snapshot belongs to")
+    public String getFlowIdentifier() {
+        return flowIdentifier;
+    }
+
+    public void setFlowIdentifier(String flowIdentifier) {
+        this.flowIdentifier = flowIdentifier;
+    }
+
+    @ApiModelProperty("The name of the flow this snapshot belongs to")
+    public String getFlowName() {
+        return flowName;
+    }
+
+    public void setFlowName(String flowName) {
+        this.flowName = flowName;
+    }
+
+    @ApiModelProperty("The version of this snapshot of the flow")
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    @ApiModelProperty("The timestamp when the flow was saved")
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @ApiModelProperty("The comments provided by the user when creating the snapshot")
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
+
+    @ApiModelProperty("The contents of the versioned flow")
+    public VersionedProcessGroup getFlowContents() {
+        return flowContents;
+    }
+
+    public void setFlowContents(VersionedProcessGroup flowContents) {
+        this.flowContents = flowContents;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.flowIdentifier, Integer.valueOf(this.version));
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        final VersionedFlowSnapshot other = (VersionedFlowSnapshot) obj;
+        return Objects.equals(this.flowIdentifier, other.flowIdentifier) && Objects.equals(this.version, other.version);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFunnel.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFunnel.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFunnel.java
new file mode 100644
index 0000000..871dafc
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedFunnel.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.registry.flow;
+
+public class VersionedFunnel extends VersionedComponent {
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.FUNNEL;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedLabel.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedLabel.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedLabel.java
new file mode 100644
index 0000000..e7af4de
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedLabel.java
@@ -0,0 +1,75 @@
+/*
+ * 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.registry.flow;
+
+import java.util.Map;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedLabel extends VersionedComponent {
+    private String label;
+
+    private Double width;
+    private Double height;
+
+    // font-size = 12px
+    // background-color = #eee
+    private Map<String, String> style;
+
+
+    @ApiModelProperty("The text that appears in the label.")
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(final String label) {
+        this.label = label;
+    }
+
+    @ApiModelProperty("The styles for this label (font-size : 12px, background-color : #eee, etc).")
+    public Map<String, String> getStyle() {
+        return style;
+    }
+
+    public void setStyle(final Map<String, String> style) {
+        this.style = style;
+    }
+
+    @ApiModelProperty("The height of the label in pixels when at a 1:1 scale.")
+    public Double getHeight() {
+        return height;
+    }
+
+    public void setHeight(Double height) {
+        this.height = height;
+    }
+
+    @ApiModelProperty("The width of the label in pixels when at a 1:1 scale.")
+    public Double getWidth() {
+        return width;
+    }
+
+    public void setWidth(Double width) {
+        this.width = width;
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.LABEL;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedPort.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedPort.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedPort.java
new file mode 100644
index 0000000..f24e386
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedPort.java
@@ -0,0 +1,52 @@
+/*
+ * 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.registry.flow;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedPort extends VersionedComponent {
+    private PortType type;
+    private Integer concurrentlySchedulableTaskCount;
+
+    @ApiModelProperty("The number of tasks that should be concurrently scheduled for the port.")
+    public Integer getConcurrentlySchedulableTaskCount() {
+        return concurrentlySchedulableTaskCount;
+    }
+
+    public void setConcurrentlySchedulableTaskCount(Integer concurrentlySchedulableTaskCount) {
+        this.concurrentlySchedulableTaskCount = concurrentlySchedulableTaskCount;
+    }
+
+    @ApiModelProperty("The type of port.")
+    public PortType getType() {
+        return type;
+    }
+
+    public void setType(PortType type) {
+        this.type = type;
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        if (type == PortType.OUTPUT_PORT) {
+            return ComponentType.OUTPUT_PORT;
+        }
+
+        return ComponentType.INPUT_PORT;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessGroup.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessGroup.java
new file mode 100644
index 0000000..9458cda
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessGroup.java
@@ -0,0 +1,123 @@
+/*
+ * 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.registry.flow;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import io.swagger.annotations.ApiModelProperty;
+
+
+public class VersionedProcessGroup extends VersionedComponent {
+
+    private Set<VersionedProcessGroup> processGroups = new LinkedHashSet<>();
+    private Set<VersionedRemoteProcessGroup> remoteProcessGroups = new LinkedHashSet<>();
+    private Set<VersionedProcessor> processors = new LinkedHashSet<>();
+    private Set<VersionedPort> inputPorts = new LinkedHashSet<>();
+    private Set<VersionedPort> outputPorts = new LinkedHashSet<>();
+    private Set<VersionedConnection> connections = new LinkedHashSet<>();
+    private Set<VersionedLabel> labels = new LinkedHashSet<>();
+    private Set<VersionedFunnel> funnels = new LinkedHashSet<>();
+    private Set<VersionedControllerService> controllerServices = new LinkedHashSet<>();
+
+    @ApiModelProperty("The child Process Groups")
+    public Set<VersionedProcessGroup> getProcessGroups() {
+        return processGroups;
+    }
+
+    public void setProcessGroups(Set<VersionedProcessGroup> processGroups) {
+        this.processGroups = processGroups;
+    }
+
+    @ApiModelProperty("The Remote Process Groups")
+    public Set<VersionedRemoteProcessGroup> getRemoteProcessGroups() {
+        return remoteProcessGroups;
+    }
+
+    public void setRemoteProcessGroups(Set<VersionedRemoteProcessGroup> remoteProcessGroups) {
+        this.remoteProcessGroups = remoteProcessGroups;
+    }
+
+    @ApiModelProperty("The Processors")
+    public Set<VersionedProcessor> getProcessors() {
+        return processors;
+    }
+
+    public void setProcessors(Set<VersionedProcessor> processors) {
+        this.processors = processors;
+    }
+
+    @ApiModelProperty("The Input Ports")
+    public Set<VersionedPort> getInputPorts() {
+        return inputPorts;
+    }
+
+    public void setInputPorts(Set<VersionedPort> inputPorts) {
+        this.inputPorts = inputPorts;
+    }
+
+    @ApiModelProperty("The Output Ports")
+    public Set<VersionedPort> getOutputPorts() {
+        return outputPorts;
+    }
+
+    public void setOutputPorts(Set<VersionedPort> outputPorts) {
+        this.outputPorts = outputPorts;
+    }
+
+    @ApiModelProperty("The Connections")
+    public Set<VersionedConnection> getConnections() {
+        return connections;
+    }
+
+    public void setConnections(Set<VersionedConnection> connections) {
+        this.connections = connections;
+    }
+
+    @ApiModelProperty("The Labels")
+    public Set<VersionedLabel> getLabels() {
+        return labels;
+    }
+
+    public void setLabels(Set<VersionedLabel> labels) {
+        this.labels = labels;
+    }
+
+    @ApiModelProperty("The Funnels")
+    public Set<VersionedFunnel> getFunnels() {
+        return funnels;
+    }
+
+    public void setFunnels(Set<VersionedFunnel> funnels) {
+        this.funnels = funnels;
+    }
+
+    @ApiModelProperty("The Controller Services")
+    public Set<VersionedControllerService> getControllerServices() {
+        return controllerServices;
+    }
+
+    public void setControllerServices(Set<VersionedControllerService> controllerServices) {
+        this.controllerServices = controllerServices;
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.PROCESS_GROUP;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessor.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessor.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessor.java
new file mode 100644
index 0000000..4678726
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedProcessor.java
@@ -0,0 +1,169 @@
+/*
+ * 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.registry.flow;
+
+import java.util.Map;
+import java.util.Set;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedProcessor extends VersionedComponent {
+
+    private Bundle bundle;
+    private Map<String, String> style;
+
+    private Map<String, String> properties;
+    private String annotationData;
+
+    private String schedulingPeriod;
+    private String schedulingStrategy;
+    private String executionNode;
+    private String penaltyDuration;
+    private String yieldDuration;
+    private String bulletinLevel;
+    private Long runDurationMillis;
+    private Integer concurrentlySchedulableTaskCount;
+    private Set<String> autoTerminatedRelationships;
+
+
+    @ApiModelProperty("The frequency with which to schedule the processor. The format of the value will depend on th value of schedulingStrategy.")
+    public String getSchedulingPeriod() {
+        return schedulingPeriod;
+    }
+
+    public void setSchedulingPeriod(String setSchedulingPeriod) {
+        this.schedulingPeriod = setSchedulingPeriod;
+    }
+
+    @ApiModelProperty("Indcates whether the prcessor should be scheduled to run in event or timer driven mode.")
+    public String getSchedulingStrategy() {
+        return schedulingStrategy;
+    }
+
+    public void setSchedulingStrategy(String schedulingStrategy) {
+        this.schedulingStrategy = schedulingStrategy;
+    }
+
+    @ApiModelProperty("Indicates the node where the process will execute.")
+    public String getExecutionNode() {
+        return executionNode;
+    }
+
+    public void setExecutionNode(String executionNode) {
+        this.executionNode = executionNode;
+    }
+
+    @ApiModelProperty("The amout of time that is used when the process penalizes a flowfile.")
+    public String getPenaltyDuration() {
+        return penaltyDuration;
+    }
+
+    public void setPenaltyDuration(String penaltyDuration) {
+        this.penaltyDuration = penaltyDuration;
+    }
+
+    @ApiModelProperty("The amount of time that must elapse before this processor is scheduled again after yielding.")
+    public String getYieldDuration() {
+        return yieldDuration;
+    }
+
+    public void setYieldDuration(String yieldDuration) {
+        this.yieldDuration = yieldDuration;
+    }
+
+    @ApiModelProperty("The level at which the processor will report bulletins.")
+    public String getBulletinLevel() {
+        return bulletinLevel;
+    }
+
+    public void setBulletinLevel(String bulletinLevel) {
+        this.bulletinLevel = bulletinLevel;
+    }
+
+    @ApiModelProperty("The number of tasks that should be concurrently schedule for the processor. If the processor doesn't allow parallol processing then any positive input will be ignored.")
+    public Integer getConcurrentlySchedulableTaskCount() {
+        return concurrentlySchedulableTaskCount;
+    }
+
+    public void setConcurrentlySchedulableTaskCount(Integer concurrentlySchedulableTaskCount) {
+        this.concurrentlySchedulableTaskCount = concurrentlySchedulableTaskCount;
+    }
+
+
+    @ApiModelProperty("The properties for the processor. Properties whose value is not set will only contain the property name.")
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    @ApiModelProperty("The annotation data for the processor used to relay configuration between a custom UI and the procesosr.")
+    public String getAnnotationData() {
+        return annotationData;
+    }
+
+    public void setAnnotationData(String annotationData) {
+        this.annotationData = annotationData;
+    }
+
+
+    @ApiModelProperty("The names of all relationships that cause a flow file to be terminated if the relationship is not connected elsewhere. This property differs "
+        + "from the 'isAutoTerminate' property of the RelationshipDTO in that the RelationshipDTO is meant to depict the current configuration, whereas this "
+        + "property can be set in a DTO when updating a Processor in order to change which Relationships should be auto-terminated.")
+    public Set<String> getAutoTerminatedRelationships() {
+        return autoTerminatedRelationships;
+    }
+
+    public void setAutoTerminatedRelationships(final Set<String> autoTerminatedRelationships) {
+        this.autoTerminatedRelationships = autoTerminatedRelationships;
+    }
+
+    @ApiModelProperty("The run duration for the processor in milliseconds.")
+    public Long getRunDurationMillis() {
+        return runDurationMillis;
+    }
+
+    public void setRunDurationMillis(Long runDurationMillis) {
+        this.runDurationMillis = runDurationMillis;
+    }
+
+    @ApiModelProperty("Information about the bundle from which the component came")
+    public Bundle getBundle() {
+        return bundle;
+    }
+
+    public void setBundle(Bundle bundle) {
+        this.bundle = bundle;
+    }
+
+    @ApiModelProperty("Stylistic data for rendering in a UI")
+    public Map<String, String> getStyle() {
+        return style;
+    }
+
+    public void setStyle(Map<String, String> style) {
+        this.style = style;
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.PROCESSOR;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteGroupPort.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteGroupPort.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteGroupPort.java
new file mode 100644
index 0000000..73b037e
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteGroupPort.java
@@ -0,0 +1,98 @@
+/*
+ * 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.registry.flow;
+
+import java.util.Objects;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedRemoteGroupPort extends VersionedComponent {
+    private String groupId;
+    private Integer concurrentlySchedulableTaskCount;
+    private Boolean useCompression;
+    private BatchSize batchSize;
+    private ComponentType componentType;
+
+    @ApiModelProperty("The number of task that may transmit flowfiles to the target port concurrently.")
+    public Integer getConcurrentlySchedulableTaskCount() {
+        return concurrentlySchedulableTaskCount;
+    }
+
+    public void setConcurrentlySchedulableTaskCount(Integer concurrentlySchedulableTaskCount) {
+        this.concurrentlySchedulableTaskCount = concurrentlySchedulableTaskCount;
+    }
+
+    @ApiModelProperty("The id of the remote process group that the port resides in.")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+
+    @ApiModelProperty("Whether the flowfiles are compressed when sent to the target port.")
+    public Boolean isUseCompression() {
+        return useCompression;
+    }
+
+    public void setUseCompression(Boolean useCompression) {
+        this.useCompression = useCompression;
+    }
+
+    @ApiModelProperty("The batch settings for data transmission.")
+    public BatchSize getBatchSize() {
+        return batchSize;
+    }
+
+    public void setBatchSettings(BatchSize batchSize) {
+        this.batchSize = batchSize;
+    }
+
+    @Override
+    public int hashCode() {
+        return 923847 + String.valueOf(getName()).hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof VersionedRemoteGroupPort)) {
+            return false;
+        }
+
+        final VersionedRemoteGroupPort other = (VersionedRemoteGroupPort) obj;
+        return Objects.equals(getName(), other.getName());
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return componentType;
+    }
+
+    public void setComponentType(final ComponentType componentType) {
+        if (componentType != ComponentType.REMOTE_INPUT_PORT && componentType != ComponentType.REMOTE_OUTPUT_PORT) {
+            throw new IllegalArgumentException();
+        }
+
+        this.componentType = componentType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteProcessGroup.java b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteProcessGroup.java
new file mode 100644
index 0000000..8417cfc
--- /dev/null
+++ b/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/flow/VersionedRemoteProcessGroup.java
@@ -0,0 +1,177 @@
+/*
+ * 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.registry.flow;
+
+import java.util.Set;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class VersionedRemoteProcessGroup extends VersionedComponent {
+    private String targetUri;
+    private String targetUris;
+    private Boolean targetSecure;
+
+    private String communicationsTimeout;
+    private String yieldDuration;
+    private SiteToSiteTransportProtocol transportProtocol;
+    private String localNetworkInterface;
+    private String proxyHost;
+    private Integer proxyPort;
+    private String proxyUser;
+
+    private Set<VersionedRemoteGroupPort> inputPorts;
+    private Set<VersionedRemoteGroupPort> outputPorts;
+
+
+    public void setTargetUri(final String targetUri) {
+        this.targetUri = targetUri;
+    }
+
+
+    @ApiModelProperty("The target URI of the remote process group." +
+        " If target uri is not set, but uris are set, then returns the first url in the urls." +
+        " If neither target uri nor uris are set, then returns null.")
+    public String getTargetUri() {
+        if (targetUri == null || targetUri.length() == 0) {
+            if (targetUri == null || targetUri.length() == 0) {
+                if (targetUris != null && targetUris.length() > 0) {
+                    if (targetUris.indexOf(',') > -1) {
+                        targetUri = targetUris.substring(0, targetUris.indexOf(','));
+                    } else {
+                        targetUri = targetUris;
+                    }
+                }
+            }
+        }
+
+        return this.targetUri;
+    }
+
+    public void setTargetUris(String targetUris) {
+        this.targetUris = targetUris;
+    }
+
+
+    @ApiModelProperty("The target URI of the remote process group." +
+        " If target uris is not set but target uri is set," +
+        " then returns a collection containing the single target uri." +
+        " If neither target uris nor uris are set, then returns null.")
+    public String getTargetUris() {
+        if (targetUris == null || targetUris.length() == 0) {
+            if (targetUris == null || targetUris.length() == 0) {
+                targetUris = targetUri;
+            }
+        }
+
+        return this.targetUris;
+    }
+
+
+    @ApiModelProperty("Whether the target is running securely.")
+    public Boolean isTargetSecure() {
+        return targetSecure;
+    }
+
+    public void setTargetSecure(Boolean targetSecure) {
+        this.targetSecure = targetSecure;
+    }
+
+    @ApiModelProperty("The time period used for the timeout when communicating with the target.")
+    public String getCommunicationsTimeout() {
+        return communicationsTimeout;
+    }
+
+    public void setCommunicationsTimeout(String communicationsTimeout) {
+        this.communicationsTimeout = communicationsTimeout;
+    }
+
+    @ApiModelProperty("When yielding, this amount of time must elapse before the remote process group is scheduled again.")
+    public String getYieldDuration() {
+        return yieldDuration;
+    }
+
+    public void setYieldDuration(String yieldDuration) {
+        this.yieldDuration = yieldDuration;
+    }
+
+
+    public SiteToSiteTransportProtocol getTransportProtocol() {
+        return transportProtocol;
+    }
+
+    public void setTransportProtocol(SiteToSiteTransportProtocol transportProtocol) {
+        this.transportProtocol = transportProtocol;
+    }
+
+    @ApiModelProperty("A Set of Input Ports that can be connected to, in order to send data to the remote NiFi instance")
+    public Set<VersionedRemoteGroupPort> getInputPorts() {
+        return inputPorts;
+    }
+
+    public void setInputPorts(Set<VersionedRemoteGroupPort> inputPorts) {
+        this.inputPorts = inputPorts;
+    }
+
+    @ApiModelProperty("A Set of Output Ports that can be connected to, in order to pull data from the remote NiFi instance")
+    public Set<VersionedRemoteGroupPort> getOutputPorts() {
+        return outputPorts;
+    }
+
+    public void setOutputPorts(Set<VersionedRemoteGroupPort> outputPorts) {
+        this.outputPorts = outputPorts;
+    }
+
+
+    @ApiModelProperty("The local network interface to send/receive data. If not specified, any local address is used. If clustered, all nodes must have an interface with this identifier.")
+    public String getLocalNetworkInterface() {
+        return localNetworkInterface;
+    }
+
+    public void setLocalNetworkInterface(String localNetworkInterface) {
+        this.localNetworkInterface = localNetworkInterface;
+    }
+
+    public String getProxyHost() {
+        return proxyHost;
+    }
+
+    public void setProxyHost(String proxyHost) {
+        this.proxyHost = proxyHost;
+    }
+
+    public Integer getProxyPort() {
+        return proxyPort;
+    }
+
+    public void setProxyPort(Integer proxyPort) {
+        this.proxyPort = proxyPort;
+    }
+
+    public String getProxyUser() {
+        return proxyUser;
+    }
+
+    public void setProxyUser(String proxyUser) {
+        this.proxyUser = proxyUser;
+    }
+
+    @Override
+    public ComponentType getComponentType() {
+        return ComponentType.REMOTE_PROCESS_GROUP;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/9eb0cef0/nifi-registry-flow-data-model/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-flow-data-model/pom.xml b/nifi-registry-flow-data-model/pom.xml
deleted file mode 100644
index 2485791..0000000
--- a/nifi-registry-flow-data-model/pom.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-    license agreements. See the NOTICE file distributed with this work for additional 
-    information regarding copyright ownership. The ASF licenses this file to 
-    You under the Apache License, Version 2.0 (the "License"); you may not use 
-    this file except in compliance with the License. You may obtain a copy of 
-    the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
-    by applicable law or agreed to in writing, software distributed under the 
-    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
-    OF ANY KIND, either express or implied. See the License for the specific 
-    language governing permissions and limitations under the License. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.nifi.registry</groupId>
-        <artifactId>nifi-registry</artifactId>
-        <version>0.0.1-SNAPSHOT</version>
-    </parent>
-    
-    <artifactId>nifi-registry-flow-data-model</artifactId>
-    <packaging>jar</packaging>
-    
-    <dependencies>
-        <dependency>
-            <groupId>io.swagger</groupId>
-            <artifactId>swagger-annotations</artifactId>
-            <version>1.5.16</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file