You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2017/09/14 15:13:07 UTC

[4/4] nifi git commit: NIFI-4280: - Adding support for the user to configure variables in the UI. - Updating the endpoints for changing variables as necessary. This closes #2135.

NIFI-4280:
- Adding support for the user to configure variables in the UI.
- Updating the endpoints for changing variables as necessary.
This closes #2135.


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

Branch: refs/heads/master
Commit: eac47e90cbfa39a8e40512379b02ff745262b5af
Parents: 9138326
Author: Matt Gilman <ma...@gmail.com>
Authored: Thu Aug 17 16:51:23 2017 -0400
Committer: Mark Payne <ma...@hotmail.com>
Committed: Thu Sep 14 11:12:54 2017 -0400

----------------------------------------------------------------------
 .../nifi/web/api/dto/AffectedComponentDTO.java  |   92 +-
 ...ontrollerServiceReferencingComponentDTO.java |    8 +-
 .../apache/nifi/web/api/dto/VariableDTO.java    |   13 +-
 .../nifi/web/api/dto/VariableRegistryDTO.java   |   16 +-
 .../dto/VariableRegistryUpdateRequestDTO.java   |   27 +-
 .../web/api/entity/AffectedComponentEntity.java |   44 +
 .../web/api/entity/VariableRegistryEntity.java  |   13 +-
 .../VariableRegistryUpdateRequestEntity.java    |   15 +-
 .../http/StandardHttpResponseMapper.java        |   21 +-
 .../VariableRegistryEndpointMerger.java         |  113 ++
 .../manager/AffectedComponentEntityMerger.java  |  102 ++
 .../nifi/groups/StandardProcessGroup.java       |   58 +-
 .../variable/VariableRegistryUpdateRequest.java |   32 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |   31 +-
 .../nifi/web/StandardNiFiServiceFacade.java     |   38 +-
 .../nifi/web/api/ProcessGroupResource.java      |  690 +++++---
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  148 +-
 .../apache/nifi/web/api/dto/EntityFactory.java  |   15 +
 .../org/apache/nifi/web/dao/ProcessorDAO.java   |    3 +-
 .../nifi/web/dao/impl/StandardProcessorDAO.java |    9 +-
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |    1 +
 .../main/resources/filters/canvas.properties    |    1 +
 .../src/main/webapp/WEB-INF/pages/canvas.jsp    |    1 +
 .../partials/canvas/variable-configuration.jsp  |   93 +
 .../src/main/webapp/css/controller-service.css  |    4 +
 .../nifi-web-ui/src/main/webapp/css/dialog.css  |   51 +
 .../propertytable/jquery.propertytable.js       |   16 +-
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |   25 +-
 .../webapp/js/nf/canvas/nf-canvas-bootstrap.js  |   10 +-
 .../main/webapp/js/nf/canvas/nf-canvas-utils.js |   21 +
 .../main/webapp/js/nf/canvas/nf-context-menu.js |   10 +
 .../js/nf/canvas/nf-controller-service.js       |   33 +-
 .../webapp/js/nf/canvas/nf-variable-registry.js | 1633 ++++++++++++++++++
 33 files changed, 2897 insertions(+), 490 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AffectedComponentDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AffectedComponentDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AffectedComponentDTO.java
index 5d631ed..28999a5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AffectedComponentDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/AffectedComponentDTO.java
@@ -17,43 +17,101 @@
 
 package org.apache.nifi.web.api.dto;
 
-import javax.xml.bind.annotation.XmlType;
-
 import com.wordnik.swagger.annotations.ApiModelProperty;
 
+import javax.xml.bind.annotation.XmlType;
+import java.util.Collection;
+
 @XmlType(name = "affectedComponent")
 public class AffectedComponentDTO {
     public static final String COMPONENT_TYPE_PROCESSOR = "PROCESSOR";
     public static final String COMPONENT_TYPE_CONTROLLER_SERVICE = "CONTROLLER_SERVICE";
 
-    private String parentGroupId;
-    private String componentId;
-    private String componentType;
+    private String processGroupId;
+    private String id;
+    private String referenceType;
+    private String name;
+    private String state;
+    private Integer activeThreadCount;
+
+    private Collection<String> validationErrors;
 
     @ApiModelProperty("The UUID of the Process Group that this component is in")
-    public String getParentGroupId() {
-        return parentGroupId;
+    public String getProcessGroupId() {
+        return processGroupId;
     }
 
-    public void setParentGroupId(final String parentGroupId) {
-        this.parentGroupId = parentGroupId;
+    public void setProcessGroupId(final String processGroupId) {
+        this.processGroupId = processGroupId;
     }
 
     @ApiModelProperty("The UUID of this component")
-    public String getComponentId() {
-        return componentId;
+    public String getId() {
+        return id;
     }
 
-    public void setComponentId(final String componentId) {
-        this.componentId = componentId;
+    public void setId(final String id) {
+        this.id = id;
     }
 
     @ApiModelProperty(value = "The type of this component", allowableValues = COMPONENT_TYPE_PROCESSOR + "," + COMPONENT_TYPE_CONTROLLER_SERVICE)
-    public String getComponentType() {
-        return componentType;
+    public String getReferenceType() {
+        return referenceType;
+    }
+
+    public void setReferenceType(final String referenceType) {
+        this.referenceType = referenceType;
+    }
+
+    @ApiModelProperty("The name of this component.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return scheduled state of the processor referencing a controller service. If this component is another service, this field represents the controller service state
+     */
+    @ApiModelProperty(
+            value = "The scheduled state of a processor or reporting task referencing a controller service. If this component is another controller "
+                    + "service, this field represents the controller service state."
+    )
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    /**
+     * @return active thread count for the referencing component
+     */
+    @ApiModelProperty(
+            value = "The number of active threads for the referencing component."
+    )
+    public Integer getActiveThreadCount() {
+        return activeThreadCount;
+    }
+
+    public void setActiveThreadCount(Integer activeThreadCount) {
+        this.activeThreadCount = activeThreadCount;
+    }
+
+    /**
+     * @return Any validation error associated with this component
+     */
+    @ApiModelProperty(
+            value = "The validation errors for the component."
+    )
+    public Collection<String> getValidationErrors() {
+        return validationErrors;
     }
 
-    public void setComponentType(final String componentType) {
-        this.componentType = componentType;
+    public void setValidationErrors(Collection<String> validationErrors) {
+        this.validationErrors = validationErrors;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java
index 380e6ce..6279ac3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java
@@ -19,10 +19,10 @@ package org.apache.nifi.web.api.dto;
 import com.wordnik.swagger.annotations.ApiModelProperty;
 import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
 
+import javax.xml.bind.annotation.XmlType;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
-import javax.xml.bind.annotation.XmlType;
 
 /**
  * A component referencing a controller service. This can either be another controller service or a processor. Depending on the type of component different properties may be set.
@@ -105,11 +105,11 @@ public class ControllerServiceReferencingComponentDTO {
     }
 
     /**
-     * @return state of the processor referencing a controller service. If this component is another service, this field is blank
+     * @return scheduled state of the processor referencing a controller service. If this component is another service, this field represents the controller service state
      */
     @ApiModelProperty(
-            value = "The state of a processor or reporting task referencing a controller service. If this component is another controller "
-                    + "service, this field is blank."
+            value = "The scheduled state of a processor or reporting task referencing a controller service. If this component is another controller "
+                    + "service, this field represents the controller service state."
     )
     public String getState() {
         return state;

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableDTO.java
index c686316..89ea27a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableDTO.java
@@ -17,19 +17,18 @@
 
 package org.apache.nifi.web.api.dto;
 
-import java.util.HashSet;
-import java.util.Set;
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
 
 import javax.xml.bind.annotation.XmlType;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import java.util.Set;
 
 @XmlType(name = "variable")
 public class VariableDTO {
     private String name;
     private String value;
     private String processGroupId;
-    private Set<AffectedComponentDTO> affectedComponents = new HashSet<>();
+    private Set<AffectedComponentEntity> affectedComponents;
 
     @ApiModelProperty("The name of the variable")
     public String getName() {
@@ -59,11 +58,11 @@ public class VariableDTO {
     }
 
     @ApiModelProperty(value = "A set of all components that will be affected if the value of this variable is changed", readOnly = true)
-    public Set<AffectedComponentDTO> getAffectedComponents() {
+    public Set<AffectedComponentEntity> getAffectedComponents() {
         return affectedComponents;
     }
 
-    public void setAffectedComponents(Set<AffectedComponentDTO> affectedComponents) {
+    public void setAffectedComponents(Set<AffectedComponentEntity> affectedComponents) {
         this.affectedComponents = affectedComponents;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryDTO.java
index c106a9a..8f37532 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryDTO.java
@@ -17,18 +17,16 @@
 
 package org.apache.nifi.web.api.dto;
 
-import java.util.Set;
-
-import javax.xml.bind.annotation.XmlType;
-
+import com.wordnik.swagger.annotations.ApiModelProperty;
 import org.apache.nifi.web.api.entity.VariableEntity;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import javax.xml.bind.annotation.XmlType;
+import java.util.Set;
 
 @XmlType(name = "variableRegistry")
 public class VariableRegistryDTO {
     private Set<VariableEntity> variables;
-    private String groupId;
+    private String processGroupId;
 
     public void setVariables(final Set<VariableEntity> variables) {
         this.variables = variables;
@@ -39,12 +37,12 @@ public class VariableRegistryDTO {
         return variables;
     }
 
-    public void setProcessGroupId(final String groupId) {
-        this.groupId = groupId;
+    public void setProcessGroupId(final String processGroupId) {
+        this.processGroupId = processGroupId;
     }
 
     @ApiModelProperty("The UUID of the Process Group that this Variable Registry belongs to")
     public String getProcessGroupId() {
-        return groupId;
+        return processGroupId;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryUpdateRequestDTO.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryUpdateRequestDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryUpdateRequestDTO.java
index 06a0dc2..e57e30a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryUpdateRequestDTO.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VariableRegistryUpdateRequestDTO.java
@@ -17,27 +17,27 @@
 
 package org.apache.nifi.web.api.dto;
 
-import java.util.Date;
-import java.util.List;
+import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.util.TimestampAdapter;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
 
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-import org.apache.nifi.web.api.dto.util.TimestampAdapter;
-
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
 
 @XmlType(name = "variableRegistryUpdateRequest")
 public class VariableRegistryUpdateRequestDTO {
     private String requestId;
     private String processGroupId;
     private String uri;
-    private Date submissionTime = new Date();
-    private Date lastUpdated = new Date();
+    private Date submissionTime;
+    private Date lastUpdated;
     private boolean complete = false;
     private String failureReason;
     private List<VariableRegistryUpdateStepDTO> updateSteps;
-
+    private Set<AffectedComponentEntity> affectedComponents;
 
     @ApiModelProperty("The unique ID of the Process Group that the variable registry belongs to")
     public String getProcessGroupId() {
@@ -112,4 +112,13 @@ public class VariableRegistryUpdateRequestDTO {
     public void setFailureReason(String reason) {
         this.failureReason = reason;
     }
+
+    @ApiModelProperty(value = "A set of all components that will be affected if the value of this variable is changed", readOnly = true)
+    public Set<AffectedComponentEntity> getAffectedComponents() {
+        return affectedComponents;
+    }
+
+    public void setAffectedComponents(Set<AffectedComponentEntity> affectedComponents) {
+        this.affectedComponents = affectedComponents;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AffectedComponentEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AffectedComponentEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AffectedComponentEntity.java
new file mode 100644
index 0000000..0f28f73
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/AffectedComponentEntity.java
@@ -0,0 +1,44 @@
+/*
+ * 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.AffectedComponentDTO;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * 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 component that references a variable.
+ */
+@XmlRootElement(name = "affectComponentEntity")
+public class AffectedComponentEntity extends ComponentEntity implements Permissible<AffectedComponentDTO> {
+
+    private AffectedComponentDTO component;
+
+    /**
+     * @return variable referencing components that is being serialized
+     */
+    public AffectedComponentDTO getComponent() {
+        return component;
+    }
+
+    public void setComponent(AffectedComponentDTO component) {
+        this.component = component;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryEntity.java
index d876453..1b7da0c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryEntity.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryEntity.java
@@ -17,16 +17,15 @@
 
 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.RevisionDTO;
 import org.apache.nifi.web.api.dto.VariableRegistryDTO;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement(name = "variableRegistryEntity")
 public class VariableRegistryEntity extends Entity {
-    private RevisionDTO groupRevision;
+    private RevisionDTO processGroupRevision;
     private VariableRegistryDTO variableRegistry;
 
 
@@ -41,10 +40,10 @@ public class VariableRegistryEntity extends Entity {
 
     @ApiModelProperty("The revision of the Process Group that the Variable Registry belongs to")
     public RevisionDTO getProcessGroupRevision() {
-        return groupRevision;
+        return processGroupRevision;
     }
 
-    public void setProcessGroupRevision(RevisionDTO revision) {
-        this.groupRevision = revision;
+    public void setProcessGroupRevision(RevisionDTO processGroupRevision) {
+        this.processGroupRevision = processGroupRevision;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryUpdateRequestEntity.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryUpdateRequestEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryUpdateRequestEntity.java
index 77257af..bfeb9ce 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryUpdateRequestEntity.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VariableRegistryUpdateRequestEntity.java
@@ -17,16 +17,15 @@
 
 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.RevisionDTO;
 import org.apache.nifi.web.api.dto.VariableRegistryUpdateRequestDTO;
 
-import com.wordnik.swagger.annotations.ApiModelProperty;
+import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement(name = "variableRegistryUpdateRequestEntity")
 public class VariableRegistryUpdateRequestEntity extends Entity {
-    private VariableRegistryUpdateRequestDTO requestDto;
+    private VariableRegistryUpdateRequestDTO request;
     private RevisionDTO processGroupRevision;
 
     @ApiModelProperty("The revision for the Process Group that owns this variable registry.")
@@ -39,11 +38,11 @@ public class VariableRegistryUpdateRequestEntity extends Entity {
     }
 
     @ApiModelProperty("The Variable Registry Update Request")
-    public VariableRegistryUpdateRequestDTO getRequestDto() {
-        return requestDto;
+    public VariableRegistryUpdateRequestDTO getRequest() {
+        return request;
     }
 
-    public void setRequestDto(VariableRegistryUpdateRequestDTO requestDto) {
-        this.requestDto = requestDto;
+    public void setRequest(VariableRegistryUpdateRequestDTO request) {
+        this.request = request;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMapper.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMapper.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMapper.java
index c102746..fa23603 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMapper.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMapper.java
@@ -16,16 +16,6 @@
  */
 package org.apache.nifi.cluster.coordination.http;
 
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import javax.ws.rs.core.StreamingOutput;
-
 import org.apache.nifi.cluster.coordination.http.endpoints.AccessPolicyEndpointMerger;
 import org.apache.nifi.cluster.coordination.http.endpoints.BulletinBoardEndpointMerger;
 import org.apache.nifi.cluster.coordination.http.endpoints.ComponentStateEndpointMerger;
@@ -79,6 +69,7 @@ import org.apache.nifi.cluster.coordination.http.endpoints.UserEndpointMerger;
 import org.apache.nifi.cluster.coordination.http.endpoints.UserGroupEndpointMerger;
 import org.apache.nifi.cluster.coordination.http.endpoints.UserGroupsEndpointMerger;
 import org.apache.nifi.cluster.coordination.http.endpoints.UsersEndpointMerger;
+import org.apache.nifi.cluster.coordination.http.endpoints.VariableRegistryEndpointMerger;
 import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
 import org.apache.nifi.cluster.manager.NodeResponse;
 import org.apache.nifi.stream.io.NullOutputStream;
@@ -87,6 +78,15 @@ import org.apache.nifi.util.NiFiProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.ws.rs.core.StreamingOutput;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
 public class StandardHttpResponseMapper implements HttpResponseMapper {
 
     private Logger logger = LoggerFactory.getLogger(StandardHttpResponseMapper.class);
@@ -154,6 +154,7 @@ public class StandardHttpResponseMapper implements HttpResponseMapper {
         endpointMergers.add(new UserGroupEndpointMerger());
         endpointMergers.add(new AccessPolicyEndpointMerger());
         endpointMergers.add(new SearchUsersEndpointMerger());
+        endpointMergers.add(new VariableRegistryEndpointMerger());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/VariableRegistryEndpointMerger.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/VariableRegistryEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/VariableRegistryEndpointMerger.java
new file mode 100644
index 0000000..0420911
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/VariableRegistryEndpointMerger.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.cluster.coordination.http.endpoints;
+
+import org.apache.nifi.cluster.coordination.http.EndpointResponseMerger;
+import org.apache.nifi.cluster.manager.AffectedComponentEntityMerger;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
+import org.apache.nifi.web.api.dto.VariableDTO;
+import org.apache.nifi.web.api.dto.VariableRegistryDTO;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
+import org.apache.nifi.web.api.entity.VariableEntity;
+import org.apache.nifi.web.api.entity.VariableRegistryEntity;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+public class VariableRegistryEndpointMerger extends AbstractSingleEntityEndpoint<VariableRegistryEntity> implements EndpointResponseMerger {
+    public static final Pattern VARIABLE_REGISTRY_UPDATE_REQUEST_URI_PATTERN = Pattern.compile("/nifi-api/process-groups/(?:(?:root)|(?:[a-f0-9\\-]{36}))/variable-registry");
+
+    private final AffectedComponentEntityMerger affectedComponentEntityMerger = new AffectedComponentEntityMerger();
+
+    @Override
+    public boolean canHandle(final URI uri, final String method) {
+        if (("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) && (VARIABLE_REGISTRY_UPDATE_REQUEST_URI_PATTERN.matcher(uri.getPath()).matches())) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    protected Class<VariableRegistryEntity> getEntityClass() {
+        return VariableRegistryEntity.class;
+    }
+
+    @Override
+    protected void mergeResponses(final VariableRegistryEntity clientEntity, final Map<NodeIdentifier, VariableRegistryEntity> entityMap,
+                                  final Set<NodeResponse> successfulResponses, final Set<NodeResponse> problematicResponses) {
+
+        final VariableRegistryDTO clientVariableRegistry = clientEntity.getVariableRegistry();
+        final Set<VariableEntity> clientVariableEntities = clientVariableRegistry.getVariables();
+
+        if (clientVariableEntities != null) {
+            for (final Iterator<VariableEntity> i = clientVariableEntities.iterator(); i.hasNext();) {
+                final VariableEntity clientVariableEntity = i.next();
+                final VariableDTO clientVariable = clientVariableEntity.getVariable();
+
+                final Map<NodeIdentifier, Set<AffectedComponentEntity>> nodeAffectedComponentEntities = new HashMap<>();
+
+                boolean retainClientVariable = true;
+                for (final Map.Entry<NodeIdentifier, VariableRegistryEntity> nodeEntry : entityMap.entrySet()) {
+                    final VariableRegistryEntity nodeVariableRegistry = nodeEntry.getValue();
+                    final Set<VariableEntity> nodeVariableEntities = nodeVariableRegistry.getVariableRegistry().getVariables();
+
+                    // if this node has no variables, then the current client variable should be removed
+                    if (nodeVariableEntities == null) {
+                        retainClientVariable = false;
+                        break;
+                    }
+
+                    boolean variableFound = false;
+                    for (final VariableEntity nodeVariableEntity : nodeVariableEntities) {
+                        final VariableDTO nodeVariable = nodeVariableEntity.getVariable();
+
+                        // identify the current clientVariable for each node
+                        if (clientVariable.getProcessGroupId().equals(nodeVariable.getProcessGroupId()) && clientVariable.getName().equals(nodeVariable.getName())) {
+                            variableFound = true;
+
+                            if (Boolean.FALSE.equals(nodeVariableEntity.getCanWrite())) {
+                                clientVariableEntity.setCanWrite(false);
+                            }
+
+                            nodeAffectedComponentEntities.put(nodeEntry.getKey(), nodeVariableEntity.getVariable().getAffectedComponents());
+                            break;
+                        }
+                    }
+
+                    if (!variableFound) {
+                        retainClientVariable = false;
+                        break;
+                    }
+                }
+
+                if (!retainClientVariable) {
+                    i.remove();
+                } else {
+                    final Set<AffectedComponentEntity> clientAffectedComponentEntities = clientVariableEntity.getVariable().getAffectedComponents();
+                    affectedComponentEntityMerger.mergeAffectedComponents(clientAffectedComponentEntities, nodeAffectedComponentEntities);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/AffectedComponentEntityMerger.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/AffectedComponentEntityMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/AffectedComponentEntityMerger.java
new file mode 100644
index 0000000..60a605d
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/AffectedComponentEntityMerger.java
@@ -0,0 +1,102 @@
+/*
+ * 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.cluster.manager;
+
+import org.apache.nifi.cluster.protocol.NodeIdentifier;
+import org.apache.nifi.controller.service.ControllerServiceState;
+import org.apache.nifi.web.api.dto.AffectedComponentDTO;
+import org.apache.nifi.web.api.dto.PermissionsDTO;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class AffectedComponentEntityMerger {
+
+    public void mergeAffectedComponents(final Set<AffectedComponentEntity> affectedComponents, final Map<NodeIdentifier, Set<AffectedComponentEntity>> affectedComponentMap) {
+
+        final Map<String, Integer> activeThreadCounts = new HashMap<>();
+        final Map<String, String> states = new HashMap<>();
+        final Map<String, PermissionsDTO> canReads = new HashMap<>();
+
+        for (final Map.Entry<NodeIdentifier, Set<AffectedComponentEntity>> nodeEntry : affectedComponentMap.entrySet()) {
+            final Set<AffectedComponentEntity> nodeAffectedComponents = nodeEntry.getValue();
+
+            // go through all the nodes referencing components
+            if (nodeAffectedComponents != null) {
+                for (final AffectedComponentEntity nodeAffectedComponentEntity : nodeAffectedComponents) {
+                    final AffectedComponentDTO nodeAffectedComponent = nodeAffectedComponentEntity.getComponent();
+
+                    if (nodeAffectedComponentEntity.getPermissions().getCanRead()) {
+                        // handle active thread counts
+                        if (nodeAffectedComponent.getActiveThreadCount() != null && nodeAffectedComponent.getActiveThreadCount() > 0) {
+                            final Integer current = activeThreadCounts.get(nodeAffectedComponent.getId());
+                            if (current == null) {
+                                activeThreadCounts.put(nodeAffectedComponent.getId(), nodeAffectedComponent.getActiveThreadCount());
+                            } else {
+                                activeThreadCounts.put(nodeAffectedComponent.getId(), nodeAffectedComponent.getActiveThreadCount() + current);
+                            }
+                        }
+
+                        // handle controller service state
+                        final String state = states.get(nodeAffectedComponent.getId());
+                        if (state == null) {
+                            if (ControllerServiceState.DISABLING.name().equals(nodeAffectedComponent.getState())) {
+                                states.put(nodeAffectedComponent.getId(), ControllerServiceState.DISABLING.name());
+                            } else if (ControllerServiceState.ENABLING.name().equals(nodeAffectedComponent.getState())) {
+                                states.put(nodeAffectedComponent.getId(), ControllerServiceState.ENABLING.name());
+                            }
+                        }
+                    }
+
+                    // handle read permissions
+                    final PermissionsDTO mergedPermissions = canReads.get(nodeAffectedComponentEntity.getId());
+                    final PermissionsDTO permissions = nodeAffectedComponentEntity.getPermissions();
+                    if (permissions != null) {
+                        if (mergedPermissions == null) {
+                            canReads.put(nodeAffectedComponentEntity.getId(), permissions);
+                        } else {
+                            PermissionsDtoMerger.mergePermissions(mergedPermissions, permissions);
+                        }
+                    }
+                }
+            }
+        }
+
+        // go through each affected components
+        if (affectedComponents != null) {
+            for (final AffectedComponentEntity affectedComponent : affectedComponents) {
+                final PermissionsDTO permissions = canReads.get(affectedComponent.getId());
+                if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) {
+                    final Integer activeThreadCount = activeThreadCounts.get(affectedComponent.getId());
+                    if (activeThreadCount != null) {
+                        affectedComponent.getComponent().setActiveThreadCount(activeThreadCount);
+                    }
+
+                    final String state = states.get(affectedComponent.getId());
+                    if (state != null) {
+                        affectedComponent.getComponent().setState(state);
+                    }
+                } else {
+                    affectedComponent.setPermissions(permissions);
+                    affectedComponent.setComponent(null);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/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 2b7b51d..1754cf7 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,23 +16,7 @@
  */
 package org.apache.nifi.groups;
 
-import static java.util.Objects.requireNonNull;
-
-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.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.Sets;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -76,6 +60,7 @@ import org.apache.nifi.logging.LogRepositoryFactory;
 import org.apache.nifi.nar.ExtensionManager;
 import org.apache.nifi.nar.NarCloseable;
 import org.apache.nifi.processor.StandardProcessContext;
+import org.apache.nifi.registry.ComponentVariableRegistry;
 import org.apache.nifi.registry.VariableDescriptor;
 import org.apache.nifi.registry.variable.MutableVariableRegistry;
 import org.apache.nifi.remote.RemoteGroupPort;
@@ -87,7 +72,22 @@ import org.apache.nifi.web.api.dto.TemplateDTO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Sets;
+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.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
 
 public final class StandardProcessGroup implements ProcessGroup {
 
@@ -2651,7 +2651,7 @@ public final class StandardProcessGroup implements ProcessGroup {
         final Set<ConfiguredComponent> affected = new HashSet<>();
 
         // Determine any Processors that references the variable
-        for (final ProcessorNode processor : findAllProcessors()) {
+        for (final ProcessorNode processor : getProcessors()) {
             for (final VariableImpact impact : getVariableImpact(processor)) {
                 if (impact.isImpacted(variableName)) {
                     affected.add(processor);
@@ -2662,7 +2662,7 @@ public final class StandardProcessGroup implements ProcessGroup {
         // Determine any Controller Service that references the variable. If Service A references a variable,
         // then that means that any other component that references that service is also affected, so recursively
         // find any references to that service and add it.
-        for (final ControllerServiceNode service : findAllControllerServices()) {
+        for (final ControllerServiceNode service : getControllerServices(false)) {
             for (final VariableImpact impact : getVariableImpact(service)) {
                 if (impact.isImpacted(variableName)) {
                     affected.add(service);
@@ -2673,6 +2673,18 @@ public final class StandardProcessGroup implements ProcessGroup {
             }
         }
 
+        // For any child Process Group that does not override the variable, also include its references.
+        // If a child group has a value for the same variable, though, then that means that the child group
+        // is overriding the variable and its components are actually referencing a different variable.
+        for (final ProcessGroup childGroup : getProcessGroups()) {
+            final ComponentVariableRegistry childRegistry = childGroup.getVariableRegistry();
+            final VariableDescriptor descriptor = childRegistry.getVariableKey(variableName);
+            final boolean overridden = childRegistry.getVariableMap().containsKey(descriptor);
+            if (!overridden) {
+                affected.addAll(childGroup.getComponentsAffectedByVariable(variableName));
+            }
+        }
+
         return affected;
     }
 
@@ -2695,7 +2707,11 @@ public final class StandardProcessGroup implements ProcessGroup {
     }
 
     private List<VariableImpact> getVariableImpact(final ConfiguredComponent component) {
-        return component.getProperties().values().stream()
+        return component.getProperties().keySet().stream()
+            .map(descriptor -> {
+                final String configuredVal = component.getProperty(descriptor);
+                return configuredVal == null ? descriptor.getDefaultValue() : configuredVal;
+            })
             .map(propVal -> Query.prepare(propVal).getVariableImpact())
             .collect(Collectors.toList());
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/registry/variable/VariableRegistryUpdateRequest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/registry/variable/VariableRegistryUpdateRequest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/registry/variable/VariableRegistryUpdateRequest.java
index 82d4683..72f9a7a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/registry/variable/VariableRegistryUpdateRequest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/registry/variable/VariableRegistryUpdateRequest.java
@@ -17,17 +17,28 @@
 
 package org.apache.nifi.registry.variable;
 
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
+
 import java.util.Date;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 public class VariableRegistryUpdateRequest {
     private final String requestId;
     private final String processGroupId;
+    private final NiFiUser user;
     private volatile Date submissionTime = new Date();
     private volatile Date lastUpdated = new Date();
     private volatile boolean complete = false;
 
     private final AtomicReference<String> failureReason = new AtomicReference<>();
+    private RevisionDTO processGroupRevision;
+    private Map<String, AffectedComponentEntity> affectedComponents;
 
     private final VariableRegistryUpdateStep identifyComponentsStep = new VariableRegistryUpdateStep("Identifying components affected");
     private final VariableRegistryUpdateStep stopProcessors = new VariableRegistryUpdateStep("Stopping affected Processors");
@@ -36,16 +47,17 @@ public class VariableRegistryUpdateRequest {
     private final VariableRegistryUpdateStep enableServices = new VariableRegistryUpdateStep("Re-Enabling affected Controller Services");
     private final VariableRegistryUpdateStep startProcessors = new VariableRegistryUpdateStep("Restarting affected Processors");
 
-    public VariableRegistryUpdateRequest(final String requestId, final String processGroupId) {
+    public VariableRegistryUpdateRequest(final String requestId, final String processGroupId, final Set<AffectedComponentEntity> affectedComponents, final NiFiUser user) {
         this.requestId = requestId;
         this.processGroupId = processGroupId;
+        this.affectedComponents = affectedComponents.stream().collect(Collectors.toMap(AffectedComponentEntity::getId, Function.identity()));
+        this.user = user;
     }
 
     public String getProcessGroupId() {
         return processGroupId;
     }
 
-
     public String getRequestId() {
         return requestId;
     }
@@ -54,6 +66,10 @@ public class VariableRegistryUpdateRequest {
         return submissionTime;
     }
 
+    public NiFiUser getUser() {
+        return user;
+    }
+
     public Date getLastUpdated() {
         return lastUpdated;
     }
@@ -102,6 +118,18 @@ public class VariableRegistryUpdateRequest {
         this.failureReason.set(reason);
     }
 
+    public RevisionDTO getProcessGroupRevision() {
+        return processGroupRevision;
+    }
+
+    public void setProcessGroupRevision(RevisionDTO processGroupRevision) {
+        this.processGroupRevision = processGroupRevision;
+    }
+
+    public Map<String, AffectedComponentEntity> getAffectedComponents() {
+        return affectedComponents;
+    }
+
     public void cancel() {
         this.failureReason.compareAndSet(null, "Update was cancelled");
         this.complete = true;

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/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 6fed58e..faa8c0e 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,13 +16,6 @@
  */
 package org.apache.nifi.web;
 
-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;
@@ -77,6 +70,7 @@ import org.apache.nifi.web.api.dto.status.ControllerStatusDTO;
 import org.apache.nifi.web.api.entity.AccessPolicyEntity;
 import org.apache.nifi.web.api.entity.ActionEntity;
 import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
 import org.apache.nifi.web.api.entity.BulletinEntity;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
 import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
@@ -108,6 +102,13 @@ import org.apache.nifi.web.api.entity.UserEntity;
 import org.apache.nifi.web.api.entity.UserGroupEntity;
 import org.apache.nifi.web.api.entity.VariableRegistryEntity;
 
+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.
  */
@@ -518,9 +519,10 @@ public interface NiFiServiceFacade {
      * Gets all the Processor transfer objects for this controller.
      *
      * @param groupId group
+     * @param includeDescendants if processors from descendent groups should be included
      * @return List of all the Processor transfer object
      */
-    Set<ProcessorEntity> getProcessors(String groupId);
+    Set<ProcessorEntity> getProcessors(String groupId, boolean includeDescendants);
 
     /**
      * Verifies the specified processor can be updated.
@@ -925,12 +927,21 @@ public interface NiFiServiceFacade {
     VariableRegistryEntity updateVariableRegistry(NiFiUser user, Revision revision, VariableRegistryDTO variableRegistryDto);
 
     /**
-     * Determines which components will be affected by updating the given Variable Registry
+     * Determines which components will be affected by updating the given Variable Registry.
+     *
+     * @param variableRegistryDto the variable registry
+     * @return the components that will be affected
+     */
+    Set<AffectedComponentEntity> getComponentsAffectedByVariableRegistryUpdate(VariableRegistryDTO variableRegistryDto);
+
+    /**
+     * Determines which components are active and will be affected by updating the given Variable Registry. These active components
+     * are needed to authorize the request and deactivate prior to changing the variables.
      *
      * @param variableRegistryDto the variable registry
      * @return the components that will be affected
      */
-    Set<AffectedComponentDTO> getComponentsAffectedByVariableRegistryUpdate(VariableRegistryDTO variableRegistryDto);
+    Set<AffectedComponentDTO> getActiveComponentsAffectedByVariableRegistryUpdate(VariableRegistryDTO variableRegistryDto);
 
     /**
      * Gets all process groups in the specified parent group.

http://git-wip-us.apache.org/repos/asf/nifi/blob/eac47e90/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 7cd5732..9caabd6 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
@@ -161,6 +161,7 @@ import org.apache.nifi.web.api.entity.AccessPolicyEntity;
 import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
 import org.apache.nifi.web.api.entity.ActionEntity;
 import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
+import org.apache.nifi.web.api.entity.AffectedComponentEntity;
 import org.apache.nifi.web.api.entity.BulletinEntity;
 import org.apache.nifi.web.api.entity.ComponentReferenceEntity;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
@@ -790,7 +791,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     @Override
-    public Set<AffectedComponentDTO> getComponentsAffectedByVariableRegistryUpdate(final VariableRegistryDTO variableRegistryDto) {
+    public Set<AffectedComponentDTO> getActiveComponentsAffectedByVariableRegistryUpdate(final VariableRegistryDTO variableRegistryDto) {
         final ProcessGroup group = processGroupDAO.getProcessGroup(variableRegistryDto.getProcessGroupId());
         if (group == null) {
             throw new ResourceNotFoundException("Could not find Process Group with ID " + variableRegistryDto.getProcessGroupId());
@@ -827,6 +828,29 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         return affectedComponentDtos;
     }
 
+    @Override
+    public Set<AffectedComponentEntity> getComponentsAffectedByVariableRegistryUpdate(final VariableRegistryDTO variableRegistryDto) {
+        final ProcessGroup group = processGroupDAO.getProcessGroup(variableRegistryDto.getProcessGroupId());
+        if (group == null) {
+            throw new ResourceNotFoundException("Could not find Process Group with ID " + variableRegistryDto.getProcessGroupId());
+        }
+
+        final Map<String, String> variableMap = new HashMap<>();
+        variableRegistryDto.getVariables().stream() // have to use forEach here instead of using Collectors.toMap because value may be null
+                .map(VariableEntity::getVariable)
+                .forEach(var -> variableMap.put(var.getName(), var.getValue()));
+
+        final Set<AffectedComponentEntity> affectedComponentEntities = new HashSet<>();
+
+        final Set<String> updatedVariableNames = getUpdatedVariables(group, variableMap);
+        for (final String variableName : updatedVariableNames) {
+            final Set<ConfiguredComponent> affectedComponents = group.getComponentsAffectedByVariable(variableName);
+            affectedComponentEntities.addAll(dtoFactory.createAffectedComponentEntities(affectedComponents, revisionManager));
+        }
+
+        return affectedComponentEntities;
+    }
+
     private Set<String> getUpdatedVariables(final ProcessGroup group, final Map<String, String> newVariableValues) {
         final Set<String> updatedVariableNames = new HashSet<>();
 
@@ -856,7 +880,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
         final RevisionUpdate<VariableRegistryDTO> snapshot = updateComponent(user, revision,
             processGroupNode,
             () -> processGroupDAO.updateVariableRegistry(variableRegistryDto),
-            processGroup -> dtoFactory.createVariableRegistryDto(processGroup));
+            processGroup -> dtoFactory.createVariableRegistryDto(processGroup, revisionManager));
 
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroupNode);
         final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
@@ -2498,8 +2522,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     @Override
-    public Set<ProcessorEntity> getProcessors(final String groupId) {
-        final Set<ProcessorNode> processors = processorDAO.getProcessors(groupId);
+    public Set<ProcessorEntity> getProcessors(final String groupId, final boolean includeDescendants) {
+        final Set<ProcessorNode> processors = processorDAO.getProcessors(groupId, includeDescendants);
         return processors.stream()
             .map(processor -> createProcessorEntity(processor))
             .collect(Collectors.toSet());
@@ -3231,7 +3255,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     private VariableRegistryEntity createVariableRegistryEntity(final ProcessGroup processGroup, final boolean includeAncestorGroups) {
-        final VariableRegistryDTO registryDto = dtoFactory.createVariableRegistryDto(processGroup);
+        final VariableRegistryDTO registryDto = dtoFactory.createVariableRegistryDto(processGroup, revisionManager);
         final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(processGroup.getIdentifier()));
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup);
 
@@ -3240,7 +3264,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
             while (parent != null) {
                 final PermissionsDTO parentPerms = dtoFactory.createPermissionsDto(parent);
                 if (Boolean.TRUE.equals(parentPerms.getCanRead())) {
-                    final VariableRegistryDTO parentRegistryDto = dtoFactory.createVariableRegistryDto(parent);
+                    final VariableRegistryDTO parentRegistryDto = dtoFactory.createVariableRegistryDto(parent, revisionManager);
                     final Set<VariableEntity> parentVariables = parentRegistryDto.getVariables();
                     registryDto.getVariables().addAll(parentVariables);
                 }
@@ -3260,7 +3284,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
             throw new ResourceNotFoundException("Could not find group with ID " + groupId);
         }
 
-        final VariableRegistryDTO registryDto = dtoFactory.populateAffectedComponents(variableRegistryDto, processGroup);
+        final VariableRegistryDTO registryDto = dtoFactory.populateAffectedComponents(variableRegistryDto, processGroup, revisionManager);
         final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(processGroup.getIdentifier()));
         final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup);
         return entityFactory.createVariableRegistryEntity(registryDto, revision, permissions);