http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index 6a90d1f..b6671b2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -16,36 +16,14 @@
  */
 package org.apache.nifi.web.api;
 
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-
+import com.sun.jersey.api.core.ResourceContext;
+import com.sun.jersey.multipart.FormDataParam;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiParam;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
+import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.authorization.Authorizer;
 import org.apache.nifi.authorization.RequestAction;
@@ -54,7 +32,6 @@ import org.apache.nifi.controller.Snippet;
 import org.apache.nifi.web.AuthorizableLookup;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.UpdateResult;
 import org.apache.nifi.web.api.dto.ConnectionDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
@@ -88,14 +65,34 @@ import org.apache.nifi.web.api.request.LongParameter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.sun.jersey.api.core.ResourceContext;
-import com.sun.jersey.multipart.FormDataParam;
-import com.wordnik.swagger.annotations.Api;
-import com.wordnik.swagger.annotations.ApiOperation;
-import com.wordnik.swagger.annotations.ApiParam;
-import com.wordnik.swagger.annotations.ApiResponse;
-import com.wordnik.swagger.annotations.ApiResponses;
-import com.wordnik.swagger.annotations.Authorization;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * RESTful endpoint for managing a Group.
@@ -320,21 +317,16 @@ public class ProcessGroupResource extends 
ApplicationResource {
             serviceFacade,
             revision,
             lookup -> {
-                final Authorizable processGroup = lookup.getProcessGroup(id);
-                processGroup.authorize(authorizer, RequestAction.WRITE);
+                Authorizable authorizable = lookup.getProcessGroup(id);
+                authorizable.authorize(authorizer, RequestAction.WRITE);
             },
             null,
             () -> {
                 // update the process group
-                final UpdateResult<ProcessGroupEntity> updateResult = 
serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO);
-                final ProcessGroupEntity entity = updateResult.getResult();
+                final ProcessGroupEntity entity = 
serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO);
                 populateRemainingProcessGroupEntityContent(entity);
 
-                if (updateResult.isNew()) {
-                    return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
-                } else {
-                    return clusterContext(generateOkResponse(entity)).build();
-                }
+                return clusterContext(generateOkResponse(entity)).build();
             }
         );
     }
@@ -457,6 +449,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Process group details must be 
specified.");
         }
 
+        if (processGroupEntity.getRevision() == null || 
(processGroupEntity.getRevision().getVersion() == null || 
processGroupEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Process group.");
+        }
+
         if (processGroupEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Process group ID cannot be 
specified.");
         }
@@ -488,7 +484,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         processGroupEntity.getComponent().setId(generateUuid());
 
         // create the process group contents
-        final ProcessGroupEntity entity = 
serviceFacade.createProcessGroup(groupId, processGroupEntity.getComponent());
+        final Revision revision = getRevision(processGroupEntity, 
processGroupEntity.getComponent().getId());
+        final ProcessGroupEntity entity = 
serviceFacade.createProcessGroup(revision, groupId, 
processGroupEntity.getComponent());
         populateRemainingProcessGroupEntityContent(entity);
 
         // generate a 201 created response
@@ -608,6 +605,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Processor details must be 
specified.");
         }
 
+        if (processorEntity.getRevision() == null || 
(processorEntity.getRevision().getVersion() == null || 
processorEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Processor.");
+        }
+
         if (processorEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Processor ID cannot be 
specified.");
         }
@@ -643,7 +644,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         processorEntity.getComponent().setId(generateUuid());
 
         // create the new processor
-        final ProcessorEntity entity = serviceFacade.createProcessor(groupId, 
processorEntity.getComponent());
+        final Revision revision = getRevision(processorEntity, 
processorEntity.getComponent().getId());
+        final ProcessorEntity entity = serviceFacade.createProcessor(revision, 
groupId, processorEntity.getComponent());
         processorResource.populateRemainingProcessorEntityContent(entity);
 
         // generate a 201 created response
@@ -757,6 +759,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Port details must be 
specified.");
         }
 
+        if (portEntity.getRevision() == null || 
(portEntity.getRevision().getVersion() == null || 
portEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Input port.");
+        }
+
         if (portEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Input port ID cannot be 
specified.");
         }
@@ -788,7 +794,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         portEntity.getComponent().setId(generateUuid());
 
         // create the input port and generate the json
-        final PortEntity entity = serviceFacade.createInputPort(groupId, 
portEntity.getComponent());
+        final Revision revision = getRevision(portEntity, 
portEntity.getComponent().getId());
+        final PortEntity entity = serviceFacade.createInputPort(revision, 
groupId, portEntity.getComponent());
         inputPortResource.populateRemainingInputPortEntityContent(entity);
 
         // build the response
@@ -899,6 +906,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Port details must be 
specified.");
         }
 
+        if (portEntity.getRevision() == null || 
(portEntity.getRevision().getVersion() == null || 
portEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Output port.");
+        }
+
         if (portEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Output port ID cannot be 
specified.");
         }
@@ -930,7 +941,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         portEntity.getComponent().setId(generateUuid());
 
         // create the output port and generate the json
-        final PortEntity entity = serviceFacade.createOutputPort(groupId, 
portEntity.getComponent());
+        final Revision revision = getRevision(portEntity, 
portEntity.getComponent().getId());
+        final PortEntity entity = serviceFacade.createOutputPort(revision, 
groupId, portEntity.getComponent());
         outputPortResource.populateRemainingOutputPortEntityContent(entity);
 
         // build the response
@@ -1042,6 +1054,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Funnel details must be 
specified.");
         }
 
+        if (funnelEntity.getRevision() == null || 
(funnelEntity.getRevision().getVersion() == null || 
funnelEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Funnel.");
+        }
+
         if (funnelEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Funnel ID cannot be 
specified.");
         }
@@ -1073,7 +1089,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         funnelEntity.getComponent().setId(generateUuid());
 
         // create the funnel and generate the json
-        final FunnelEntity entity = serviceFacade.createFunnel(groupId, 
funnelEntity.getComponent());
+        final Revision revision = getRevision(funnelEntity, 
funnelEntity.getComponent().getId());
+        final FunnelEntity entity = serviceFacade.createFunnel(revision, 
groupId, funnelEntity.getComponent());
         funnelResource.populateRemainingFunnelEntityContent(entity);
 
         // build the response
@@ -1185,6 +1202,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Label details must be 
specified.");
         }
 
+        if (labelEntity.getRevision() == null || 
(labelEntity.getRevision().getVersion() == null || 
labelEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Label.");
+        }
+
         if (labelEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Label ID cannot be 
specified.");
         }
@@ -1216,7 +1237,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         labelEntity.getComponent().setId(generateUuid());
 
         // create the label and generate the json
-        final LabelEntity entity = serviceFacade.createLabel(groupId, 
labelEntity.getComponent());
+        final Revision revision = getRevision(labelEntity, 
labelEntity.getComponent().getId());
+        final LabelEntity entity = serviceFacade.createLabel(revision, 
groupId, labelEntity.getComponent());
         labelResource.populateRemainingLabelEntityContent(entity);
 
         // build the response
@@ -1328,6 +1350,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Remote process group details 
must be specified.");
         }
 
+        if (remoteProcessGroupEntity.getRevision() == null || 
(remoteProcessGroupEntity.getRevision().getVersion() == null || 
remoteProcessGroupEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Remote process group.");
+        }
+
         final RemoteProcessGroupDTO requestProcessGroupDTO = 
remoteProcessGroupEntity.getComponent();
 
         if (requestProcessGroupDTO.getId() != null) {
@@ -1391,7 +1417,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         requestProcessGroupDTO.setTargetUri(controllerUri);
 
         // create the remote process group
-        final RemoteProcessGroupEntity entity = 
serviceFacade.createRemoteProcessGroup(groupId, requestProcessGroupDTO);
+        final Revision revision = getRevision(remoteProcessGroupEntity, 
requestProcessGroupDTO.getId());
+        final RemoteProcessGroupEntity entity = 
serviceFacade.createRemoteProcessGroup(revision, groupId, 
requestProcessGroupDTO);
         
remoteProcessGroupResource.populateRemainingRemoteProcessGroupEntityContent(entity);
 
         return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
@@ -1517,6 +1544,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Connection details must be 
specified.");
         }
 
+        if (connectionEntity.getRevision() == null || 
(connectionEntity.getRevision().getVersion() == null || 
connectionEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Connection.");
+        }
+
         if (connectionEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Connection ID cannot be 
specified.");
         }
@@ -1552,7 +1583,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         connection.setId(generateUuid());
 
         // create the new relationship target
-        final ConnectionEntity entity = 
serviceFacade.createConnection(groupId, connection);
+        final Revision revision = getRevision(connectionEntity, 
connection.getId());
+        final ConnectionEntity entity = 
serviceFacade.createConnection(revision, groupId, connection);
         connectionResource.populateRemainingConnectionEntityContent(entity);
 
         // extract the href and build the response
@@ -2127,6 +2159,10 @@ public class ProcessGroupResource extends 
ApplicationResource {
             throw new IllegalArgumentException("Controller service details 
must be specified.");
         }
 
+        if (controllerServiceEntity.getRevision() == null || 
(controllerServiceEntity.getRevision().getVersion() == null || 
controllerServiceEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Controller service.");
+        }
+
         if (controllerServiceEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("Controller service ID cannot 
be specified.");
         }
@@ -2162,7 +2198,8 @@ public class ProcessGroupResource extends 
ApplicationResource {
         controllerServiceEntity.getComponent().setId(generateUuid());
 
         // create the controller service and generate the json
-        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(groupId, 
controllerServiceEntity.getComponent());
+        final Revision revision = getRevision(controllerServiceEntity, 
controllerServiceEntity.getComponent().getId());
+        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(revision, groupId, 
controllerServiceEntity.getComponent());
         
controllerServiceResource.populateRemainingControllerServiceContent(entity.getComponent());
 
         // build the response

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index dccb1f3..0847fe0 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -31,7 +31,6 @@ import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.UiExtensionType;
-import org.apache.nifi.web.UpdateResult;
 import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
@@ -58,7 +57,6 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import java.net.URI;
 import java.util.List;
 import java.util.Set;
 
@@ -383,8 +381,6 @@ public class ProcessorResource extends ApplicationResource {
                 processor.authorize(authorizer, RequestAction.WRITE);
             });
         }
-
-        // handle expects request (usually from the cluster manager)
         if (isValidationPhase) {
             serviceFacade.verifyCanClearProcessorState(id);
             return generateContinueResponse().build();
@@ -467,21 +463,16 @@ public class ProcessorResource extends 
ApplicationResource {
             serviceFacade,
             revision,
             lookup -> {
-                final Authorizable processor = lookup.getProcessor(id);
-                processor.authorize(authorizer, RequestAction.WRITE);
+                Authorizable authorizable = lookup.getProcessor(id);
+                authorizable.authorize(authorizer, RequestAction.WRITE);
             },
             () -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO),
             () -> {
                 // update the processor
-                final UpdateResult<ProcessorEntity> result = 
serviceFacade.updateProcessor(revision, requestProcessorDTO);
-                final ProcessorEntity entity = result.getResult();
+                final ProcessorEntity entity = 
serviceFacade.updateProcessor(revision, requestProcessorDTO);
                 populateRemainingProcessorEntityContent(entity);
 
-                if (result.isNew()) {
-                    return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
-                } else {
-                    return clusterContext(generateOkResponse(entity)).build();
-                }
+                return clusterContext(generateOkResponse(entity)).build();
             }
         );
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
index 1e9e720..9739c8c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java
@@ -28,7 +28,6 @@ import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.UpdateResult;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
@@ -492,8 +491,8 @@ public class RemoteProcessGroupResource extends 
ApplicationResource {
             serviceFacade,
             revision,
             lookup -> {
-                final Authorizable remoteProcessGroup = 
lookup.getRemoteProcessGroup(id);
-                remoteProcessGroup.authorize(authorizer, RequestAction.WRITE);
+                Authorizable authorizable = lookup.getRemoteProcessGroup(id);
+                authorizable.authorize(authorizer, RequestAction.WRITE);
             },
             () -> 
serviceFacade.verifyUpdateRemoteProcessGroup(requestRemoteProcessGroup),
             () -> {
@@ -530,16 +529,10 @@ public class RemoteProcessGroupResource extends 
ApplicationResource {
                 }
 
                 // update the specified remote process group
-                final UpdateResult<RemoteProcessGroupEntity> updateResult = 
serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup);
-
-                final RemoteProcessGroupEntity entity = 
updateResult.getResult();
+                final RemoteProcessGroupEntity entity = 
serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup);
                 populateRemainingRemoteProcessGroupEntityContent(entity);
 
-                if (updateResult.isNew()) {
-                    return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
-                } else {
-                    return clusterContext(generateOkResponse(entity)).build();
-                }
+                return clusterContext(generateOkResponse(entity)).build();
             }
         );
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
index f1fa304..54e63b3 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
@@ -31,7 +31,6 @@ import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
 import org.apache.nifi.web.UiExtensionType;
-import org.apache.nifi.web.UpdateResult;
 import org.apache.nifi.web.api.dto.ComponentStateDTO;
 import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
@@ -57,7 +56,6 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import java.net.URI;
 import java.util.List;
 import java.util.Set;
 
@@ -359,12 +357,10 @@ public class ReportingTaskResource extends 
ApplicationResource {
         if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
             // authorize access
             serviceFacade.authorizeAccess(lookup -> {
-                final Authorizable reportingTask = lookup.getReportingTask(id);
-                reportingTask.authorize(authorizer, RequestAction.WRITE);
+                final Authorizable processor = lookup.getReportingTask(id);
+                processor.authorize(authorizer, RequestAction.WRITE);
             });
         }
-
-        // handle expects request (usually from the cluster manager)
         if (isValidationPhase) {
             serviceFacade.verifyCanClearReportingTaskState(id);
             return generateContinueResponse().build();
@@ -446,23 +442,16 @@ public class ReportingTaskResource extends 
ApplicationResource {
             serviceFacade,
             revision,
             lookup -> {
-                final Authorizable reportingTask = lookup.getReportingTask(id);
-                reportingTask.authorize(authorizer, RequestAction.WRITE);
+                Authorizable authorizable = lookup.getReportingTask(id);
+                authorizable.authorize(authorizer, RequestAction.WRITE);
             },
             () -> 
serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO),
             () -> {
                 // update the reporting task
-                final UpdateResult<ReportingTaskEntity> controllerResponse = 
serviceFacade.updateReportingTask(revision, requestReportingTaskDTO);
-
-                // get the results
-                final ReportingTaskEntity entity = 
controllerResponse.getResult();
+                final ReportingTaskEntity entity = 
serviceFacade.updateReportingTask(revision, requestReportingTaskDTO);
                 populateRemainingReportingTaskEntityContent(entity);
 
-                if (controllerResponse.isNew()) {
-                    return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
-                } else {
-                    return clusterContext(generateOkResponse(entity)).build();
-                }
+                return clusterContext(generateOkResponse(entity)).build();
             }
         );
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
index 0cde5cb..d689749 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
@@ -24,6 +24,7 @@ import com.wordnik.swagger.annotations.ApiResponse;
 import com.wordnik.swagger.annotations.ApiResponses;
 import com.wordnik.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.Authorizer;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
 import org.apache.nifi.remote.HttpRemoteSiteListener;
@@ -38,11 +39,11 @@ import 
org.apache.nifi.remote.exception.NotAuthorizedException;
 import org.apache.nifi.remote.exception.RequestExpiredException;
 import org.apache.nifi.remote.io.http.HttpOutput;
 import org.apache.nifi.remote.io.http.HttpServerCommunicationsSession;
+import org.apache.nifi.remote.protocol.HandshakeProperty;
+import org.apache.nifi.remote.protocol.ResponseCode;
 import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol;
 import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocolImpl;
 import org.apache.nifi.remote.protocol.http.HttpHeaders;
-import org.apache.nifi.remote.protocol.HandshakeProperty;
-import org.apache.nifi.remote.protocol.ResponseCode;
 import org.apache.nifi.stream.io.ByteArrayOutputStream;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.api.dto.ControllerDTO;
@@ -82,17 +83,17 @@ import java.util.ArrayList;
 
 import static javax.ws.rs.core.Response.Status.NOT_FOUND;
 import static org.apache.commons.lang3.StringUtils.isEmpty;
-import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_USE_COMPRESSION;
+import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_COUNT;
+import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_DURATION;
+import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_SIZE;
+import static 
org.apache.nifi.remote.protocol.HandshakeProperty.REQUEST_EXPIRATION_MILLIS;
 import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_COUNT;
 import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_DURATION;
 import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_SIZE;
 import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_REQUEST_EXPIRATION;
+import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_USE_COMPRESSION;
 import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_NAME;
 import static 
org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_VALUE;
-import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_COUNT;
-import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_DURATION;
-import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_SIZE;
-import static 
org.apache.nifi.remote.protocol.HandshakeProperty.REQUEST_EXPIRATION_MILLIS;
 
 /**
  * RESTful endpoint for managing a SiteToSite connection.
@@ -114,6 +115,7 @@ public class SiteToSiteResource extends ApplicationResource 
{
     private static final String PORT_TYPE_OUTPUT = "output-ports";
 
     private NiFiServiceFacade serviceFacade;
+    private Authorizer authorizer;
     private final ResponseCreator responseCreator = new ResponseCreator();
     private final VersionNegotiator transportProtocolVersionNegotiator = new 
TransportProtocolVersionNegotiator(1);
     private final HttpRemoteSiteListener transactionManager = 
HttpRemoteSiteListener.getInstance();
@@ -143,7 +145,7 @@ public class SiteToSiteResource extends ApplicationResource 
{
                 @ApiResponse(code = 409, message = "The request was valid but 
NiFi was not in the appropriate state to process it. Retrying the same request 
later may be successful.")
             }
     )
-    public Response getController(
+    public Response getSiteToSite(
             @Context HttpServletRequest req) {
 
         if (isReplicateRequest()) {
@@ -996,6 +998,9 @@ public class SiteToSiteResource extends ApplicationResource 
{
         this.serviceFacade = serviceFacade;
     }
 
+    public void setAuthorizer(Authorizer authorizer) {
+        this.authorizer = authorizer;
+    }
 
     private class ResponseCreator {
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UserGroupsResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UserGroupsResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UserGroupsResource.java
index 553f8c6..a770e8b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UserGroupsResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UserGroupsResource.java
@@ -31,7 +31,6 @@ import 
org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.UpdateResult;
 import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.dto.UserGroupDTO;
 import org.apache.nifi.web.api.entity.UserGroupEntity;
@@ -133,6 +132,10 @@ public class UserGroupsResource extends 
ApplicationResource {
             throw new IllegalArgumentException("User group details must be 
specified.");
         }
 
+        if (userGroupEntity.getRevision() == null || 
(userGroupEntity.getRevision().getVersion() == null || 
userGroupEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Processor.");
+        }
+
         if (userGroupEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("User group ID cannot be 
specified.");
         }
@@ -294,17 +297,10 @@ public class UserGroupsResource extends 
ApplicationResource {
                 null,
                 () -> {
                     // update the user group
-                    final UpdateResult<UserGroupEntity> updateResult = 
serviceFacade.updateUserGroup(revision, userGroupDTO);
-
-                    // get the results
-                    final UserGroupEntity entity = updateResult.getResult();
+                    final UserGroupEntity entity = 
serviceFacade.updateUserGroup(revision, userGroupDTO);
                     populateRemainingUserGroupEntityContent(entity);
 
-                    if (updateResult.isNew()) {
-                        return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
-                    } else {
-                        return 
clusterContext(generateOkResponse(entity)).build();
-                    }
+                    return clusterContext(generateOkResponse(entity)).build();
                 }
         );
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UsersResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UsersResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UsersResource.java
index 01deb93..4a7bc4b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UsersResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/UsersResource.java
@@ -31,7 +31,6 @@ import 
org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.UpdateResult;
 import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.dto.UserDTO;
 import org.apache.nifi.web.api.entity.UserEntity;
@@ -133,6 +132,10 @@ public class UsersResource extends ApplicationResource {
             throw new IllegalArgumentException("User details must be 
specified.");
         }
 
+        if (userEntity.getRevision() == null || 
(userEntity.getRevision().getVersion() == null || 
userEntity.getRevision().getVersion() != 0)) {
+            throw new IllegalArgumentException("A revision of 0 must be 
specified when creating a new Processor.");
+        }
+
         if (userEntity.getComponent().getId() != null) {
             throw new IllegalArgumentException("User ID cannot be specified.");
         }
@@ -294,17 +297,10 @@ public class UsersResource extends ApplicationResource {
                 null,
                 () -> {
                     // update the user
-                    final UpdateResult<UserEntity> updateResult = 
serviceFacade.updateUser(revision, userDTO);
-
-                    // get the results
-                    final UserEntity entity = updateResult.getResult();
+                    final UserEntity entity = 
serviceFacade.updateUser(revision, userDTO);
                     populateRemainingUserEntityContent(entity);
 
-                    if (updateResult.isNew()) {
-                        return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
-                    } else {
-                        return 
clusterContext(generateOkResponse(entity)).build();
-                    }
+                    return clusterContext(generateOkResponse(entity)).build();
                 }
         );
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 5aaddcd..0577b03 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -185,10 +185,15 @@ public final class DtoFactory {
     private EntityFactory entityFactory;
     private Authorizer authorizer;
 
-    public ControllerConfigurationDTO createControllerConfigurationDto(final 
ControllerFacade controllerFacade, final String autoRefreshInterval) {
+    public ControllerConfigurationDTO createControllerConfigurationDto(final 
ControllerFacade controllerFacade) {
         final ControllerConfigurationDTO dto = new 
ControllerConfigurationDTO();
         
dto.setMaxTimerDrivenThreadCount(controllerFacade.getMaxTimerDrivenThreadCount());
         
dto.setMaxEventDrivenThreadCount(controllerFacade.getMaxEventDrivenThreadCount());
+        return dto;
+    }
+
+    public FlowConfigurationDTO createFlowConfigurationDto(final String 
autoRefreshInterval) {
+        final FlowConfigurationDTO dto = new FlowConfigurationDTO();
 
         // get the refresh interval
         final long refreshInterval = 
FormatUtils.getTimeDuration(autoRefreshInterval, TimeUnit.SECONDS);

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
index fa5620a..e1c183b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
@@ -42,6 +42,7 @@ import org.apache.nifi.web.api.entity.SnippetEntity;
 import org.apache.nifi.web.api.entity.UserEntity;
 import org.apache.nifi.web.api.entity.UserGroupEntity;
 
+import java.util.Date;
 import java.util.List;
 
 public final class EntityFactory {
@@ -49,12 +50,12 @@ public final class EntityFactory {
     public ControllerConfigurationEntity 
createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final 
RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
         final ControllerConfigurationEntity entity = new 
ControllerConfigurationEntity();
         entity.setRevision(revision);
+        entity.setCurrentTime(new Date());
         if (dto != null) {
             entity.setAccessPolicy(accessPolicy);
-            // TODO - remove this once contents of 
ControllerConfigurationEntity is updated
-//            if (accessPolicy != null && accessPolicy.getCanRead()) {
-                entity.setConfig(dto);
-//            }
+            if (accessPolicy != null && accessPolicy.getCanRead()) {
+                entity.setControllerConfiguration(dto);
+            }
         }
         return entity;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 68208ec..5d41c2c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -19,7 +19,12 @@ package org.apache.nifi.web.controller;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.admin.service.KeyService;
+import org.apache.nifi.authorization.AccessDeniedException;
+import org.apache.nifi.authorization.AuthorizationRequest;
+import org.apache.nifi.authorization.AuthorizationResult;
+import org.apache.nifi.authorization.AuthorizationResult.Result;
+import org.apache.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.Resource;
 import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.authorization.resource.ResourceFactory;
@@ -111,6 +116,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
 import java.io.IOException;
 import java.io.InputStream;
 import java.text.Collator;
@@ -130,6 +136,8 @@ import java.util.TimeZone;
 import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
 
+import static org.apache.nifi.controller.FlowController.ROOT_GROUP_ID_ALIAS;
+
 public class ControllerFacade implements Authorizable {
 
     private static final Logger logger = 
LoggerFactory.getLogger(ControllerFacade.class);
@@ -137,14 +145,15 @@ public class ControllerFacade implements Authorizable {
     // nifi components
     private FlowController flowController;
     private FlowService flowService;
-    private KeyService keyService;
     private ClusterCoordinator clusterCoordinator;
     private BulletinRepository bulletinRepository;
+    private Authorizer authorizer;
 
     // properties
     private NiFiProperties properties;
     private DtoFactory dtoFactory;
 
+
     /**
      * Creates an archive of the current flow.
      *
@@ -264,6 +273,14 @@ public class ControllerFacade implements Authorizable {
      * @return status history
      */
     public StatusHistoryDTO getProcessorStatusHistory(final String 
processorId) {
+        final ProcessGroup root = 
flowController.getGroup(flowController.getRootGroupId());
+        final ProcessorNode processor = root.findProcessor(processorId);
+
+        // ensure the processor was found
+        if (processor == null) {
+            throw new ResourceNotFoundException(String.format("Unable to 
locate processor with id '%s'.", processorId));
+        }
+
         return flowController.getProcessorStatusHistory(processorId);
     }
 
@@ -274,6 +291,14 @@ public class ControllerFacade implements Authorizable {
      * @return status history
      */
     public StatusHistoryDTO getConnectionStatusHistory(final String 
connectionId) {
+        final ProcessGroup root = 
flowController.getGroup(flowController.getRootGroupId());
+        final Connection connection = root.findConnection(connectionId);
+
+        // ensure the connection was found
+        if (connection == null) {
+            throw new ResourceNotFoundException(String.format("Unable to 
locate connection with id '%s'.", connectionId));
+        }
+
         return flowController.getConnectionStatusHistory(connectionId);
     }
 
@@ -284,6 +309,15 @@ public class ControllerFacade implements Authorizable {
      * @return status history
      */
     public StatusHistoryDTO getProcessGroupStatusHistory(final String groupId) 
{
+        final String searchId = groupId.equals(ROOT_GROUP_ID_ALIAS) ? 
flowController.getRootGroupId() : groupId;
+        final ProcessGroup root = 
flowController.getGroup(flowController.getRootGroupId());
+        final ProcessGroup group = root.findProcessGroup(searchId);
+
+        // ensure the processor was found
+        if (group == null) {
+            throw new ResourceNotFoundException(String.format("Unable to 
locate process group with id '%s'.", groupId));
+        }
+
         return flowController.getProcessGroupStatusHistory(groupId);
     }
 
@@ -294,6 +328,14 @@ public class ControllerFacade implements Authorizable {
      * @return status history
      */
     public StatusHistoryDTO getRemoteProcessGroupStatusHistory(final String 
remoteProcessGroupId) {
+        final ProcessGroup root = 
flowController.getGroup(flowController.getRootGroupId());
+        final RemoteProcessGroup remoteProcessGroup = 
root.findRemoteProcessGroup(remoteProcessGroupId);
+
+        // ensure the output port was found
+        if (remoteProcessGroup == null) {
+            throw new ResourceNotFoundException(String.format("Unable to 
locate remote process group with id '%s'.", remoteProcessGroupId));
+        }
+
         return 
flowController.getRemoteProcessGroupStatusHistory(remoteProcessGroupId);
     }
 
@@ -1085,9 +1127,6 @@ public class ControllerFacade implements Authorizable {
     public DownloadableContent getContent(final Long eventId, final String 
uri, final ContentDirection contentDirection) {
         try {
             final NiFiUser user = NiFiUserUtils.getNiFiUser();
-            if (user == null) {
-                throw new WebApplicationException(new Throwable("Unable to 
access details for current user."));
-            }
 
             // get the event in order to get the filename
             final ProvenanceEventRecord event = 
flowController.getProvenanceRepository().getEvent(eventId);
@@ -1105,12 +1144,56 @@ public class ControllerFacade implements Authorizable {
 
             // calculate the dn chain
             final List<String> dnChain = 
ProxiedEntitiesUtils.buildProxiedEntitiesChain(user);
+            dnChain.forEach(identity -> {
+                final String rootGroupId = flowController.getRootGroupId();
+                final ProcessGroup rootGroup = 
flowController.getGroup(rootGroupId);
+
+                final Resource eventResource;
+                if (rootGroupId.equals(event.getComponentId())) {
+                    eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.ProcessGroup, 
rootGroup.getIdentifier(), rootGroup.getName());
+                } else {
+                    final Connectable connectable = 
rootGroup.findConnectable(event.getComponentId());
+
+                    if (connectable == null) {
+                        throw new AccessDeniedException("The component that 
generated this event is no longer part of the data flow. Unable to determine 
access policy.");
+                    }
 
-            // TODO - ensure the users in this chain are allowed to download 
this content
-//            final DownloadAuthorization downloadAuthorization = 
keyService.authorizeDownload(dnChain, attributes);
-//            if (!downloadAuthorization.isApproved()) {
-//                throw new 
AccessDeniedException(downloadAuthorization.getExplanation());
-//            }
+                    switch (connectable.getConnectableType()) {
+                        case PROCESSOR:
+                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.Processor, 
connectable.getIdentifier(), connectable.getName());
+                            break;
+                        case INPUT_PORT:
+                        case REMOTE_INPUT_PORT:
+                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.InputPort, 
connectable.getIdentifier(), connectable.getName());
+                            break;
+                        case OUTPUT_PORT:
+                        case REMOTE_OUTPUT_PORT:
+                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.OutputPort, 
connectable.getIdentifier(), connectable.getName());
+                            break;
+                        case FUNNEL:
+                            eventResource = 
ResourceFactory.getComponentProvenanceResource(ResourceType.Funnel, 
connectable.getIdentifier(), connectable.getName());
+                            break;
+                        default:
+                            throw new 
WebApplicationException(Response.serverError().entity("An unexpected type of 
component generated this event.").build());
+                    }
+                }
+
+                // build the request
+                final AuthorizationRequest request = new 
AuthorizationRequest.Builder()
+                        .identity(identity)
+                        .anonymous(user.isAnonymous()) // allow current user 
to drive anonymous flag as anonymous users are never chained... supports single 
user case
+                        .accessAttempt(false)
+                        .action(RequestAction.READ)
+                        .resource(eventResource)
+                        .eventAttributes(attributes)
+                        .build();
+
+                // perform the authorization
+                final AuthorizationResult result = 
authorizer.authorize(request);
+                if (!Result.Approved.equals(result.getResult())) {
+                    throw new AccessDeniedException(result.getExplanation());
+                }
+            });
 
             // get the filename and fall back to the identifier (should never 
happen)
             String filename = attributes.get(CoreAttributes.FILENAME.key());
@@ -1687,8 +1770,8 @@ public class ControllerFacade implements Authorizable {
         this.properties = properties;
     }
 
-    public void setKeyService(KeyService keyService) {
-        this.keyService = keyService;
+    public void setAuthorizer(Authorizer authorizer) {
+        this.authorizer = authorizer;
     }
 
     public void setFlowService(FlowService flowService) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
index f5c6f85..e16dd05 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java
@@ -16,6 +16,10 @@
  */
 package org.apache.nifi.web.dao.impl;
 
+import org.apache.nifi.authorization.AccessDeniedException;
+import org.apache.nifi.authorization.AuthorizationRequest;
+import org.apache.nifi.authorization.AuthorizationResult;
+import org.apache.nifi.authorization.AuthorizationResult.Result;
 import org.apache.nifi.authorization.Authorizer;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.user.NiFiUser;
@@ -579,9 +583,6 @@ public class StandardConnectionDAO extends ComponentDAO 
implements ConnectionDAO
     public DownloadableContent getContent(String id, String flowFileUuid, 
String requestUri) {
         try {
             final NiFiUser user = NiFiUserUtils.getNiFiUser();
-            if (user == null) {
-                throw new WebApplicationException(new Throwable("Unable to 
access details for current user."));
-            }
 
             final Connection connection = locateConnection(id);
             final FlowFileQueue queue = connection.getFlowFileQueue();
@@ -591,15 +592,27 @@ public class StandardConnectionDAO extends ComponentDAO 
implements ConnectionDAO
                 throw new ResourceNotFoundException(String.format("The 
FlowFile with UUID %s is no longer in the active queue.", flowFileUuid));
             }
 
+            final Map<String, String> attributes = flowFile.getAttributes();
+
             // calculate the dn chain
             final List<String> dnChain = 
ProxiedEntitiesUtils.buildProxiedEntitiesChain(user);
-
-            // TODO - ensure the users in this chain are allowed to download 
this content
-            final Map<String, String> attributes = flowFile.getAttributes();
-//            final DownloadAuthorization downloadAuthorization = 
keyService.authorizeDownload(dnChain, attributes);
-//            if (!downloadAuthorization.isApproved()) {
-//                throw new 
AccessDeniedException(downloadAuthorization.getExplanation());
-//            }
+            dnChain.forEach(identity -> {
+                // build the request
+                final AuthorizationRequest request = new 
AuthorizationRequest.Builder()
+                        .identity(identity)
+                        .anonymous(user.isAnonymous())
+                        .accessAttempt(false)
+                        .action(RequestAction.WRITE)
+                        .resource(connection.getResource())
+                        .eventAttributes(attributes)
+                        .build();
+
+                // perform the authorization
+                final AuthorizationResult result = 
authorizer.authorize(request);
+                if (!Result.Approved.equals(result.getResult())) {
+                    throw new AccessDeniedException(result.getExplanation());
+                }
+            });
 
             // get the filename and fall back to the identifier (should never 
happen)
             String filename = attributes.get(CoreAttributes.FILENAME.key());

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
index 3db3973..099d4ec 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
@@ -39,6 +39,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.nifi.controller.FlowController.ROOT_GROUP_ID_ALIAS;
+
 public class StandardControllerServiceDAO extends ComponentDAO implements 
ControllerServiceDAO {
 
     private ControllerServiceProvider serviceProvider;
@@ -79,7 +81,7 @@ public class StandardControllerServiceDAO extends 
ComponentDAO implements Contro
                 flowController.addRootControllerService(controllerService);
             } else {
                 final ProcessGroup group;
-                if (groupId.equals(FlowController.ROOT_GROUP_ID_ALIAS)) {
+                if (groupId.equals(ROOT_GROUP_ID_ALIAS)) {
                     group = 
flowController.getGroup(flowController.getRootGroupId());
                 } else {
                     group = 
flowController.getGroup(flowController.getRootGroupId()).findProcessGroup(groupId);
@@ -113,7 +115,8 @@ public class StandardControllerServiceDAO extends 
ComponentDAO implements Contro
         if (groupId == null) {
             return flowController.getRootControllerServices();
         } else {
-            final ProcessGroup procGroup = 
flowController.getGroup(flowController.getRootGroupId()).findProcessGroup(groupId);
+            final String searchId = groupId.equals(ROOT_GROUP_ID_ALIAS) ? 
flowController.getRootGroupId() : groupId;
+            final ProcessGroup procGroup = 
flowController.getGroup(flowController.getRootGroupId()).findProcessGroup(searchId);
             if (procGroup == null) {
                 throw new ResourceNotFoundException("Could not find Process 
Group with ID " + groupId);
             }

http://git-wip-us.apache.org/repos/asf/nifi/blob/f0811ca4/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
index bff775b..6eb9a3a 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
@@ -116,7 +116,7 @@
         <property name="flowController" ref="flowController"/>
         <property name="flowService" ref="flowService"/>
         <property name="clusterCoordinator" ref="clusterCoordinator" />
-        <property name="keyService" ref="keyService"/>
+        <property name="authorizer" ref="authorizer"/>
         <property name="dtoFactory" ref="dtoFactory"/>
         <property name="bulletinRepository" ref="bulletinRepository"/>
     </bean>
@@ -157,7 +157,6 @@
         <property name="userGroupDAO" ref="policyBasedAuthorizerDAO"/>
         <property name="userDAO" ref="policyBasedAuthorizerDAO"/>
         <property name="auditService" ref="auditService"/>
-        <property name="keyService" ref="keyService"/>
         <property name="snippetUtils" ref="snippetUtils"/>
         <property name="revisionManager" ref="revisionManager" />
         <property name="dtoFactory" ref="dtoFactory"/>
@@ -219,6 +218,7 @@
         <property name="properties" ref="nifiProperties"/>
         <property name="clusterCoordinator" ref="clusterCoordinator"/>
         <property name="requestReplicator" ref="requestReplicator" />
+        <property name="authorizer" ref="authorizer"/>
     </bean>
     <bean id="snippetResource" class="org.apache.nifi.web.api.SnippetResource" 
scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>
@@ -320,12 +320,6 @@
         <property name="requestReplicator" ref="requestReplicator" />
         <property name="authorizer" ref="authorizer" />
     </bean>
-    <bean id="historyResource" class="org.apache.nifi.web.api.HistoryResource" 
scope="singleton">
-        <property name="serviceFacade" ref="serviceFacade"/>
-        <property name="properties" ref="nifiProperties"/>
-        <property name="clusterCoordinator" ref="clusterCoordinator"/>
-        <property name="requestReplicator" ref="requestReplicator" />
-    </bean>
     <bean id="provenanceResource" 
class="org.apache.nifi.web.api.ProvenanceResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>
         <property name="properties" ref="nifiProperties"/>
@@ -333,17 +327,12 @@
         <property name="requestReplicator" ref="requestReplicator" />
         <property name="authorizer" ref="authorizer"/>
     </bean>
-    <bean id="clusterResource" class="org.apache.nifi.web.api.ClusterResource" 
scope="singleton">
-        <property name="serviceFacade" ref="serviceFacade"/>
-        <property name="properties" ref="nifiProperties"/>
-        <property name="clusterCoordinator" ref="clusterCoordinator"/>
-        <property name="requestReplicator" ref="requestReplicator" />
-    </bean>
-    <bean id="nodeResource" class="org.apache.nifi.web.api.NodeResource" 
scope="singleton">
+    <bean id="countersResource" 
class="org.apache.nifi.web.api.CountersResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>
         <property name="properties" ref="nifiProperties"/>
         <property name="clusterCoordinator" ref="clusterCoordinator"/>
         <property name="requestReplicator" ref="requestReplicator" />
+        <property name="authorizer" ref="authorizer"/>
     </bean>
     <bean id="systemDiagnosticsResource" 
class="org.apache.nifi.web.api.SystemDiagnosticsResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>

Reply via email to