You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2018/01/08 18:13:56 UTC

[08/50] nifi git commit: NIFI-4436: - Adding support to save a version of a flow based on a selected Process Group. - Adding support for revert changes back to the most recent version. - Adding support to disconnect from version control. - Moving the ver

NIFI-4436:
- Adding support to save a version of a flow based on a selected Process Group.
- Adding support for revert changes back to the most recent version.
- Adding support to disconnect from version control.
- Moving the version control information out of the entity objects and into the dto's.
- Fixing checkstyle issues.
NIFI-4502:
- Updating the UI to allow for the user to register registry clients.
- Updating the version control menu item names.


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

Branch: refs/heads/master
Commit: 7a0a900a0ff8b9329296b9a19b9239b63fc2d76d
Parents: 6a58d78
Author: Matt Gilman <ma...@gmail.com>
Authored: Thu Oct 12 12:29:05 2017 -0400
Committer: Bryan Bende <bb...@apache.org>
Committed: Mon Jan 8 12:44:52 2018 -0500

----------------------------------------------------------------------
 .../org/apache/nifi/web/api/dto/BucketDTO.java  |  69 +++
 .../web/api/dto/ControllerConfigurationDTO.java |   1 +
 .../nifi/web/api/dto/FlowConfigurationDTO.java  |  15 +
 .../apache/nifi/web/api/dto/RegistryDTO.java    |  69 +++
 .../nifi/web/api/dto/VersionedFlowDTO.java      |  10 +
 .../web/api/dto/flow/FlowBreadcrumbDTO.java     |  16 +
 .../nifi/web/api/entity/BucketEntity.java       |  39 ++
 .../nifi/web/api/entity/BucketsEntity.java      |  41 ++
 .../nifi/web/api/entity/RegistriesEntity.java   |  41 ++
 .../nifi/web/api/entity/RegistryEntity.java     |  39 ++
 .../entity/VersionControlInformationEntity.java |   6 +-
 .../org/apache/nifi/groups/ProcessGroup.java    |   7 +-
 .../apache/nifi/registry/flow/FlowRegistry.java |  17 +
 .../nifi-framework/nifi-framework-core/pom.xml  |   5 +
 .../nifi/groups/StandardProcessGroup.java       |  58 ++-
 .../flow/FileBasedFlowRegistryClient.java       |  49 +-
 .../service/mock/MockProcessGroup.java          |  25 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |  75 ++-
 .../nifi/web/NiFiWebApiResourceConfig.java      |   1 +
 .../nifi/web/StandardNiFiServiceFacade.java     | 142 ++++--
 .../apache/nifi/web/api/ControllerResource.java | 298 ++++++++++++
 .../org/apache/nifi/web/api/FlowResource.java   | 113 +++++
 .../apache/nifi/web/api/VersionsResource.java   | 156 +++---
 .../api/concurrent/AsynchronousWebRequest.java  |   6 +-
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  74 +--
 .../apache/nifi/web/api/dto/EntityFactory.java  |   1 +
 .../apache/nifi/web/dao/ProcessGroupDAO.java    |  18 +-
 .../web/dao/impl/StandardProcessGroupDAO.java   |  20 +-
 .../ClusterReplicationComponentLifecycle.java   |  37 +-
 .../nifi/web/util/LocalComponentLifecycle.java  |  16 +-
 .../src/main/resources/nifi-web-api-context.xml |   3 +
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |   1 +
 .../main/resources/filters/canvas.properties    |   1 +
 .../src/main/webapp/WEB-INF/pages/canvas.jsp    |   2 +
 .../WEB-INF/partials/canvas/canvas-header.jsp   |  16 +-
 .../canvas/registry-configuration-dialog.jsp    |  40 ++
 .../canvas/save-flow-version-dialog.jsp         |  54 +++
 .../partials/canvas/settings-content.jsp        |   3 +
 .../nifi-web-ui/src/main/webapp/css/dialog.css  |  16 +
 .../nifi-web-ui/src/main/webapp/css/graph.css   |   8 +
 .../src/main/webapp/css/navigation.css          |   5 +
 .../controllers/nf-ng-breadcrumbs-controller.js |  15 +
 .../nf-ng-canvas-graph-controls-controller.js   |   2 +-
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |  54 ++-
 .../webapp/js/nf/canvas/nf-canvas-bootstrap.js  |  11 +-
 .../main/webapp/js/nf/canvas/nf-canvas-utils.js |  11 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  18 +
 .../webapp/js/nf/canvas/nf-component-state.js   |   2 +-
 .../webapp/js/nf/canvas/nf-component-version.js |   2 +-
 .../main/webapp/js/nf/canvas/nf-context-menu.js |  97 +++-
 .../main/webapp/js/nf/canvas/nf-flow-version.js | 476 +++++++++++++++++++
 .../nf/canvas/nf-process-group-configuration.js |   2 +-
 .../webapp/js/nf/canvas/nf-process-group.js     |  15 +
 .../src/main/webapp/js/nf/canvas/nf-settings.js | 392 ++++++++++++++-
 .../views/nf-ng-breadcrumbs-directive-view.html |   1 +
 55 files changed, 2465 insertions(+), 246 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java
new file mode 100644
index 0000000..3c004c7
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details about a bucket in a registry.
+ */
+@XmlType(name = "bucket")
+public class BucketDTO {
+
+    private String id;
+    private String name;
+    private String description;
+    private Long created;
+
+    @ApiModelProperty("The bucket identifier")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @ApiModelProperty("The bucket name")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @ApiModelProperty("The bucket description")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @ApiModelProperty("The created timestamp of this bucket")
+    public Long getCreated() {
+        return created;
+    }
+
+    public void setCreated(Long created) {
+        this.created = created;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
index 61b037f..597d700 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
@@ -28,6 +28,7 @@ public class ControllerConfigurationDTO {
 
     private Integer maxTimerDrivenThreadCount;
     private Integer maxEventDrivenThreadCount;
+    private String registryUrl;
 
     /**
      * @return maximum number of timer driven threads this NiFi has available

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java
index 657d760..03e1a7d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java
@@ -32,6 +32,7 @@ public class FlowConfigurationDTO {
     private Boolean supportsManagedAuthorizer;
     private Boolean supportsConfigurableAuthorizer;
     private Boolean supportsConfigurableUsersAndGroups;
+    private Boolean supportsFlowVersioning;
     private Long autoRefreshIntervalSeconds;
 
     private Date currentTime;
@@ -127,4 +128,18 @@ public class FlowConfigurationDTO {
     public void setTimeOffset(Integer timeOffset) {
         this.timeOffset = timeOffset;
     }
+
+    /**
+     * @return whether this NiFi is configured for support flow versioning
+     */
+    @ApiModelProperty(
+            value = "Whether this NiFi supports flow versioning."
+    )
+    public Boolean getSupportsFlowVersioning() {
+        return supportsFlowVersioning;
+    }
+
+    public void setSupportsFlowVersioning(Boolean supportsFlowVersioning) {
+        this.supportsFlowVersioning = supportsFlowVersioning;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java
new file mode 100644
index 0000000..f630430
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details about a configured registry.
+ */
+@XmlType(name = "registry")
+public class RegistryDTO {
+
+    private String id;
+    private String name;
+    private String description;
+    private String uri;
+
+    @ApiModelProperty("The registry identifier")
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @ApiModelProperty("The registry name")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @ApiModelProperty("The registry description")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @ApiModelProperty("The registry URI")
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java
index 27a83e6..1e1f5f5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java
@@ -28,6 +28,7 @@ public class VersionedFlowDTO {
     private String flowId;
     private String flowName;
     private String description;
+    private String comments;
 
     @ApiModelProperty("The ID of the registry that the flow is tracked to")
     public String getRegistryId() {
@@ -73,4 +74,13 @@ public class VersionedFlowDTO {
     public void setDescription(String description) {
         this.description = description;
     }
+
+    @ApiModelProperty("Comments for the changeset")
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java
index 170a30f..60af3fa 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.web.api.dto.flow;
 
 import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
 
 import javax.xml.bind.annotation.XmlType;
 
@@ -28,6 +29,7 @@ public class FlowBreadcrumbDTO {
 
     private String id;
     private String name;
+    private VersionControlInformationDTO versionControlInformation;
 
     /**
      * The id for this group.
@@ -60,4 +62,18 @@ public class FlowBreadcrumbDTO {
     public void setName(final String name) {
         this.name = name;
     }
+
+    /**
+     * @return the process group version control information or null if not version controlled
+     */
+    @ApiModelProperty(
+            value = "The process group version control information or null if not version controlled."
+    )
+    public VersionControlInformationDTO getVersionControlInformation() {
+        return versionControlInformation;
+    }
+
+    public void setVersionControlInformation(VersionControlInformationDTO versionControlInformation) {
+        this.versionControlInformation = versionControlInformation;
+    }
 }

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

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

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

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

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java
index e8ec81f..749a118 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java
@@ -25,16 +25,16 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement(name = "versionControlInformationEntity")
 public class VersionControlInformationEntity extends Entity {
-    private VersionControlInformationDTO versionControlDto;
+    private VersionControlInformationDTO versionControlInformation;
     private RevisionDTO processGroupRevision;
 
     @ApiModelProperty("The Version Control information")
     public VersionControlInformationDTO getVersionControlInformation() {
-        return versionControlDto;
+        return versionControlInformation;
     }
 
     public void setVersionControlInformation(VersionControlInformationDTO versionControlDto) {
-        this.versionControlDto = versionControlDto;
+        this.versionControlInformation = versionControlDto;
     }
 
     @ApiModelProperty("The Revision for the Process Group")

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
index 8934788..d335461 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
@@ -16,7 +16,6 @@
  */
 package org.apache.nifi.groups;
 
-import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -42,7 +41,6 @@ import org.apache.nifi.flowfile.FlowFile;
 import org.apache.nifi.processor.Processor;
 import org.apache.nifi.registry.ComponentVariableRegistry;
 import org.apache.nifi.registry.flow.FlowRegistryClient;
-import org.apache.nifi.registry.flow.UnknownResourceException;
 import org.apache.nifi.registry.flow.VersionControlInformation;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
 import org.apache.nifi.remote.RemoteGroupPort;
@@ -941,6 +939,11 @@ public interface ProcessGroup extends ComponentAuthorizable, Positionable, Versi
     void setVersionControlInformation(VersionControlInformation versionControlInformation, Map<String, String> versionedComponentIds);
 
     /**
+     * Disconnects this Process Group from version control. If not currently under version control, this method does nothing.
+     */
+    void disconnectVersionControl();
+
+    /**
      * Synchronizes the Process Group with the given Flow Registry, determining whether or not the local flow
      * is up to date with the newest version of the flow in the Registry and whether or not the local flow has been
      * modified since it was last synced with the Flow Registry. If this Process Group is not under Version Control,

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java
index a5bb738..962a940 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java
@@ -17,7 +17,11 @@
 
 package org.apache.nifi.registry.flow;
 
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.registry.bucket.Bucket;
+
 import java.io.IOException;
+import java.util.Set;
 
 public interface FlowRegistry {
 
@@ -27,6 +31,19 @@ public interface FlowRegistry {
     String getURL();
 
     /**
+     * @return the name of the Flow Registry
+     */
+    String getName();
+
+    /**
+     * Gets the buckets for the specified user.
+     *
+     * @param user current user
+     * @return buckets for this user
+     */
+    Set<Bucket> getBuckets(NiFiUser user) throws IOException;
+
+    /**
      * Registers the given Versioned Flow with the Flow Registry
      *
      * @param flow the Versioned Flow to add to the registry

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
index 09d032e..6548004 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml
@@ -160,6 +160,11 @@
             <groupId>org.apache.nifi.registry</groupId>
             <artifactId>nifi-registry-flow-diff</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.curator</groupId>

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
index 282c50d..3b8117b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
@@ -16,30 +16,6 @@
  */
 package org.apache.nifi.groups;
 
-import static java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -133,6 +109,30 @@ import org.apache.nifi.web.api.dto.TemplateDTO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
+
 public final class StandardProcessGroup implements ProcessGroup {
 
     private final String id;
@@ -2835,6 +2835,16 @@ public final class StandardProcessGroup implements ProcessGroup {
         }
     }
 
+    public void disconnectVersionControl() {
+        writeLock.lock();
+        try {
+            // TODO remove version component ids from each component (until another versioned PG is encountered)
+            this.versionControlInfo.set(null);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
     private void updateVersionedComponentIds(final ProcessGroup processGroup, final Map<String, String> versionedComponentIds) {
         if (versionedComponentIds == null || versionedComponentIds.isEmpty()) {
             return;

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java
index 22ba50b..2cc39c6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java
@@ -17,6 +17,15 @@
 
 package org.apache.nifi.registry.flow;
 
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.registry.bucket.Bucket;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -35,13 +44,6 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.UUID;
 
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.map.DeserializationConfig;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.util.DefaultPrettyPrinter;
-
 /**
  * A simple file-based implementation of a Flow Registry Client. Rather than interacting
  * with an actual Flow Registry, this implementation simply reads flows from disk and writes
@@ -114,6 +116,35 @@ public class FileBasedFlowRegistryClient implements FlowRegistryClient, FlowRegi
     }
 
     @Override
+    public String getName() {
+        return "Local Registry";
+    }
+
+    @Override
+    public Set<Bucket> getBuckets(NiFiUser user) throws IOException {
+        final Set<Bucket> buckets = new HashSet<>();
+
+        final File[] bucketDirs = directory.listFiles();
+        if (bucketDirs == null) {
+            throw new IOException("Could not get listing of directory " + directory);
+        }
+
+        for (final File bucketDirectory : bucketDirs) {
+            final String bucketIdentifier = bucketDirectory.getName();
+            final long creation = bucketDirectory.lastModified();
+
+            final Bucket bucket = new Bucket();
+            bucket.setIdentifier(bucketIdentifier);
+            bucket.setName("Bucket '" + bucketIdentifier + "'");
+            bucket.setCreatedTimestamp(creation);
+
+            buckets.add(bucket);
+        }
+
+        return buckets;
+    }
+
+    @Override
     public synchronized VersionedFlow registerVersionedFlow(final VersionedFlow flow) throws IOException, UnknownResourceException {
         Objects.requireNonNull(flow);
         Objects.requireNonNull(flow.getBucketIdentifier());
@@ -303,9 +334,9 @@ public class FileBasedFlowRegistryClient implements FlowRegistryClient, FlowRegi
         final File contentsFile = new File(versionDir, "flow.xml");
 
         final VersionedProcessGroup processGroup;
-        try (final JsonParser parser = jsonFactory.createJsonParser(contentsFile)) {
+        try (final JsonParser parser = jsonFactory.createParser(contentsFile)) {
             final ObjectMapper mapper = new ObjectMapper();
-            mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 
             parser.setCodec(mapper);
             processGroup = parser.readValueAs(VersionedProcessGroup.class);

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
index 27e1678..18dc51b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
@@ -17,16 +17,6 @@
 
 package org.apache.nifi.controller.service.mock;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-
 import org.apache.nifi.authorization.Resource;
 import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.connectable.Connectable;
@@ -52,6 +42,16 @@ import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
 import org.apache.nifi.registry.variable.MutableVariableRegistry;
 import org.apache.nifi.remote.RemoteGroupPort;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
 public class MockProcessGroup implements ProcessGroup {
     private final Map<String, ControllerServiceNode> serviceMap = new HashMap<>();
     private final Map<String, ProcessorNode> processorMap = new HashMap<>();
@@ -661,4 +661,9 @@ public class MockProcessGroup implements ProcessGroup {
     public void setVersionControlInformation(VersionControlInformation versionControlInformation, Map<String, String> versionedComponentIds) {
         this.versionControlInfo = versionControlInformation;
     }
+
+    @Override
+    public void disconnectVersionControl() {
+        this.versionControlInfo = null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index 84e582c..a68ad0c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -16,14 +16,6 @@
  */
 package org.apache.nifi.web;
 
-import java.io.IOException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-
 import org.apache.nifi.authorization.AuthorizeAccess;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.user.NiFiUser;
@@ -31,7 +23,6 @@ import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.controller.repository.claim.ContentDirection;
 import org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.groups.ProcessGroup;
-import org.apache.nifi.registry.flow.FlowRegistryClient;
 import org.apache.nifi.registry.flow.UnknownResourceException;
 import org.apache.nifi.registry.flow.VersionedFlow;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
@@ -62,6 +53,7 @@ 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.PropertyDescriptorDTO;
+import org.apache.nifi.web.api.dto.RegistryDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
@@ -104,6 +96,7 @@ import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorEntity;
 import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
+import org.apache.nifi.web.api.entity.RegistryEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
@@ -119,6 +112,14 @@ import org.apache.nifi.web.api.entity.VersionControlComponentMappingEntity;
 import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
 import org.apache.nifi.web.api.entity.VersionedFlowEntity;
 
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+
 /**
  * Defines the NiFiServiceFacade interface.
  */
@@ -1320,6 +1321,14 @@ public interface NiFiServiceFacade {
     VersionControlInformationEntity setVersionControlInformation(Revision processGroupRevision, String processGroupId, VersionControlInformationDTO versionControlInfo,
         Map<String, String> versionedComponentMapping);
 
+    /**
+     * Disconnects the specified Process Group from version control.
+     *
+     * @param revision revision
+     * @param processGroupId group id
+     * @return version control information prior to disconnecting
+     */
+    VersionControlInformationEntity deleteVersionControl(final Revision revision, final String processGroupId);
 
     /**
      * Retrieves the Versioned Flow Snapshot for the coordinates provided by the given Version Control Information DTO
@@ -1381,8 +1390,6 @@ public interface NiFiServiceFacade {
     ProcessGroupEntity updateProcessGroup(NiFiUser user, Revision revision, String groupId, VersionControlInformationDTO versionControlInfo, VersionedFlowSnapshot snapshot, String componentIdSeed,
         boolean verifyNotModified);
 
-    void setFlowRegistryClient(FlowRegistryClient flowRegistryClient);
-
     // ----------------------------------------
     // Component state methods
     // ----------------------------------------
@@ -1829,6 +1836,52 @@ public interface NiFiServiceFacade {
     void verifyDeleteReportingTask(String reportingTaskId);
 
     // ----------------------------------------
+    // Registry methods
+    // ----------------------------------------
+
+    /**
+     * Creates a registry.
+     *
+     * @param revision revision
+     * @param registryDTO The registry DTO
+     * @return The reporting task DTO
+     */
+    RegistryEntity createRegistry(Revision revision, RegistryDTO registryDTO);
+
+    /**
+     * Gets a registry with the specified id.
+     *
+     * @param registryId id
+     * @return entity
+     */
+    RegistryEntity getRegistry(String registryId);
+
+    /**
+     * Gets all registries.
+     *
+     * @return registries
+     */
+    Set<RegistryEntity> getRegistries();
+
+    /**
+     * Updates the specified registry using the specified revision.
+     *
+     * @param revision revision
+     * @param registryDTO the registry dto
+     * @return the updated registry registry entity
+     */
+    RegistryEntity updateRegistry(Revision revision, RegistryDTO registryDTO);
+
+    /**
+     * Deletes the specified registry using the specified revision.
+     *
+     * @param revision revision
+     * @param registryId id
+     * @return the deleted registry entity
+     */
+    RegistryEntity deleteRegistry(Revision revision, String registryId);
+
+    // ----------------------------------------
     // History methods
     // ----------------------------------------
     /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
index 0881cdf..065db86 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
@@ -98,6 +98,7 @@ public class NiFiWebApiResourceConfig extends ResourceConfig {
         register(ctx.getBean("accessResource"));
         register(ctx.getBean("accessPolicyResource"));
         register(ctx.getBean("tenantsResource"));
+        register(ctx.getBean("versionsResource"));
 
         // exception mappers
         register(AccessDeniedExceptionMapper.class);

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index d3a5fd0..0105bf1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -16,32 +16,7 @@
  */
 package org.apache.nifi.web;
 
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.function.Function;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
-
+import com.google.common.collect.Sets;
 import org.apache.nifi.action.Action;
 import org.apache.nifi.action.Component;
 import org.apache.nifi.action.FlowChangeAction;
@@ -141,6 +116,7 @@ import org.apache.nifi.reporting.BulletinQuery;
 import org.apache.nifi.reporting.BulletinRepository;
 import org.apache.nifi.reporting.ComponentType;
 import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.Tuple;
 import org.apache.nifi.web.api.dto.AccessPolicyDTO;
 import org.apache.nifi.web.api.dto.AccessPolicySummaryDTO;
 import org.apache.nifi.web.api.dto.AffectedComponentDTO;
@@ -179,6 +155,7 @@ import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
 import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.PropertyHistoryDTO;
+import org.apache.nifi.web.api.dto.RegistryDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
@@ -236,6 +213,7 @@ import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity;
 import org.apache.nifi.web.api.entity.ProcessorEntity;
 import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
+import org.apache.nifi.web.api.entity.RegistryEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
@@ -279,7 +257,30 @@ import org.apache.nifi.web.util.SnippetUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Sets;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 /**
  * Implementation of NiFiServiceFacade that performs revision checking.
@@ -330,6 +331,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     private AuthorizableLookup authorizableLookup;
 
+    private Map<String, Tuple<Revision, RegistryDTO>> registryCache = new HashMap<>();
+
     // -----------------------------------------
     // Synchronization methods
     // -----------------------------------------
@@ -2257,6 +2260,45 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         return entityFactory.createControllerServiceEntity(snapshot, null, permissions, null);
     }
 
+    private RegistryEntity createRegistryEntity(final Revision updatedRevision, final RegistryDTO registryDTO) {
+        final RegistryEntity entity = new RegistryEntity();
+        entity.setId(registryDTO.getId());
+        entity.setPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController()));
+        entity.setRevision(dtoFactory.createRevisionDTO(updatedRevision));
+        entity.setComponent(registryDTO);
+        return entity;
+    }
+
+    @Override
+    public RegistryEntity createRegistry(Revision revision, RegistryDTO registryDTO) {
+        registryCache.put(registryDTO.getId(), new Tuple(revision, registryDTO));
+        return createRegistryEntity(revision, registryDTO);
+    }
+
+    @Override
+    public RegistryEntity getRegistry(String registryId) {
+        final Tuple<Revision, RegistryDTO> registry = registryCache.get(registryId);
+        return createRegistry(registry.getKey(), registry.getValue());
+    }
+
+    @Override
+    public Set<RegistryEntity> getRegistries() {
+        return registryCache.values().stream()
+                .map(registry -> createRegistry(registry.getKey(), registry.getValue()))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public RegistryEntity updateRegistry(Revision revision, RegistryDTO registryDTO) {
+        registryCache.put(registryDTO.getId(), new Tuple(revision, registryDTO));
+        return createRegistryEntity(revision, registryDTO);
+    }
+
+    @Override
+    public RegistryEntity deleteRegistry(Revision revision, String registryId) {
+        final Tuple<Revision, RegistryDTO> registry = registryCache.remove(registryId);
+        return createRegistryEntity(registry.getKey(), registry.getValue());
+    }
 
     @Override
     public ReportingTaskEntity createReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) {
@@ -3504,7 +3546,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
             return null;
         }
 
-        final VersionControlInformationDTO versionControlDto = dtoFactory.createVersionControlInformationDto(versionControlInfo);
+        final VersionControlInformationDTO versionControlDto = dtoFactory.createVersionControlInformationDto(processGroup);
         final RevisionDTO groupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(groupId));
         return entityFactory.createVersionControlInformationEntity(versionControlDto, groupRevision);
     }
@@ -3555,7 +3597,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         final RevisionUpdate<VersionControlInformationDTO> snapshot = updateComponent(revision,
             group,
             () -> processGroupDAO.updateVersionControlInformation(versionControlInfo, versionedComponentMapping),
-            processGroup -> dtoFactory.createVersionControlInformationDto(processGroup.getVersionControlInformation()));
+            processGroup -> dtoFactory.createVersionControlInformationDto(processGroup));
+
+        return entityFactory.createVersionControlInformationEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()));
+    }
+
+    @Override
+    public VersionControlInformationEntity deleteVersionControl(final Revision revision, final String processGroupId) {
+        final ProcessGroup group = processGroupDAO.getProcessGroup(processGroupId);
+
+        final RevisionUpdate<VersionControlInformationDTO> snapshot = updateComponent(revision,
+            group,
+            () -> processGroupDAO.disconnectVersionControl(processGroupId),
+            processGroup -> dtoFactory.createVersionControlInformationDto(group));
 
         return entityFactory.createVersionControlInformationEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()));
     }
@@ -3835,12 +3889,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, permissions, status, bulletinEntities);
     }
 
-
-    @Override
-    public void setFlowRegistryClient(final FlowRegistryClient client) {
-        this.flowRegistryClient = client;
-    }
-
     private AuthorizationResult authorizeAction(final Action action) {
         final String sourceId = action.getSourceId();
         final Component type = action.getSourceType();
@@ -4194,4 +4242,28 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     public void setLeaderElectionManager(final LeaderElectionManager leaderElectionManager) {
         this.leaderElectionManager = leaderElectionManager;
     }
+
+    public void setFlowRegistryClient(FlowRegistryClient flowRegistryClient) {
+        this.flowRegistryClient = flowRegistryClient;
+
+        // temp code to load the registry client cache
+        final Set<String> registryIdentifiers = flowRegistryClient.getRegistryIdentifiers();
+        if (registryIdentifiers != null) {
+
+            for (final String registryIdentifier : registryIdentifiers) {
+                final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(registryIdentifier);
+
+                final RegistryDTO registry = new RegistryDTO();
+                registry.setId(registryIdentifier);
+                registry.setName(flowRegistry.getName());
+                registry.setUri(flowRegistry.getURL());
+                registry.setDescription("Default client for storing Flow Revisions to the local disk.");
+
+                final RegistryEntity registryEntity = new RegistryEntity();
+                registryEntity.setComponent(registry);
+
+                registryCache.put(registryIdentifier, new Tuple(new Revision(0L, null, registryIdentifier), registry));
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
index b213755..959d06d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
@@ -37,6 +37,7 @@ import org.apache.nifi.web.api.dto.BulletinDTO;
 import org.apache.nifi.web.api.dto.ClusterDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.NodeDTO;
+import org.apache.nifi.web.api.dto.RegistryDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
 import org.apache.nifi.web.api.entity.BulletinEntity;
 import org.apache.nifi.web.api.entity.ClusterEntity;
@@ -45,12 +46,16 @@ import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import org.apache.nifi.web.api.entity.Entity;
 import org.apache.nifi.web.api.entity.HistoryEntity;
 import org.apache.nifi.web.api.entity.NodeEntity;
+import org.apache.nifi.web.api.entity.RegistryEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
+import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.DateTimeParameter;
+import org.apache.nifi.web.api.request.LongParameter;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.POST;
@@ -82,6 +87,17 @@ public class ControllerResource extends ApplicationResource {
     private ControllerServiceResource controllerServiceResource;
 
     /**
+     * Populate the uri's for the specified registry.
+     *
+     * @param registryEntity registry
+     * @return dtos
+     */
+    public RegistryEntity populateRemainingRegistryEntityContent(final RegistryEntity registryEntity) {
+        registryEntity.setUri(generateResourceUri("controller", "registries", registryEntity.getId()));
+        return registryEntity;
+    }
+
+    /**
      * Authorizes access to the flow.
      */
     private void authorizeController(final RequestAction action) {
@@ -290,6 +306,288 @@ public class ControllerResource extends ApplicationResource {
         );
     }
 
+    // ----------
+    // registries
+    // ----------
+
+    /**
+     * Creates a new Registry.
+     *
+     * @param httpServletRequest  request
+     * @param requestRegistryEntity A registryEntity.
+     * @return A registryEntity.
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("registries")
+    @ApiOperation(
+            value = "Creates a new registry",
+            response = RegistryEntity.class,
+            authorizations = {
+                    @Authorization(value = "Write - /controller")
+            }
+    )
+    @ApiResponses(
+            value = {
+                    @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+                    @ApiResponse(code = 401, message = "Client could not be authenticated."),
+                    @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+                    @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+            }
+    )
+
+    public Response createRegistry(
+            @Context final HttpServletRequest httpServletRequest,
+            @ApiParam(
+                    value = "The registry configuration details.",
+                    required = true
+            ) final RegistryEntity requestRegistryEntity) {
+
+        if (requestRegistryEntity == null || requestRegistryEntity.getComponent() == null) {
+            throw new IllegalArgumentException("Registry details must be specified.");
+        }
+
+        if (requestRegistryEntity.getRevision() == null || (requestRegistryEntity.getRevision().getVersion() == null || requestRegistryEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Registry.");
+        }
+
+        final RegistryDTO requestReportingTask = requestRegistryEntity.getComponent();
+        if (requestReportingTask.getId() != null) {
+            throw new IllegalArgumentException("Registry ID cannot be specified.");
+        }
+
+        if (isReplicateRequest()) {
+            return replicate(HttpMethod.POST, requestRegistryEntity);
+        }
+
+        return withWriteLock(
+                serviceFacade,
+                requestRegistryEntity,
+                lookup -> {
+                    authorizeController(RequestAction.WRITE);
+                },
+                null,
+                (registryEntity) -> {
+                    final RegistryDTO registry = registryEntity.getComponent();
+
+                    // set the processor id as appropriate
+                    registry.setId(generateUuid());
+
+                    // create the reporting task and generate the json
+                    final Revision revision = getRevision(registryEntity, registry.getId());
+                    final RegistryEntity entity = serviceFacade.createRegistry(revision, registry);
+                    populateRemainingRegistryEntityContent(entity);
+
+                    // build the response
+                    return generateCreatedResponse(URI.create(entity.getUri()), entity).build();
+                }
+        );
+    }
+
+    /**
+     * Retrieves the specified registry.
+     *
+     * @param id The id of the registry to retrieve
+     * @return A registryEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/registries/{id}")
+    @ApiOperation(
+            value = "Gets a registry",
+            response = RegistryEntity.class,
+            authorizations = {
+                    @Authorization(value = "Read - /controller")
+            }
+    )
+    @ApiResponses(
+            value = {
+                    @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+                    @ApiResponse(code = 401, message = "Client could not be authenticated."),
+                    @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+                    @ApiResponse(code = 404, message = "The specified resource could not be found."),
+                    @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+            }
+    )
+    public Response getRegistry(
+            @ApiParam(
+                    value = "The registry id.",
+                    required = true
+            )
+            @PathParam("id") final String id) {
+
+        if (isReplicateRequest()) {
+            return replicate(HttpMethod.GET);
+        }
+
+        // authorize access
+        authorizeController(RequestAction.READ);
+
+        // get the registry
+        final RegistryEntity entity = serviceFacade.getRegistry(id);
+        populateRemainingRegistryEntityContent(entity);
+
+        return generateOkResponse(entity).build();
+    }
+
+    /**
+     * Updates the specified registry.
+     *
+     * @param httpServletRequest      request
+     * @param id                      The id of the controller service to update.
+     * @param requestRegsitryEntity A controllerServiceEntity.
+     * @return A controllerServiceEntity.
+     */
+    @PUT
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/registries/{id}")
+    @ApiOperation(
+            value = "Updates a registry",
+            response = RegistryEntity.class,
+            authorizations = {
+                    @Authorization(value = "Write - /controller")
+            }
+    )
+    @ApiResponses(
+            value = {
+                    @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+                    @ApiResponse(code = 401, message = "Client could not be authenticated."),
+                    @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+                    @ApiResponse(code = 404, message = "The specified resource could not be found."),
+                    @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+            }
+    )
+    public Response updateControllerService(
+            @Context HttpServletRequest httpServletRequest,
+            @ApiParam(
+                    value = "The registry id.",
+                    required = true
+            )
+            @PathParam("id") final String id,
+            @ApiParam(
+                    value = "The registry configuration details.",
+                    required = true
+            ) final RegistryEntity requestRegsitryEntity) {
+
+        if (requestRegsitryEntity == null || requestRegsitryEntity.getComponent() == null) {
+            throw new IllegalArgumentException("Registry details must be specified.");
+        }
+
+        if (requestRegsitryEntity.getRevision() == null) {
+            throw new IllegalArgumentException("Revision must be specified.");
+        }
+
+        // ensure the ids are the same
+        final RegistryDTO requestRegistryDTO = requestRegsitryEntity.getComponent();
+        if (!id.equals(requestRegistryDTO.getId())) {
+            throw new IllegalArgumentException(String.format("The registry id (%s) in the request body does not equal the "
+                    + "registry id of the requested resource (%s).", requestRegistryDTO.getId(), id));
+        }
+
+        if (isReplicateRequest()) {
+            return replicate(HttpMethod.PUT, requestRegsitryEntity);
+        }
+
+        // handle expects request (usually from the cluster manager)
+        final Revision requestRevision = getRevision(requestRegsitryEntity, id);
+        return withWriteLock(
+                serviceFacade,
+                requestRegsitryEntity,
+                requestRevision,
+                lookup -> {
+                    authorizeController(RequestAction.WRITE);
+                },
+                null,
+                (revision, registryEntity) -> {
+                    final RegistryDTO registry = registryEntity.getComponent();
+
+                    // update the controller service
+                    final RegistryEntity entity = serviceFacade.updateRegistry(revision, registry);
+                    populateRemainingRegistryEntityContent(entity);
+
+                    return generateOkResponse(entity).build();
+                }
+        );
+    }
+
+    /**
+     * Removes the specified registry.
+     *
+     * @param httpServletRequest request
+     * @param version            The revision is used to verify the client is working with
+     *                           the latest version of the flow.
+     * @param clientId           Optional client id. If the client id is not specified, a
+     *                           new one will be generated. This value (whether specified or generated) is
+     *                           included in the response.
+     * @param id                 The id of the registry to remove.
+     * @return A entity containing the client id and an updated revision.
+     */
+    @DELETE
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/registries/{id}")
+    @ApiOperation(
+            value = "Deletes a reistry",
+            response = RegistryEntity.class,
+            authorizations = {
+                    @Authorization(value = "Write - /controller")
+            }
+    )
+    @ApiResponses(
+            value = {
+                    @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+                    @ApiResponse(code = 401, message = "Client could not be authenticated."),
+                    @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+                    @ApiResponse(code = 404, message = "The specified resource could not be found."),
+                    @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+            }
+    )
+    public Response deleteRegistry(
+            @Context HttpServletRequest httpServletRequest,
+            @ApiParam(
+                    value = "The revision is used to verify the client is working with the latest version of the flow.",
+                    required = false
+            )
+            @QueryParam(VERSION) final LongParameter version,
+            @ApiParam(
+                    value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
+                    required = false
+            )
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final ClientIdParameter clientId,
+            @ApiParam(
+                    value = "The registry id.",
+                    required = true
+            )
+            @PathParam("id") final String id) {
+
+        if (isReplicateRequest()) {
+            return replicate(HttpMethod.DELETE);
+        }
+
+        final RegistryEntity requestRegistryEntity = new RegistryEntity();
+        requestRegistryEntity.setId(id);
+
+        // handle expects request (usually from the cluster manager)
+        final Revision requestRevision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id);
+        return withWriteLock(
+                serviceFacade,
+                requestRegistryEntity,
+                requestRevision,
+                lookup -> {
+                    authorizeController(RequestAction.WRITE);
+                },
+                null,
+                (revision, registryEntity) -> {
+                    // delete the specified registry
+                    final RegistryEntity entity = serviceFacade.deleteRegistry(revision, registryEntity.getId());
+                    return generateOkResponse(entity).build();
+                }
+        );
+    }
+
     /**
      * Creates a Bulletin.
      *

http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
index 38e8891..3e9be6d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
@@ -39,13 +39,18 @@ import org.apache.nifi.controller.service.ControllerServiceNode;
 import org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.groups.ProcessGroup;
 import org.apache.nifi.nar.NarClassLoaders;
+import org.apache.nifi.registry.bucket.Bucket;
+import org.apache.nifi.registry.flow.FlowRegistry;
+import org.apache.nifi.registry.flow.FlowRegistryClient;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.IllegalClusterResourceRequestException;
+import org.apache.nifi.web.NiFiCoreException;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.ResourceNotFoundException;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.api.dto.AboutDTO;
 import org.apache.nifi.web.api.dto.BannerDTO;
+import org.apache.nifi.web.api.dto.BucketDTO;
 import org.apache.nifi.web.api.dto.BulletinBoardDTO;
 import org.apache.nifi.web.api.dto.BulletinQueryDTO;
 import org.apache.nifi.web.api.dto.ClusterDTO;
@@ -64,6 +69,8 @@ import org.apache.nifi.web.api.entity.AboutEntity;
 import org.apache.nifi.web.api.entity.ActionEntity;
 import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
 import org.apache.nifi.web.api.entity.BannerEntity;
+import org.apache.nifi.web.api.entity.BucketEntity;
+import org.apache.nifi.web.api.entity.BucketsEntity;
 import org.apache.nifi.web.api.entity.BulletinBoardEntity;
 import org.apache.nifi.web.api.entity.ClusteSummaryEntity;
 import org.apache.nifi.web.api.entity.ClusterSearchResultsEntity;
@@ -84,6 +91,8 @@ import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorTypesEntity;
+import org.apache.nifi.web.api.entity.RegistriesEntity;
+import org.apache.nifi.web.api.entity.RegistryEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity;
@@ -112,6 +121,7 @@ import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.EnumSet;
@@ -148,8 +158,11 @@ public class FlowResource extends ApplicationResource {
     private TemplateResource templateResource;
     private ProcessGroupResource processGroupResource;
     private ControllerServiceResource controllerServiceResource;
+    private ControllerResource controllerResource;
     private ReportingTaskResource reportingTaskResource;
 
+    private FlowRegistryClient flowRegistryClient;
+
     public FlowResource() {
         super();
     }
@@ -1317,6 +1330,98 @@ public class FlowResource extends ApplicationResource {
         return generateOkResponse(entity).build();
     }
 
+    // ----------
+    // registries
+    // ----------
+
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("registries")
+    @ApiOperation(value = "Gets the listing of available registries", response = RegistriesEntity.class, authorizations = {
+            @Authorization(value = "Read - /flow")
+    })
+    @ApiResponses(value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+    })
+    public Response getRegistries() {
+        authorizeFlow();
+
+        if (isReplicateRequest()) {
+            return replicate(HttpMethod.GET);
+        }
+
+        final Set<RegistryEntity> registries = serviceFacade.getRegistries();
+        registries.forEach(registry -> controllerResource.populateRemainingRegistryEntityContent(registry));
+
+        final RegistriesEntity registryEntities = new RegistriesEntity();
+        registryEntities.setRegistries(registries);
+
+        return generateOkResponse(registryEntities).build();
+    }
+
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("registries/{id}/buckets")
+    @ApiOperation(value = "Gets the buckets from the specified registry for the current user", response = BucketsEntity.class, authorizations = {
+            @Authorization(value = "Read - /flow")
+    })
+    @ApiResponses(value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
+            @ApiResponse(code = 401, message = "Client could not be authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
+            @ApiResponse(code = 404, message = "The specified resource could not be found."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
+    })
+    public Response getBuckets(
+            @ApiParam(
+                    value = "The registry id.",
+                    required = true
+            )
+            @PathParam("id") String id) {
+
+        authorizeFlow();
+
+        try {
+            final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(id);
+            if (flowRegistry == null) {
+                throw new IllegalArgumentException("The specified registry id is unknown to this NiFi.");
+            }
+
+            final Set<Bucket> userBuckets = flowRegistry.getBuckets(NiFiUserUtils.getNiFiUser());
+
+            final BucketsEntity bucketsEntity = new BucketsEntity();
+
+            if (userBuckets != null) {
+
+                final Set<BucketEntity> bucketSet = new HashSet<>();
+                for (final Bucket userBucket : userBuckets) {
+                    final BucketDTO bucket = new BucketDTO();
+                    bucket.setId(userBucket.getIdentifier());
+                    bucket.setName(userBucket.getName());
+                    bucket.setDescription(userBucket.getDescription());
+                    bucket.setCreated(userBucket.getCreatedTimestamp());
+
+                    final BucketEntity bucketEntity = new BucketEntity();
+                    bucketEntity.setBucket(bucket);
+
+                    bucketSet.add(bucketEntity);
+                }
+
+                bucketsEntity.setBuckets(bucketSet);
+            }
+
+            return generateOkResponse(bucketsEntity).build();
+        } catch (final IOException ioe) {
+            throw new NiFiCoreException("Unable to obtain bucket listing: " + ioe.getMessage(), ioe);
+        }
+    }
+
     // --------------
     // bulletin board
     // --------------
@@ -2524,6 +2629,10 @@ public class FlowResource extends ApplicationResource {
         this.processGroupResource = processGroupResource;
     }
 
+    public void setControllerResource(ControllerResource controllerResource) {
+        this.controllerResource = controllerResource;
+    }
+
     public void setControllerServiceResource(ControllerServiceResource controllerServiceResource) {
         this.controllerServiceResource = controllerServiceResource;
     }
@@ -2535,4 +2644,8 @@ public class FlowResource extends ApplicationResource {
     public void setAuthorizer(Authorizer authorizer) {
         this.authorizer = authorizer;
     }
+
+    public void setFlowRegistryClient(FlowRegistryClient flowRegistryClient) {
+        this.flowRegistryClient = flowRegistryClient;
+    }
 }