NIFI-1781:
- Including access policies in the breadcrumb's trail.
- Updating toolbox according to group access policies.
- Updating actions in palette based on selection access policies.
NIFI-1554:
- Introducing authorization during two phase commit.
- Introducing snippet authorization according to the encapsulated components 
and the action performed.
- This closes #461


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

Branch: refs/heads/master
Commit: 4dd50c80a4fe086d94998c8e7738dcf149734a84
Parents: d42ea46
Author: Matt Gilman <matt.c.gil...@gmail.com>
Authored: Mon May 23 14:14:22 2016 -0400
Committer: Matt Gilman <matt.c.gil...@gmail.com>
Committed: Mon May 23 14:15:32 2016 -0400

----------------------------------------------------------------------
 .../org/apache/nifi/controller/Snippet.java     |  12 +-
 .../nifi/web/api/dto/ProcessGroupDTO.java       |  15 -
 .../org/apache/nifi/web/api/dto/SnippetDTO.java |  17 -
 .../web/api/dto/flow/FlowBreadcrumbDTO.java     |  17 -
 .../apache/nifi/web/api/dto/flow/FlowDTO.java   |  15 -
 .../web/api/dto/flow/ProcessGroupFlowDTO.java   |   7 +-
 .../web/api/entity/FlowBreadcrumbEntity.java    |  99 +++
 .../web/api/entity/ProcessGroupFlowEntity.java  |  19 +
 .../api/entity/ScheduleComponentsEntity.java    |  77 ++
 .../nifi/web/api/entity/SnippetEntity.java      |   7 +-
 .../nifi/controller/ConfiguredComponent.java    |   3 +-
 .../nifi/controller/ReportingTaskNode.java      |   9 +-
 .../service/ControllerServiceNode.java          |   9 +-
 .../org/apache/nifi/groups/ProcessGroup.java    |  34 +-
 .../apache/nifi/controller/StandardSnippet.java |  14 -
 .../nifi/groups/StandardProcessGroup.java       |  92 +-
 .../service/mock/MockProcessGroup.java          |   7 +
 .../apache/nifi/audit/ProcessGroupAuditor.java  |  73 +-
 .../org/apache/nifi/audit/SnippetAuditor.java   | 157 ++--
 .../org/apache/nifi/web/AuthorizableLookup.java | 154 ++++
 .../org/apache/nifi/web/AuthorizeAccess.java    |  21 +
 .../org/apache/nifi/web/NiFiServiceFacade.java  | 106 ++-
 .../nifi/web/StandardNiFiServiceFacade.java     | 513 ++++++------
 .../nifi/web/api/ApplicationResource.java       | 187 ++++-
 .../apache/nifi/web/api/ConnectionResource.java | 155 ++--
 .../nifi/web/api/ControllerServiceResource.java | 195 +++--
 .../nifi/web/api/FlowFileQueueResource.java     | 159 ++--
 .../org/apache/nifi/web/api/FlowResource.java   | 209 ++++-
 .../org/apache/nifi/web/api/FunnelResource.java | 153 ++--
 .../apache/nifi/web/api/InputPortResource.java  | 139 ++--
 .../org/apache/nifi/web/api/LabelResource.java  | 143 ++--
 .../apache/nifi/web/api/OutputPortResource.java | 151 ++--
 .../nifi/web/api/ProcessGroupResource.java      | 833 ++++++++-----------
 .../apache/nifi/web/api/ProcessorResource.java  | 154 ++--
 .../apache/nifi/web/api/ProvenanceResource.java | 158 ++--
 .../web/api/RemoteProcessGroupResource.java     | 319 ++++---
 .../nifi/web/api/ReportingTaskResource.java     | 137 +--
 .../apache/nifi/web/api/ResourceResource.java   |  35 +
 .../apache/nifi/web/api/SnippetResource.java    | 327 ++++++++
 .../nifi/web/api/SystemDiagnosticsResource.java |  33 +-
 .../apache/nifi/web/api/TemplateResource.java   |  37 +-
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  59 +-
 .../apache/nifi/web/api/dto/EntityFactory.java  |  35 +-
 .../apache/nifi/web/dao/ProcessGroupDAO.java    |  14 +-
 .../org/apache/nifi/web/dao/SnippetDAO.java     |  23 +-
 .../web/dao/impl/StandardProcessGroupDAO.java   |  66 +-
 .../nifi/web/dao/impl/StandardSnippetDAO.java   |  98 +--
 .../src/main/resources/nifi-web-api-context.xml |  19 +
 .../accesscontrol/DfmAccessControlTest.java     |   1 -
 .../nifi/web/revision/NaiveRevisionManager.java |   8 +-
 .../WEB-INF/partials/canvas/canvas-header.jsp   |   8 +
 .../WEB-INF/partials/canvas/navigation.jsp      |  20 +-
 .../src/main/webapp/css/navigation.css          |   1 +
 .../controllers/nf-ng-breadcrumbs-controller.js |  18 +-
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |  64 +-
 .../main/webapp/js/nf/canvas/nf-canvas-utils.js |  57 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  17 +
 .../main/webapp/js/nf/canvas/nf-context-menu.js |   2 +-
 .../js/nf/canvas/nf-processor-configuration.js  |   2 +-
 .../js/nf/canvas/nf-remote-process-group.js     |   4 +-
 .../src/main/webapp/js/nf/canvas/nf-snippet.js  |  73 +-
 .../main/webapp/js/nf/nf-connection-details.js  |   2 +-
 .../main/webapp/js/nf/nf-processor-details.js   |   2 +-
 .../views/nf-ng-breadcrumbs-directive-view.html |   2 +-
 64 files changed, 3397 insertions(+), 2199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java 
b/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java
index 5fad824..702b7cd 100644
--- a/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java
+++ b/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java
@@ -16,10 +16,10 @@
  */
 package org.apache.nifi.controller;
 
-import java.util.Map;
-
 import org.apache.nifi.web.Revision;
 
+import java.util.Map;
+
 /**
  * A Snippet represents a segment of the flow
  */
@@ -31,14 +31,6 @@ public interface Snippet {
     public String getId();
 
     /**
-     * @return Whether or not this snippet is linked to the data flow. If the 
Snippet is
-     * deleted and is linked, then the underlying components will also be
-     * deleted. If the Snippet is deleted and is NOT linked, only the Snippet 
is
-     * removed
-     */
-    public boolean isLinked();
-
-    /**
      * @return parent group id of the components in this snippet
      */
     public String getParentGroupId();

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java
index 224db57..dd18cc4 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java
@@ -27,7 +27,6 @@ public class ProcessGroupDTO extends ComponentDTO {
 
     private String name;
     private String comments;
-    private Boolean running;
 
     private Integer runningCount;
     private Integer stoppedCount;
@@ -132,20 +131,6 @@ public class ProcessGroupDTO extends ComponentDTO {
     }
 
     /**
-     * @return Used in requests, indicates whether this process group should 
be running
-     */
-    @ApiModelProperty(
-            value = "Used in requests, indicates whether the process group 
should be running."
-    )
-    public Boolean isRunning() {
-        return running;
-    }
-
-    public void setRunning(Boolean running) {
-        this.running = running;
-    }
-
-    /**
      * @return number of running component in this process group
      */
     @ApiModelProperty(

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java
index 8362c18..a617cf9 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java
@@ -32,7 +32,6 @@ public class SnippetDTO {
     private String id;
     private String uri;
     private String parentGroupId;
-    private Boolean linked;
 
     // when specified these are only considered during creation
     private Map<String, RevisionDTO> processGroups = new HashMap<>();
@@ -87,22 +86,6 @@ public class SnippetDTO {
     }
 
     /**
-     * @return whether or not this snippet is linked to the underlying data 
flow
-     */
-    @ApiModelProperty(
-            value = "Whether or not the snippet is linked to the underlying 
data flow. For instance if linked was set to true and the snippet was deleted "
-                    + "it would also deleted the components in the snippet. If 
the snippet was not linked, deleting the snippet would only remove the "
-                    + "snippet and leave the component intact."
-    )
-    public Boolean isLinked() {
-        return linked;
-    }
-
-    public void setLinked(Boolean linked) {
-        this.linked = linked;
-    }
-
-    /**
      * @return the ids of the connections in this snippet. These ids will be 
populated within each response. They can be specified when creating a snippet. 
However, once a snippet has been created its
      * contents cannot be modified (these ids are ignored during update 
requests)
      */

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/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 afdfb64..a6f12d7 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
@@ -28,7 +28,6 @@ public class FlowBreadcrumbDTO {
 
     private String id;
     private String name;
-    private FlowBreadcrumbDTO parentBreadcrumb;
 
     /**
      * The id for this group.
@@ -61,20 +60,4 @@ public class FlowBreadcrumbDTO {
     public void setName(final String name) {
         this.name = name;
     }
-
-    /**
-     * The parent breadcrumb for this breadcrumb.
-     *
-     * @return The parent breadcrumb for this breadcrumb
-     */
-    @ApiModelProperty(
-        value = "The parent breadcrumb for this breadcrumb."
-    )
-    public FlowBreadcrumbDTO getParentBreadcrumb() {
-        return parentBreadcrumb;
-    }
-
-    public void setParentBreadcrumb(FlowBreadcrumbDTO parentBreadcrumb) {
-        this.parentBreadcrumb = parentBreadcrumb;
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.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/FlowDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java
index a3a3ae7..557d72f 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java
@@ -18,7 +18,6 @@ package org.apache.nifi.web.api.dto.flow;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
-import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import org.apache.nifi.web.api.entity.FunnelEntity;
 import org.apache.nifi.web.api.entity.LabelEntity;
 import org.apache.nifi.web.api.entity.PortEntity;
@@ -44,7 +43,6 @@ public class FlowDTO {
     private Set<ConnectionEntity> connections = new LinkedHashSet<>();
     private Set<LabelEntity> labels = new LinkedHashSet<>();
     private Set<FunnelEntity> funnels = new LinkedHashSet<>();
-    private Set<ControllerServiceEntity> controllerServices = new 
LinkedHashSet<>();
 
     /**
      * @return connections in this flow
@@ -158,17 +156,4 @@ public class FlowDTO {
         this.remoteProcessGroups = remoteProcessGroups;
     }
 
-    /**
-     * @return the Controller Services in this flow
-     */
-    @ApiModelProperty(
-            value = "The controller services in this flow."
-    )
-    public Set<ControllerServiceEntity> getControllerServices() {
-        return controllerServices;
-    }
-
-    public void setControllerServices(Set<ControllerServiceEntity> 
controllerServices) {
-        this.controllerServices = controllerServices;
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.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/ProcessGroupFlowDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java
index 3970d63..ce5d1e0 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java
@@ -18,6 +18,7 @@ package org.apache.nifi.web.api.dto.flow;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
 import org.apache.nifi.web.api.dto.util.TimeAdapter;
+import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
 
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -32,7 +33,7 @@ public class ProcessGroupFlowDTO {
     private String id;
     private String uri;
     private String parentGroupId;
-    private FlowBreadcrumbDTO breadcrumb;
+    private FlowBreadcrumbEntity breadcrumb;
     private FlowDTO flow;
     private Date lastRefreshed;
 
@@ -74,11 +75,11 @@ public class ProcessGroupFlowDTO {
     @ApiModelProperty(
         value = "The breadcrumb of the process group."
     )
-    public FlowBreadcrumbDTO getBreadcrumb() {
+    public FlowBreadcrumbEntity getBreadcrumb() {
         return breadcrumb;
     }
 
-    public void setBreadcrumb(FlowBreadcrumbDTO breadcrumb) {
+    public void setBreadcrumb(FlowBreadcrumbEntity breadcrumb) {
         this.breadcrumb = breadcrumb;
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java
new file mode 100644
index 0000000..ddd8407
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.AccessPolicyDTO;
+import org.apache.nifi.web.api.dto.flow.FlowBreadcrumbDTO;
+
+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 FlowBreadcrumbDTO.
+ */
+@XmlRootElement(name = "flowEntity")
+public class FlowBreadcrumbEntity extends Entity {
+
+    private String id;
+    private AccessPolicyDTO accessPolicy;
+    private FlowBreadcrumbDTO breadcrumb;
+    private FlowBreadcrumbEntity parentBreadcrumb;
+
+    /**
+     * The id for this ancestor ProcessGroup.
+     *
+     * @return The id
+     */
+    @ApiModelProperty(
+        value = "The id of this ancestor ProcessGroup."
+    )
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * The access policy for this ancestor ProcessGroup.
+     *
+     * @return The access policy
+     */
+    @ApiModelProperty(
+        value = "The access policy for this ancestor ProcessGroup."
+    )
+    public AccessPolicyDTO getAccessPolicy() {
+        return accessPolicy;
+    }
+
+    public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
+        this.accessPolicy = accessPolicy;
+    }
+
+    /**
+     * The FlowBreadcrumbDTO that is being serialized.
+     *
+     * @return The FlowBreadcrumbDTO object
+     */
+    @ApiModelProperty(
+        value = "This breadcrumb."
+    )
+    public FlowBreadcrumbDTO getBreadcrumb() {
+        return breadcrumb;
+    }
+
+    public void setBreadcrumb(FlowBreadcrumbDTO breadcrumb) {
+        this.breadcrumb = breadcrumb;
+    }
+
+    /**
+     * The parent breadcrumb for this breadcrumb.
+     *
+     * @return The parent breadcrumb for this breadcrumb
+     */
+    @ApiModelProperty(
+        value = "The parent breadcrumb for this breadcrumb."
+    )
+    public FlowBreadcrumbEntity getParentBreadcrumb() {
+        return parentBreadcrumb;
+    }
+
+    public void setParentBreadcrumb(FlowBreadcrumbEntity parentBreadcrumb) {
+        this.parentBreadcrumb = parentBreadcrumb;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java
index 8ab1327..8dd3b05 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java
@@ -16,6 +16,8 @@
  */
 package org.apache.nifi.web.api.entity;
 
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.AccessPolicyDTO;
 import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
 
 import javax.xml.bind.annotation.XmlRootElement;
@@ -26,9 +28,26 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement(name = "processGroupFlowEntity")
 public class ProcessGroupFlowEntity extends Entity {
 
+    private AccessPolicyDTO accessPolicy;
     private ProcessGroupFlowDTO processGroupFlow;
 
     /**
+     * The access policy for this component.
+     *
+     * @return The access policy
+     */
+    @ApiModelProperty(
+        value = "The access policy for this process group."
+    )
+    public AccessPolicyDTO getAccessPolicy() {
+        return accessPolicy;
+    }
+
+    public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
+        this.accessPolicy = accessPolicy;
+    }
+
+    /**
      * The ProcessGroupFlowDTO that is being serialized.
      *
      * @return The ProcessGroupFlowDTO object

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java
new file mode 100644
index 0000000..9aeef40
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.entity;
+
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Map;
+
+/**
+ * A serialized representation of this class can be placed in the entity body 
of a request to the API.
+ */
+@XmlRootElement(name = "scheduleComponentEntity")
+public class ScheduleComponentsEntity extends Entity {
+
+    private String id;
+    private String state;
+    private Map<String, RevisionDTO> components;
+
+    /**
+     * @return The id of the ProcessGroup
+     */
+    @ApiModelProperty(
+        value = "The id of the ProcessGroup"
+    )
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return The desired state of the descendant components. Possible states 
are 'RUNNING' and 'STOPPED'
+     */
+    @ApiModelProperty(
+        value = "The desired state of the descendant components",
+        allowableValues = "RUNNING, STOPPED"
+    )
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    /**
+     * @return The components to schedule. If not specified, all authorized 
descendant components will be used.
+     */
+    @ApiModelProperty(
+        value = "Optional components to schedule. If not specified, all 
authorized descendant components will be used."
+    )
+    public Map<String, RevisionDTO> getComponents() {
+        return components;
+    }
+
+    public void setComponents(Map<String, RevisionDTO> components) {
+        this.components = components;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java
index 205dc17..7ec8de6 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java
@@ -16,14 +16,16 @@
  */
 package org.apache.nifi.web.api.entity;
 
-import javax.xml.bind.annotation.XmlRootElement;
+import com.wordnik.swagger.annotations.ApiModelProperty;
 import org.apache.nifi.web.api.dto.SnippetDTO;
 
+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 SnippetDTO.
  */
 @XmlRootElement(name = "snippetEntity")
-public class SnippetEntity extends ComponentEntity {
+public class SnippetEntity extends Entity {
 
     private SnippetDTO snippet;
 
@@ -32,6 +34,7 @@ public class SnippetEntity extends ComponentEntity {
      *
      * @return The SnippetDTO object
      */
+    @ApiModelProperty("The snippet.")
     public SnippetDTO getSnippet() {
         return snippet;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
index 0fcccdd..d053466 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java
@@ -19,10 +19,11 @@ package org.apache.nifi.controller;
 import java.util.Collection;
 import java.util.Map;
 
+import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.ValidationResult;
 
-public interface ConfiguredComponent {
+public interface ConfiguredComponent extends Authorizable {
 
     public String getIdentifier();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java
index a230bcb..28e848f 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java
@@ -16,16 +16,15 @@
  */
 package org.apache.nifi.controller;
 
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.controller.service.ControllerServiceNode;
 import org.apache.nifi.reporting.ReportingContext;
 import org.apache.nifi.reporting.ReportingTask;
 import org.apache.nifi.scheduling.SchedulingStrategy;
 
-public interface ReportingTaskNode extends ConfiguredComponent, Authorizable {
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+public interface ReportingTaskNode extends ConfiguredComponent {
 
     void setSchedulingStrategy(SchedulingStrategy schedulingStrategy);
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
index 710a771..bd3a42b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
@@ -16,15 +16,14 @@
  */
 package org.apache.nifi.controller.service;
 
-import java.util.Set;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.controller.ConfiguredComponent;
 import org.apache.nifi.controller.ControllerService;
 import org.apache.nifi.groups.ProcessGroup;
 
-public interface ControllerServiceNode extends ConfiguredComponent, 
Authorizable {
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+
+public interface ControllerServiceNode extends ConfiguredComponent {
 
     /**
      * @return the Process Group that this Controller Service belongs to, or 
<code>null</code> if the Controller Service

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/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 c3a4c8e..8d026f0 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,10 +16,6 @@
  */
 package org.apache.nifi.groups;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
 import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.connectable.Connectable;
 import org.apache.nifi.connectable.Connection;
@@ -27,6 +23,7 @@ import org.apache.nifi.connectable.Funnel;
 import org.apache.nifi.connectable.Port;
 import org.apache.nifi.connectable.Position;
 import org.apache.nifi.controller.ProcessorNode;
+import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.controller.Snippet;
 import org.apache.nifi.controller.Template;
 import org.apache.nifi.controller.label.Label;
@@ -34,6 +31,11 @@ import 
org.apache.nifi.controller.service.ControllerServiceNode;
 import org.apache.nifi.flowfile.FlowFile;
 import org.apache.nifi.processor.Processor;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+
 /**
  * <p>
  * ProcessGroup objects are containers for processing entities, such as
@@ -46,6 +48,26 @@ import org.apache.nifi.processor.Processor;
 public interface ProcessGroup extends Authorizable {
 
     /**
+     * Predicate for filtering schedulable Processors.
+     */
+    Predicate<ProcessorNode> SCHEDULABLE_PROCESSORS = node -> 
!node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED;
+
+    /**
+     * Predicate for filtering unschedulable Processors.
+     */
+    Predicate<ProcessorNode> UNSCHEDULABLE_PROCESSORS = node -> 
node.isRunning();
+
+    /**
+     * Predicate for filtering schedulable Ports
+     */
+    Predicate<Port> SCHEDULABLE_PORTS = port -> port.getScheduledState() != 
ScheduledState.DISABLED;
+
+    /**
+     * Predicate for filtering schedulable Ports
+     */
+    Predicate<Port> UNSCHEDULABLE_PORTS = port -> port.getScheduledState() == 
ScheduledState.RUNNING;
+
+    /**
      * @return a reference to this ProcessGroup's parent. This will be
      * <tt>null</tt> if and only if this is the root group.
      */
@@ -743,8 +765,12 @@ public interface ProcessGroup extends Authorizable {
      */
     void verifyCanDelete(boolean ignorePortConnections);
 
+    void verifyCanStart(Connectable connectable);
+
     void verifyCanStart();
 
+    void verifyCanStop(Connectable connectable);
+
     void verifyCanStop();
 
     /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java
index 7060699..e17301b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java
@@ -33,7 +33,6 @@ public class StandardSnippet implements Snippet {
 
     private String id;
     private String parentGroupId;
-    private Boolean linked;
 
     private Map<String, Revision> processGroups = new HashMap<>();
     private Map<String, Revision> remoteProcessGroups = new HashMap<>();
@@ -54,19 +53,6 @@ public class StandardSnippet implements Snippet {
     }
 
     @Override
-    public boolean isLinked() {
-        if (linked == null) {
-            return false;
-        } else {
-            return linked;
-        }
-    }
-
-    public void setLinked(Boolean linked) {
-        this.linked = linked;
-    }
-
-    @Override
     public String getParentGroupId() {
         return parentGroupId;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/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 1a3ab52..d3f5a1a 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
@@ -283,38 +283,21 @@ public final class StandardProcessGroup implements 
ProcessGroup {
     public void startProcessing() {
         readLock.lock();
         try {
-            for (final ProcessorNode node : processors.values()) {
+            
findAllProcessors().stream().filter(SCHEDULABLE_PROCESSORS).forEach(node -> {
                 try {
-                    if (!node.isRunning() && node.getScheduledState() != 
ScheduledState.DISABLED) {
-                        startProcessor(node);
-                    }
+                    node.getProcessGroup().startProcessor(node);
                 } catch (final Throwable t) {
                     LOG.error("Unable to start {} due to {}", new 
Object[]{node, t});
                 }
-            }
-
-            for (final Port inputPort : getInputPorts()) {
-                if (inputPort.getScheduledState() != ScheduledState.DISABLED) {
-                    startInputPort(inputPort);
-                }
-            }
-
-            for (final Port outputPort : getOutputPorts()) {
-                if (outputPort.getScheduledState() != ScheduledState.DISABLED) 
{
-                    startOutputPort(outputPort);
-                }
-            }
+            });
 
-            for (final Funnel funnel : getFunnels()) {
-                if (funnel.getScheduledState() != ScheduledState.DISABLED) {
-                    startFunnel(funnel);
-                }
-            }
+            
findAllInputPorts().stream().filter(SCHEDULABLE_PORTS).forEach(port -> {
+                port.getProcessGroup().startInputPort(port);
+            });
 
-            // Recursively start child groups.
-            for (final ProcessGroup group : processGroups.values()) {
-                group.startProcessing();
-            }
+            
findAllOutputPorts().stream().filter(SCHEDULABLE_PORTS).forEach(port -> {
+                port.getProcessGroup().startOutputPort(port);
+            });
         } finally {
             readLock.unlock();
         }
@@ -324,32 +307,21 @@ public final class StandardProcessGroup implements 
ProcessGroup {
     public void stopProcessing() {
         readLock.lock();
         try {
-            for (final ProcessorNode node : processors.values()) {
+            
findAllProcessors().stream().filter(UNSCHEDULABLE_PROCESSORS).forEach(node -> {
                 try {
-                    if (node.isRunning()) {
-                        stopProcessor(node);
-                    }
+                    node.getProcessGroup().stopProcessor(node);
                 } catch (final Throwable t) {
                     LOG.error("Unable to stop {} due to {}", new 
Object[]{node, t});
                 }
-            }
-
-            for (final Port inputPort : getInputPorts()) {
-                if (inputPort.getScheduledState() == ScheduledState.RUNNING) {
-                    stopInputPort(inputPort);
-                }
-            }
+            });
 
-            for (final Port outputPort : getOutputPorts()) {
-                if (outputPort.getScheduledState() == ScheduledState.RUNNING) {
-                    stopOutputPort(outputPort);
-                }
-            }
+            
findAllInputPorts().stream().filter(UNSCHEDULABLE_PORTS).forEach(port -> {
+                port.getProcessGroup().stopInputPort(port);
+            });
 
-            // Recursively stop child groups.
-            for (final ProcessGroup group : processGroups.values()) {
-                group.stopProcessing();
-            }
+            
findAllOutputPorts().stream().filter(UNSCHEDULABLE_PORTS).forEach(port -> {
+                port.getProcessGroup().stopOutputPort(port);
+            });
         } finally {
             readLock.unlock();
         }
@@ -2292,21 +2264,35 @@ public final class StandardProcessGroup implements 
ProcessGroup {
     }
 
     @Override
+    public void verifyCanStop(Connectable connectable) {
+    }
+
+    @Override
     public void verifyCanStop() {
     }
 
     @Override
+    public void verifyCanStart(Connectable connectable) {
+        readLock.lock();
+        try {
+            if (connectable.getScheduledState() == ScheduledState.STOPPED) {
+                if (scheduler.getActiveThreadCount(connectable) > 0) {
+                    throw new IllegalStateException("Cannot start " + 
connectable + " because it is currently stopping");
+                }
+
+                connectable.verifyCanStart();
+            }
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    @Override
     public void verifyCanStart() {
         readLock.lock();
         try {
             for (final Connectable connectable : findAllConnectables(this, 
false)) {
-                if (connectable.getScheduledState() == ScheduledState.STOPPED) 
{
-                    if (scheduler.getActiveThreadCount(connectable) > 0) {
-                        throw new IllegalStateException("Cannot start " + 
connectable + " because it is currently stopping");
-                    }
-
-                    connectable.verifyCanStart();
-                }
+                verifyCanStart(connectable);
             }
         } finally {
             readLock.unlock();

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/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 11724f4..eebcfa5 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
@@ -557,4 +557,11 @@ public class MockProcessGroup implements ProcessGroup {
         return null;
     }
 
+    @Override
+    public void verifyCanStart(Connectable connectable) {
+    }
+
+    @Override
+    public void verifyCanStop(Connectable connectable) {
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
index 04dca11..a4277c6 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
@@ -16,9 +16,6 @@
  */
 package org.apache.nifi.audit;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
 import org.apache.nifi.action.Action;
 import org.apache.nifi.action.Component;
 import org.apache.nifi.action.FlowChangeAction;
@@ -26,9 +23,10 @@ import org.apache.nifi.action.Operation;
 import org.apache.nifi.action.details.ActionDetails;
 import org.apache.nifi.action.details.FlowChangeConfigureDetails;
 import org.apache.nifi.action.details.FlowChangeMoveDetails;
+import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
+import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.groups.ProcessGroup;
-import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.dao.ProcessGroupDAO;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -37,6 +35,10 @@ import org.aspectj.lang.annotation.Aspect;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
 /**
  * Audits process group creation/removal and configuration changes.
  */
@@ -153,28 +155,6 @@ public class ProcessGroupAuditor extends NiFiAuditor {
                 }
             }
 
-            // if the user was starting/stopping this process group
-            if (processGroupDTO.isRunning() != null) {
-                // create a process group action
-                FlowChangeAction processGroupAction = new FlowChangeAction();
-                processGroupAction.setUserIdentity(user.getIdentity());
-                processGroupAction.setUserName(user.getUserName());
-                processGroupAction.setSourceId(processGroup.getIdentifier());
-                processGroupAction.setSourceName(processGroup.getName());
-                processGroupAction.setSourceType(Component.ProcessGroup);
-                processGroupAction.setTimestamp(new Date());
-
-                // determine the running state
-                if (processGroupDTO.isRunning()) {
-                    processGroupAction.setOperation(Operation.Start);
-                } else {
-                    processGroupAction.setOperation(Operation.Stop);
-                }
-
-                // add this action
-                actions.add(processGroupAction);
-            }
-
             // save actions if necessary
             if (!actions.isEmpty()) {
                 saveActions(actions, logger);
@@ -185,6 +165,47 @@ public class ProcessGroupAuditor extends NiFiAuditor {
     }
 
     /**
+     * Audits the update of process group configuration.
+     *
+     * @param proceedingJoinPoint join point
+     * @param groupId group id
+     * @param state scheduled state
+     * @throws Throwable ex
+     */
+    @Around("within(org.apache.nifi.web.dao.ProcessGroupDAO+) && "
+        + "execution(void scheduleComponents(java.lang.String, 
org.apache.nifi.controller.ScheduledState, java.util.Set)) && "
+        + "args(groupId, state)")
+    public void scheduleComponentsAdvice(ProceedingJoinPoint 
proceedingJoinPoint, String groupId, ScheduledState state) throws Throwable {
+        ProcessGroupDAO processGroupDAO = getProcessGroupDAO();
+        ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
+
+        // perform the action
+        proceedingJoinPoint.proceed();
+
+        // get the current user
+        NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+        // if the user was starting/stopping this process group
+        FlowChangeAction action = new FlowChangeAction();
+        action.setUserIdentity(user.getIdentity());
+        action.setUserName(user.getUserName());
+        action.setSourceId(processGroup.getIdentifier());
+        action.setSourceName(processGroup.getName());
+        action.setSourceType(Component.ProcessGroup);
+        action.setTimestamp(new Date());
+
+        // determine the running state
+        if (ScheduledState.RUNNING.equals(state)) {
+            action.setOperation(Operation.Start);
+        } else {
+            action.setOperation(Operation.Stop);
+        }
+
+        // add this action
+        saveAction(action, logger);
+    }
+
+    /**
      * Audits the removal of a process group via deleteProcessGroup().
      *
      * @param proceedingJoinPoint join point

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java
index bb96e88..27b76b1 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java
@@ -253,7 +253,7 @@ public class SnippetAuditor extends NiFiAuditor {
      * @throws Throwable ex
      */
     @Around("within(org.apache.nifi.web.dao.SnippetDAO+) && "
-            + "execution(org.apache.nifi.controller.Snippet 
updateSnippet(org.apache.nifi.web.api.dto.SnippetDTO)) && "
+            + "execution(org.apache.nifi.controller.Snippet 
updateSnippetComponents(org.apache.nifi.web.api.dto.SnippetDTO)) && "
             + "args(snippetDTO) && "
             + "target(snippetDAO)")
     public Snippet updateSnippetAdvice(ProceedingJoinPoint 
proceedingJoinPoint, SnippetDTO snippetDTO, SnippetDAO snippetDAO) throws 
Throwable {
@@ -266,7 +266,7 @@ public class SnippetAuditor extends NiFiAuditor {
 
         // if this snippet is linked and its parent group id has changed
         final String groupId = snippetDTO.getParentGroupId();
-        if (snippet.isLinked() && !previousGroupId.equals(groupId)) {
+        if (!previousGroupId.equals(groupId)) {
 
             // create move audit records for all items in this snippet
             final Collection<Action> actions = new ArrayList<>();
@@ -346,114 +346,109 @@ public class SnippetAuditor extends NiFiAuditor {
      * @throws Throwable ex
      */
     @Around("within(org.apache.nifi.web.dao.SnippetDAO+) && "
-            + "execution(void deleteSnippet(java.lang.String)) && "
+            + "execution(void deleteSnippetComponents(java.lang.String)) && "
             + "args(snippetId) && "
             + "target(snippetDAO)")
     public void removeSnippetAdvice(ProceedingJoinPoint proceedingJoinPoint, 
String snippetId, SnippetDAO snippetDAO) throws Throwable {
         // get the snippet before removing it
         final Snippet snippet = snippetDAO.getSnippet(snippetId);
 
-        if (snippet.isLinked()) {
-            // locate all the components being removed
-            final Set<Funnel> funnels = new HashSet<>();
-            for (String id : snippet.getFunnels().keySet()) {
-                funnels.add(funnelDAO.getFunnel(id));
-            }
+        // locate all the components being removed
+        final Set<Funnel> funnels = new HashSet<>();
+        for (String id : snippet.getFunnels().keySet()) {
+            funnels.add(funnelDAO.getFunnel(id));
+        }
 
-            final Set<Port> inputPorts = new HashSet<>();
-            for (String id : snippet.getInputPorts().keySet()) {
-                inputPorts.add(inputPortDAO.getPort(id));
-            }
+        final Set<Port> inputPorts = new HashSet<>();
+        for (String id : snippet.getInputPorts().keySet()) {
+            inputPorts.add(inputPortDAO.getPort(id));
+        }
 
-            final Set<Port> outputPorts = new HashSet<>();
-            for (String id : snippet.getOutputPorts().keySet()) {
-                outputPorts.add(outputPortDAO.getPort(id));
-            }
+        final Set<Port> outputPorts = new HashSet<>();
+        for (String id : snippet.getOutputPorts().keySet()) {
+            outputPorts.add(outputPortDAO.getPort(id));
+        }
 
-            final Set<RemoteProcessGroup> remoteProcessGroups = new 
HashSet<>();
-            for (String id : snippet.getRemoteProcessGroups().keySet()) {
-                
remoteProcessGroups.add(remoteProcessGroupDAO.getRemoteProcessGroup(id));
-            }
+        final Set<RemoteProcessGroup> remoteProcessGroups = new HashSet<>();
+        for (String id : snippet.getRemoteProcessGroups().keySet()) {
+            
remoteProcessGroups.add(remoteProcessGroupDAO.getRemoteProcessGroup(id));
+        }
 
-            final Set<ProcessGroup> processGroups = new HashSet<>();
-            final ProcessGroupDAO processGroupDAO = getProcessGroupDAO();
-            for (String id : snippet.getProcessGroups().keySet()) {
-                processGroups.add(processGroupDAO.getProcessGroup(id));
-            }
+        final Set<ProcessGroup> processGroups = new HashSet<>();
+        final ProcessGroupDAO processGroupDAO = getProcessGroupDAO();
+        for (String id : snippet.getProcessGroups().keySet()) {
+            processGroups.add(processGroupDAO.getProcessGroup(id));
+        }
 
-            final Set<ProcessorNode> processors = new HashSet<>();
-            for (String id : snippet.getProcessors().keySet()) {
-                processors.add(processorDAO.getProcessor(id));
-            }
+        final Set<ProcessorNode> processors = new HashSet<>();
+        for (String id : snippet.getProcessors().keySet()) {
+            processors.add(processorDAO.getProcessor(id));
+        }
 
-            final Set<Connection> connections = new HashSet<>();
-            for (String id : snippet.getConnections().keySet()) {
-                connections.add(connectionDAO.getConnection(id));
-            }
+        final Set<Connection> connections = new HashSet<>();
+        for (String id : snippet.getConnections().keySet()) {
+            connections.add(connectionDAO.getConnection(id));
+        }
 
-            // remove the snippet and components
-            proceedingJoinPoint.proceed();
+        // remove the snippet and components
+        proceedingJoinPoint.proceed();
 
-            final Collection<Action> actions = new ArrayList<>();
+        final Collection<Action> actions = new ArrayList<>();
 
-            // audit funnel removal
-            for (Funnel funnel : funnels) {
-                final Action action = 
funnelAuditor.generateAuditRecord(funnel, Operation.Remove);
-                if (action != null) {
-                    actions.add(action);
-                }
+        // audit funnel removal
+        for (Funnel funnel : funnels) {
+            final Action action = funnelAuditor.generateAuditRecord(funnel, 
Operation.Remove);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            for (Port inputPort : inputPorts) {
-                final Action action = 
portAuditor.generateAuditRecord(inputPort, Operation.Remove);
-                if (action != null) {
-                    actions.add(action);
-                }
+        for (Port inputPort : inputPorts) {
+            final Action action = portAuditor.generateAuditRecord(inputPort, 
Operation.Remove);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            for (Port outputPort : outputPorts) {
-                final Action action = 
portAuditor.generateAuditRecord(outputPort, Operation.Remove);
-                if (action != null) {
-                    actions.add(action);
-                }
+        for (Port outputPort : outputPorts) {
+            final Action action = portAuditor.generateAuditRecord(outputPort, 
Operation.Remove);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            for (RemoteProcessGroup remoteProcessGroup : remoteProcessGroups) {
-                final Action action = 
remoteProcessGroupAuditor.generateAuditRecord(remoteProcessGroup, 
Operation.Remove);
-                if (action != null) {
-                    actions.add(action);
-                }
+        for (RemoteProcessGroup remoteProcessGroup : remoteProcessGroups) {
+            final Action action = 
remoteProcessGroupAuditor.generateAuditRecord(remoteProcessGroup, 
Operation.Remove);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            for (ProcessGroup processGroup : processGroups) {
-                final Action action = 
processGroupAuditor.generateAuditRecord(processGroup, Operation.Remove);
-                if (action != null) {
-                    actions.add(action);
-                }
+        for (ProcessGroup processGroup : processGroups) {
+            final Action action = 
processGroupAuditor.generateAuditRecord(processGroup, Operation.Remove);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            for (ProcessorNode processor : processors) {
-                final Action action = 
processorAuditor.generateAuditRecord(processor, Operation.Remove);
-                if (action != null) {
-                    actions.add(action);
-                }
+        for (ProcessorNode processor : processors) {
+            final Action action = 
processorAuditor.generateAuditRecord(processor, Operation.Remove);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            for (Connection connection : connections) {
-                final ConnectDetails connectDetails = 
relationshipAuditor.createConnectDetails(connection, 
connection.getRelationships());
-                final Action action = 
relationshipAuditor.generateAuditRecordForConnection(connection, 
Operation.Disconnect, connectDetails);
-                if (action != null) {
-                    actions.add(action);
-                }
+        for (Connection connection : connections) {
+            final ConnectDetails connectDetails = 
relationshipAuditor.createConnectDetails(connection, 
connection.getRelationships());
+            final Action action = 
relationshipAuditor.generateAuditRecordForConnection(connection, 
Operation.Disconnect, connectDetails);
+            if (action != null) {
+                actions.add(action);
             }
+        }
 
-            // save the actions
-            if (CollectionUtils.isNotEmpty(actions)) {
-                saveActions(actions, logger);
-            }
-        } else {
-            // remove the snippet but not the components since this snippet 
isn't linked
-            proceedingJoinPoint.proceed();
+        // save the actions
+        if (CollectionUtils.isNotEmpty(actions)) {
+            saveActions(actions, logger);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java
new file mode 100644
index 0000000..d6db1f0
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java
@@ -0,0 +1,154 @@
+/*
+ * 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;
+
+import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.controller.Snippet;
+
+public interface AuthorizableLookup {
+
+    /**
+     * Get the authorizable Processor.
+     *
+     * @param id processor id
+     * @return authorizable
+     */
+    Authorizable getProcessor(String id);
+
+    /**
+     * Get the authorizable InputPort.
+     *
+     * @param id input port id
+     * @return authorizable
+     */
+    Authorizable getInputPort(String id);
+
+    /**
+     * Get the authorizable OutputPort.
+     *
+     * @param id output port id
+     * @return authorizable
+     */
+    Authorizable getOutputPort(String id);
+
+    /**
+     * Get the authorizable Connection.
+     *
+     * @param id connection id
+     * @return authorizable
+     */
+    Authorizable getConnection(String id);
+
+    /**
+     * Get the authorizable ProcessGroup.
+     *
+     * @param id process group id
+     * @return authorizable
+     */
+    Authorizable getProcessGroup(String id);
+
+    /**
+     * Get the authorizable RemoteProcessGroup.
+     *
+     * @param id remote process group id
+     * @return authorizable
+     */
+    Authorizable getRemoteProcessGroup(String id);
+
+    /**
+     * Get the authorizable RemoteProcessGroup input port.
+     *
+     * @param remoteProcessGroupId remote process group id
+     * @param id input port id
+     * @return authorizable
+     */
+    Authorizable getRemoteProcessGroupInputPort(String remoteProcessGroupId, 
String id);
+
+    /**
+     * Get the authorizable RemoteProcessGroup output port.
+     *
+     * @param remoteProcessGroupId remote process group id
+     * @param id output port id
+     * @return authorizable
+     */
+    Authorizable getRemoteProcessGroupOutputPort(String remoteProcessGroupId, 
String id);
+
+    /**
+     * Get the authorizable Label.
+     *
+     * @param id label id
+     * @return authorizable
+     */
+    Authorizable getLabel(String id);
+
+    /**
+     * Get the authorizable Funnel.
+     *
+     * @param id funnel id
+     * @return authorizable
+     */
+    Authorizable getFunnel(String id);
+
+    /**
+     * Get the authorizable ControllerService.
+     *
+     * @param id controller service id
+     * @return authorizable
+     */
+    Authorizable getControllerService(String id);
+
+    /**
+     * Get the authorizable referencing component.
+     *
+     * @param controllerSeriveId controller service id
+     * @param id component id
+     * @return authorizable
+     */
+    Authorizable getControllerServiceReferencingComponent(String 
controllerSeriveId, String id);
+
+    /**
+     * Get the authorizable ReportingTask.
+     *
+     * @param id reporting task id
+     * @return authorizable
+     */
+    Authorizable getReportingTask(String id);
+
+    /**
+     * Get the authorizable Template.
+     *
+     * @param id template id
+     * @return authorizable
+     */
+    Authorizable getTemplate(String id);
+
+    /**
+     * Get the authorizable connectable.
+     *
+     * @param id connectable id
+     * @return authorizable
+     */
+    Authorizable getConnectable(String id);
+
+    /**
+     * Get the snippet of authorizable's.
+     *
+     * @param id snippet id
+     * @return snippet of authorizable's
+     */
+    Snippet getSnippet(String id);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java
new file mode 100644
index 0000000..29fd523
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+public interface AuthorizeAccess {
+    void authorize(AuthorizableLookup lookup);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/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 41b9867..f372812 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,9 +16,11 @@
  */
 package org.apache.nifi.web;
 
+import org.apache.nifi.authorization.user.NiFiUser;
 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.web.api.dto.BulletinBoardDTO;
 import org.apache.nifi.web.api.dto.BulletinQueryDTO;
 import org.apache.nifi.web.api.dto.ClusterDTO;
@@ -51,7 +53,6 @@ import org.apache.nifi.web.api.dto.TemplateDTO;
 import org.apache.nifi.web.api.dto.action.ActionDTO;
 import org.apache.nifi.web.api.dto.action.HistoryDTO;
 import org.apache.nifi.web.api.dto.action.HistoryQueryDTO;
-import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO;
 import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO;
@@ -72,10 +73,12 @@ import org.apache.nifi.web.api.entity.FunnelEntity;
 import org.apache.nifi.web.api.entity.LabelEntity;
 import org.apache.nifi.web.api.entity.PortEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
 import org.apache.nifi.web.api.entity.ProcessorEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
+import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
 import org.apache.nifi.web.api.entity.SnippetEntity;
 
 import java.util.Date;
@@ -83,6 +86,7 @@ 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.
@@ -92,7 +96,64 @@ public interface NiFiServiceFacade {
     // ----------------------------------------
     // Synchronization methods
     // ----------------------------------------
-    void claimRevision(Revision revision) throws InvalidRevisionException;
+
+    /**
+     * Authorizes access to the service facade.
+     *
+     * @param authorizeAccess authorize access callback
+     */
+    void authorizeAccess(AuthorizeAccess authorizeAccess);
+
+    /**
+     * Claims the specified revision for the specified user.
+     *
+     * @param revision revision
+     * @param user user
+     * @throws InvalidRevisionException invalid revision
+     */
+    void claimRevision(Revision revision, NiFiUser user) throws 
InvalidRevisionException;
+
+    /**
+     * Claims the specified revisions for the specified user.
+     *
+     * @param revisions revisions
+     * @param user user
+     * @throws InvalidRevisionException invalid revision
+     */
+    void claimRevisions(Set<Revision> revisions, NiFiUser user) throws 
InvalidRevisionException;
+
+    /**
+     * Cancels the specified revision. Cancellation is only supported based on 
the current thread.
+     *
+     * @param revision revision
+     * @throws InvalidRevisionException invalid revision
+     */
+    void cancelRevision(Revision revision) throws InvalidRevisionException;
+
+    /**
+     * Cancels the specified revisions. Cancellation is only supported based 
on the current thread.
+     *
+     * @param revisions revision
+     * @throws InvalidRevisionException invalid revision
+     */
+    void cancelRevisions(Set<Revision> revisions) throws 
InvalidRevisionException;
+
+    /**
+     * Gets the current revisions for the components based on the specified 
function.
+     *
+     * @param groupId group
+     * @param getComponents callback
+     * @return component revisions
+     */
+    Set<Revision> getRevisionsFromGroup(String groupId, Function<ProcessGroup, 
Set<String>> getComponents);
+
+    /**
+     * Gets the revisions from the specified snippet.
+     *
+     * @param snippetId snippet
+     * @return component revisions from the snippet
+     */
+    Set<Revision> getRevisionsFromSnippet(String snippetId);
 
     // ----------------------------------------
     // Controller methods
@@ -754,7 +815,7 @@ public interface NiFiServiceFacade {
      * @param recurse recurse
      * @return the flow
      */
-    ConfigurationSnapshot<ProcessGroupFlowDTO> getProcessGroupFlow(String 
groupId, boolean recurse);
+    ProcessGroupFlowEntity getProcessGroupFlow(String groupId, boolean 
recurse);
 
     // ----------------------------------------
     // ProcessGroup methods
@@ -785,11 +846,23 @@ public interface NiFiServiceFacade {
     Set<ProcessGroupEntity> getProcessGroups(String parentGroupId);
 
     /**
-     * Verifies the specified process group can be updated.
+     * Verifies the contents of the specified process group can be scheduled 
or unscheduled.
      *
-     * @param processGroupDTO The ProcessGroupDTO
+     * @param processGroupId The ProcessGroup id
+     * @param componentIds the components
+     * @param state scheduled state
+     */
+    void verifyScheduleComponents(String processGroupId, ScheduledState state, 
Set<String> componentIds);
+
+    /**
+     * Schedules all applicable components under the specified ProcessGroup.
+     *
+     * @param processGroupId The ProcessGroup id
+     * @param state schedule state
+     * @param componentRevisions components and their revision
+     * @return snapshot
      */
-    void verifyUpdateProcessGroup(ProcessGroupDTO processGroupDTO);
+    ScheduleComponentsEntity scheduleComponents(String processGroupId, 
ScheduledState state, Map<String, Revision> componentRevisions);
 
     /**
      * Updates the specified process group.
@@ -1320,44 +1393,37 @@ public interface NiFiServiceFacade {
     SnippetEntity createSnippet(SnippetDTO snippet);
 
     /**
-     * Gets the specified snippet.
-     *
-     * @param snippetId id
-     * @return snippet
-     */
-    SnippetEntity getSnippet(String snippetId);
-
-    /**
      * Determines if this snippet can be updated.
      *
      * @param snippetDto snippet
      */
-    void verifyUpdateSnippet(SnippetDTO snippetDto);
+    void verifyUpdateSnippet(SnippetDTO snippetDto, Set<String> 
affectedComponentIds);
 
     /**
      * If group id is specified, moves the specified snippet to the specified 
group.
      *
-     * @param revision revision
+     * @param revisions revisions
      * @param snippetDto snippet
      * @return snapshot
      */
-    UpdateResult<SnippetEntity> updateSnippet(Revision revision, SnippetDTO 
snippetDto);
+    SnippetEntity updateSnippet(Set<Revision> revisions, SnippetDTO 
snippetDto);
 
     /**
      * Determines if this snippet can be removed.
      *
      * @param id id
+     * @param affectedComponentIds affected components
      */
-    void verifyDeleteSnippet(String id);
+    void verifyDeleteSnippet(String id, Set<String> affectedComponentIds);
 
     /**
      * Removes the specified snippet.
      *
-     * @param revision revision
+     * @param revisions revisions
      * @param snippetId snippet
      * @return snapshot
      */
-    SnippetEntity deleteSnippet(Revision revision, String snippetId);
+    SnippetEntity deleteSnippet(Set<Revision> revisions, String snippetId);
 
     // ----------------------------------------
     // Cluster methods

Reply via email to