NIFI-1800:
- UI style updates to make the components stand out better.
- Reusing controller service table in different contexts (controller, process 
group, etc).
- This closes #469


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

Branch: refs/heads/master
Commit: 9152a9fdbb804930e4d3e6dfb44cddfa866d9338
Parents: ae3012a
Author: Matt Gilman <[email protected]>
Authored: Thu May 26 10:20:52 2016 -0400
Committer: Matt Gilman <[email protected]>
Committed: Thu May 26 14:15:56 2016 -0400

----------------------------------------------------------------------
 .../web/api/dto/ControllerConfigurationDTO.java |  51 +-
 .../entity/ControllerConfigurationEntity.java   |  19 +-
 .../apache/nifi/audit/ControllerAuditor.java    | 117 +--
 .../org/apache/nifi/web/NiFiServiceFacade.java  |   5 +-
 .../nifi/web/StandardNiFiServiceFacade.java     |  98 +-
 .../apache/nifi/web/api/ControllerResource.java | 227 +++--
 .../org/apache/nifi/web/api/FlowResource.java   | 130 ++-
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  19 +
 .../apache/nifi/web/api/dto/EntityFactory.java  |  14 +
 .../src/main/resources/nifi-web-api-context.xml |   3 +
 .../accesscontrol/AdminAccessControlTest.java   |   1 -
 .../accesscontrol/DfmAccessControlTest.java     |   2 -
 .../ReadOnlyAccessControlTest.java              |   1 -
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |   1 +
 .../main/resources/filters/canvas.properties    |   1 +
 .../WEB-INF/partials/canvas/navigation.jsp      |  14 +-
 .../canvas/process-group-configuration.jsp      |  55 +-
 .../partials/canvas/settings-content.jsp        |  41 +-
 .../src/main/webapp/css/flow-status.css         |   7 +-
 .../nifi-web-ui/src/main/webapp/css/graph.css   |   6 +
 .../nifi-web-ui/src/main/webapp/css/header.css  |   8 +-
 .../src/main/webapp/css/navigation.css          |  19 +-
 .../webapp/css/process-group-configuration.css  |  59 +-
 .../src/main/webapp/css/settings.css            |  37 +-
 .../propertytable/jquery.propertytable.js       |  77 +-
 .../nf-ng-canvas-global-menu-controller.js      |   4 +-
 .../nf-ng-canvas-header-controller.js           |  26 -
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |  13 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  54 +-
 .../js/nf/canvas/nf-controller-service.js       | 254 +++--
 .../js/nf/canvas/nf-controller-services.js      | 883 ++++++++++++++++++
 .../nf/canvas/nf-process-group-configuration.js | 327 +++++--
 .../webapp/js/nf/canvas/nf-reporting-task.js    |  15 +-
 .../src/main/webapp/js/nf/canvas/nf-settings.js | 920 ++++---------------
 .../src/main/webapp/js/nf/nf-common.js          |  13 +-
 35 files changed, 2047 insertions(+), 1474 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
index c6a7766..2c7edf7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
@@ -17,10 +17,11 @@
 package org.apache.nifi.web.api.dto;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
-import java.util.Date;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.nifi.web.api.dto.util.TimeAdapter;
+import java.util.Date;
 
 /**
  * Details for the controller configuration.
@@ -28,13 +29,10 @@ import org.apache.nifi.web.api.dto.util.TimeAdapter;
 @XmlType(name = "config")
 public class ControllerConfigurationDTO {
 
-    private String name;
-    private String comments;
     private Integer maxTimerDrivenThreadCount;
     private Integer maxEventDrivenThreadCount;
 
     private Long autoRefreshIntervalSeconds;
-    private Boolean siteToSiteSecure;
 
     private Date currentTime;
     private Integer timeOffset;
@@ -68,34 +66,6 @@ public class ControllerConfigurationDTO {
     }
 
     /**
-     * @return name of this NiFi
-     */
-    @ApiModelProperty(
-            value = "The name of this NiFi."
-    )
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * @return comments for this NiFi
-     */
-    @ApiModelProperty(
-            value = "The comments for this NiFi."
-    )
-    public String getComments() {
-        return comments;
-    }
-
-    public void setComments(String comments) {
-        this.comments = comments;
-    }
-
-    /**
      * @return interval in seconds between the automatic NiFi refresh 
requests. This value is read only
      */
     @ApiModelProperty(
@@ -111,21 +81,6 @@ public class ControllerConfigurationDTO {
     }
 
     /**
-     * @return Indicates whether or not Site-to-Site communications with this 
instance is secure (2-way authentication). This value is read only
-     */
-    @ApiModelProperty(
-            value = "Indicates whether site to site communication with the 
NiFi is secure (requires 2-way authenticiation).",
-            readOnly = true
-    )
-    public Boolean isSiteToSiteSecure() {
-        return siteToSiteSecure;
-    }
-
-    public void setSiteToSiteSecure(Boolean siteToSiteSecure) {
-        this.siteToSiteSecure = siteToSiteSecure;
-    }
-
-    /**
      * @return current time on the server
      */
     @XmlJavaTypeAdapter(TimeAdapter.class)

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java
index 5aa7acd..4b1188c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ControllerConfigurationEntity.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.web.api.entity;
 
 import com.wordnik.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.web.api.dto.AccessPolicyDTO;
 import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
 
@@ -26,10 +27,11 @@ import javax.xml.bind.annotation.XmlRootElement;
  * A serialized representation of this class can be placed in the entity body 
of a request or response to or from the API. This particular entity holds a 
reference to a ControllerConfigurationDTO.
  */
 @XmlRootElement(name = "controllerConfigurationEntity")
-public class ControllerConfigurationEntity extends ComponentEntity {
+public class ControllerConfigurationEntity extends Entity {
 
     private ControllerConfigurationDTO config;
     private RevisionDTO revision;
+    private AccessPolicyDTO accessPolicy;
 
     /**
      * @return revision for this request/response
@@ -65,4 +67,19 @@ public class ControllerConfigurationEntity extends 
ComponentEntity {
         this.config = config;
     }
 
+    /**
+     * The access policy for this component.
+     *
+     * @return The access policy
+     */
+    @ApiModelProperty(
+            value = "The access policy for the controller."
+    )
+    public AccessPolicyDTO getAccessPolicy() {
+        return accessPolicy;
+    }
+
+    public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
+        this.accessPolicy = accessPolicy;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ControllerAuditor.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ControllerAuditor.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ControllerAuditor.java
index 5a6c590..d8c2736 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ControllerAuditor.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ControllerAuditor.java
@@ -16,9 +16,6 @@
  */
 package org.apache.nifi.audit;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
 import org.apache.nifi.action.Action;
 import org.apache.nifi.action.Component;
 import org.apache.nifi.action.FlowChangeAction;
@@ -33,6 +30,10 @@ import org.aspectj.lang.annotation.Aspect;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
 /**
  * Audits configuration changes to the controller.
  */
@@ -42,112 +43,6 @@ public class ControllerAuditor extends NiFiAuditor {
     private static final Logger logger = 
LoggerFactory.getLogger(ControllerAuditor.class);
 
     /**
-     * Audits updating the name of the controller.
-     *
-     * @param proceedingJoinPoint join point
-     * @param name name
-     * @param controllerFacade facade
-     * @throws java.lang.Throwable ex
-     */
-    @Around("within(org.apache.nifi.web.controller.ControllerFacade) && "
-            + "execution(void setName(java.lang.String)) && "
-            + "args(name) && "
-            + "target(controllerFacade)")
-    public void updateControllerNameAdvice(ProceedingJoinPoint 
proceedingJoinPoint, String name, ControllerFacade controllerFacade) throws 
Throwable {
-        // get the previous name
-        String previousName = controllerFacade.getName();
-
-        // update the configuraion
-        proceedingJoinPoint.proceed();
-
-        // if no exception were thrown, add the configuration action...
-        // ensure the name changed
-        if (!name.equals(previousName)) {
-            // get the current user
-            NiFiUser user = NiFiUserUtils.getNiFiUser();
-
-            // ensure the user was found
-            if (user != null) {
-                Collection<Action> actions = new ArrayList<>();
-
-                // create the configuration details
-                FlowChangeConfigureDetails configDetails = new 
FlowChangeConfigureDetails();
-                configDetails.setName("Controller Name");
-                configDetails.setValue(name);
-                configDetails.setPreviousValue(previousName);
-
-                // create the config action
-                FlowChangeAction configAction = new FlowChangeAction();
-                configAction.setUserIdentity(user.getIdentity());
-                configAction.setUserName(user.getUserName());
-                configAction.setOperation(Operation.Configure);
-                configAction.setTimestamp(new Date());
-                configAction.setSourceId("Flow Controller");
-                configAction.setSourceName(controllerFacade.getName());
-                configAction.setSourceType(Component.Controller);
-                configAction.setActionDetails(configDetails);
-                actions.add(configAction);
-
-                // record the action
-                saveActions(actions, logger);
-            }
-        }
-    }
-
-    /**
-     * Audits updating the comments of the controller.
-     *
-     * @param proceedingJoinPoint join point
-     * @param comments comments
-     * @param controllerFacade facade
-     * @throws java.lang.Throwable ex
-     */
-    @Around("within(org.apache.nifi.web.controller.ControllerFacade) && "
-            + "execution(void setComments(java.lang.String)) && "
-            + "args(comments) && "
-            + "target(controllerFacade)")
-    public void updateControllerCommentsAdvice(ProceedingJoinPoint 
proceedingJoinPoint, String comments, ControllerFacade controllerFacade) throws 
Throwable {
-        // get the previous name
-        String previousComments = controllerFacade.getComments();
-
-        // update the configuraion
-        proceedingJoinPoint.proceed();
-
-        // if no exception were thrown, add the configuration action...
-        // ensure the name changed
-        if (!comments.equals(previousComments)) {
-            // get the current user
-            NiFiUser user = NiFiUserUtils.getNiFiUser();
-
-            // ensure the user was found
-            if (user != null) {
-                Collection<Action> actions = new ArrayList<>();
-
-                // create the configuration details
-                FlowChangeConfigureDetails configDetails = new 
FlowChangeConfigureDetails();
-                configDetails.setName("Controller Comments");
-                configDetails.setValue(comments);
-                configDetails.setPreviousValue(previousComments);
-
-                // create the config action
-                FlowChangeAction configAction = new FlowChangeAction();
-                configAction.setUserIdentity(user.getIdentity());
-                configAction.setUserName(user.getUserName());
-                configAction.setOperation(Operation.Configure);
-                configAction.setTimestamp(new Date());
-                configAction.setSourceId("Flow Controller");
-                configAction.setSourceName(controllerFacade.getName());
-                configAction.setSourceType(Component.Controller);
-                configAction.setActionDetails(configDetails);
-                actions.add(configAction);
-
-                // record the action
-                saveActions(actions, logger);
-            }
-        }
-    }
-
-    /**
      * Audits updating the max number of timer driven threads for the 
controller.
      *
      * @param proceedingJoinPoint joint point
@@ -189,7 +84,7 @@ public class ControllerAuditor extends NiFiAuditor {
                 configAction.setOperation(Operation.Configure);
                 configAction.setTimestamp(new Date());
                 configAction.setSourceId("Flow Controller");
-                configAction.setSourceName(controllerFacade.getName());
+                configAction.setSourceName("Flow Controller");
                 configAction.setSourceType(Component.Controller);
                 configAction.setActionDetails(configDetails);
                 actions.add(configAction);
@@ -242,7 +137,7 @@ public class ControllerAuditor extends NiFiAuditor {
                 configAction.setOperation(Operation.Configure);
                 configAction.setTimestamp(new Date());
                 configAction.setSourceId("Flow Controller");
-                configAction.setSourceName(controllerFacade.getName());
+                configAction.setSourceName("Flow Controller");
                 configAction.setSourceType(Component.Controller);
                 configAction.setActionDetails(configDetails);
                 actions.add(configAction);

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/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 f372812..c4dc34d 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
@@ -66,6 +66,7 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
+import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import 
org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
 import org.apache.nifi.web.api.entity.FlowEntity;
@@ -262,7 +263,7 @@ public interface NiFiServiceFacade {
      *
      * @return Controller configuration transfer object
      */
-    ControllerConfigurationDTO getControllerConfiguration();
+    ControllerConfigurationEntity getControllerConfiguration();
 
     /**
      * Updates the configuration for this controller.
@@ -271,7 +272,7 @@ public interface NiFiServiceFacade {
      * @param controllerConfigurationDTO Controller configuration DTO
      * @return Controller configuration DTO
      */
-    ConfigurationSnapshot<ControllerConfigurationDTO> 
updateControllerConfiguration(Revision revision, ControllerConfigurationDTO 
controllerConfigurationDTO);
+    ControllerConfigurationEntity updateControllerConfiguration(Revision 
revision, ControllerConfigurationDTO controllerConfigurationDTO);
 
     /**
      * Creates a new archive of the flow configuration.

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/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 cb44834..d4f235a 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
@@ -45,6 +45,7 @@ import org.apache.nifi.connectable.Funnel;
 import org.apache.nifi.connectable.Port;
 import org.apache.nifi.controller.ConfiguredComponent;
 import org.apache.nifi.controller.Counter;
+import org.apache.nifi.controller.FlowController;
 import org.apache.nifi.controller.ProcessorNode;
 import org.apache.nifi.controller.ReportingTaskNode;
 import org.apache.nifi.controller.ScheduledState;
@@ -67,7 +68,6 @@ import org.apache.nifi.remote.RootGroupPort;
 import org.apache.nifi.reporting.Bulletin;
 import org.apache.nifi.reporting.BulletinQuery;
 import org.apache.nifi.reporting.BulletinRepository;
-import org.apache.nifi.util.FormatUtils;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.api.dto.AccessPolicyDTO;
 import org.apache.nifi.web.api.dto.BulletinBoardDTO;
@@ -127,6 +127,7 @@ import 
org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
+import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import 
org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
 import 
org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
@@ -183,9 +184,7 @@ import java.util.ListIterator;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.TimeZone;
 import java.util.UUID;
-import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
@@ -886,32 +885,25 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
-    public ConfigurationSnapshot<ControllerConfigurationDTO> 
updateControllerConfiguration(final Revision revision, final 
ControllerConfigurationDTO controllerConfigurationDTO) {
-        final Supplier<ControllerConfigurationDTO> daoUpdate = () -> {
-            // update the controller configuration through the proxy
-            if (controllerConfigurationDTO.getName() != null) {
-                controllerFacade.setName(controllerConfigurationDTO.getName());
-            }
-            if (controllerConfigurationDTO.getComments() != null) {
-                
controllerFacade.setComments(controllerConfigurationDTO.getComments());
-            }
-            if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() != 
null) {
-                
controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount());
-            }
-            if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() != 
null) {
-                
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
-            }
-
-            return controllerConfigurationDTO;
-        };
-
+    public ControllerConfigurationEntity updateControllerConfiguration(final 
Revision revision, final ControllerConfigurationDTO controllerConfigurationDTO) 
{
         final RevisionUpdate<ControllerConfigurationDTO> updatedComponent = 
updateComponent(
             revision,
             controllerFacade,
-            daoUpdate,
-            controller -> getControllerConfiguration());
+            () -> {
+                if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() 
!= null) {
+                    
controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount());
+                }
+                if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() 
!= null) {
+                    
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
+                }
+
+                return controllerConfigurationDTO;
+            },
+            controller -> 
dtoFactory.createControllerConfigurationDto(controllerFacade, 
properties.getAutoRefreshInterval()));
 
-        return new 
ConfigurationSnapshot<>(updatedComponent.getLastModification().getRevision().getVersion());
+        final AccessPolicyDTO accessPolicy = 
dtoFactory.createAccessPolicyDto(controllerFacade);
+        final RevisionDTO updateRevision = 
dtoFactory.createRevisionDTO(updatedComponent.getLastModification());
+        return 
entityFactory.createControllerConfigurationEntity(updatedComponent.getComponent(),
 updateRevision, accessPolicy);
     }
 
     @Override
@@ -1266,9 +1258,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
      *
      * @return a RevisionUpdate that represents the updated configuration
      */
-    private <D, C> RevisionUpdate<D> createComponent(final ComponentDTO 
componentDto,
-        final Supplier<C> daoCreation, final Function<C, D> dtoCreation) {
-
+    private <D, C> RevisionUpdate<D> createComponent(final ComponentDTO 
componentDto, final Supplier<C> daoCreation, final Function<C, D> dtoCreation) {
         final String modifier = NiFiUserUtils.getNiFiUserName();
 
         // ensure id is set
@@ -1638,6 +1628,9 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
 
     @Override
     public ControllerServiceEntity createControllerService(final String 
groupId, final ControllerServiceDTO controllerServiceDTO) {
+        final String normalizedGroupId = groupId == null ? 
controllerFacade.getRootGroupId() : groupId;
+        controllerServiceDTO.setParentGroupId(normalizedGroupId);
+
         final RevisionUpdate<ControllerServiceDTO> snapshot = createComponent(
             controllerServiceDTO,
             () -> {
@@ -1645,7 +1638,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
                 final ControllerServiceNode controllerService = 
controllerServiceDAO.createControllerService(controllerServiceDTO);
 
                 // TODO - this logic should be part of the controllerServiceDAO
-                final ProcessGroup group = 
processGroupDAO.getProcessGroup(groupId);
+                final ProcessGroup group = 
processGroupDAO.getProcessGroup(normalizedGroupId);
                 group.addControllerService(controllerService);
                 return controllerService;
             },
@@ -2350,8 +2343,6 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final ControllerDTO controllerDTO = new ControllerDTO();
         controllerDTO.setId(controllerFacade.getRootGroupId());
         controllerDTO.setInstanceId(controllerFacade.getInstanceId());
-        controllerDTO.setName(controllerFacade.getName());
-        controllerDTO.setComments(controllerFacade.getComments());
         controllerDTO.setInputPorts(inputPortDtos);
         controllerDTO.setOutputPorts(outputPortDtos);
         controllerDTO.setInputPortCount(inputPorts.size());
@@ -2374,29 +2365,13 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
-    public ControllerConfigurationDTO getControllerConfiguration() {
-        ControllerConfigurationDTO controllerConfig = new 
ControllerConfigurationDTO();
-        controllerConfig.setName(controllerFacade.getName());
-        controllerConfig.setComments(controllerFacade.getComments());
-        
controllerConfig.setMaxTimerDrivenThreadCount(controllerFacade.getMaxTimerDrivenThreadCount());
-        
controllerConfig.setMaxEventDrivenThreadCount(controllerFacade.getMaxEventDrivenThreadCount());
-
-        // get the refresh interval
-        final long refreshInterval = 
FormatUtils.getTimeDuration(properties.getAutoRefreshInterval(), 
TimeUnit.SECONDS);
-        controllerConfig.setAutoRefreshIntervalSeconds(refreshInterval);
-
-        final Date now = new Date();
-        
controllerConfig.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime()));
-        controllerConfig.setCurrentTime(now);
-
-        // determine the site to site configuration
-        if (isClustered()) {
-            
controllerConfig.setSiteToSiteSecure(controllerFacade.isClusterManagerRemoteSiteCommsSecure());
-        } else {
-            
controllerConfig.setSiteToSiteSecure(controllerFacade.isRemoteSiteCommsSecure());
-        }
-
-        return controllerConfig;
+    public ControllerConfigurationEntity getControllerConfiguration() {
+        return revisionManager.get(FlowController.class.getSimpleName(), rev 
-> {
+            final ControllerConfigurationDTO dto = 
dtoFactory.createControllerConfigurationDto(controllerFacade, 
properties.getAutoRefreshInterval());
+            final AccessPolicyDTO accessPolicy = 
dtoFactory.createAccessPolicyDto(controllerFacade);
+            final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
+            return entityFactory.createControllerConfigurationEntity(dto, 
revision, accessPolicy);
+        });
     }
 
     @Override
@@ -2656,9 +2631,18 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     @Override
     public Set<ControllerServiceEntity> getControllerServices(String groupId) {
         // TODO - move this logic into the ControllerServiceDAO
-        final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
-        final Set<ControllerServiceNode> serviceNodes = 
group.getControllerServices(true);
-        final Set<String> serviceIds = serviceNodes.stream().map(service -> 
service.getIdentifier()).collect(Collectors.toSet());
+
+        final Set<ControllerServiceNode> serviceNodes;
+        final Set<String> serviceIds;
+        if (groupId == null) {
+            // TODO - controller services scoped by the controller
+            serviceNodes = controllerServiceDAO.getControllerServices();
+            serviceIds = serviceNodes.stream().map(service -> 
service.getIdentifier()).collect(Collectors.toSet());
+        } else {
+            final ProcessGroup group = 
processGroupDAO.getProcessGroup(groupId);
+            serviceNodes = group.getControllerServices(true);
+            serviceIds = serviceNodes.stream().map(service -> 
service.getIdentifier()).collect(Collectors.toSet());
+        }
 
         return revisionManager.get(serviceIds, () -> {
             return serviceNodes.stream()

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
index 695898e..59484a0 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
@@ -16,28 +16,21 @@
  */
 package org.apache.nifi.web.api;
 
-import java.net.URI;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-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 com.sun.jersey.api.core.ResourceContext;
+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.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.ResourceFactory;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
 import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
@@ -46,31 +39,40 @@ import 
org.apache.nifi.cluster.manager.exception.UnknownNodeException;
 import org.apache.nifi.cluster.manager.impl.WebClusterManager;
 import org.apache.nifi.cluster.node.Node;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
+import org.apache.nifi.controller.FlowController;
 import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.web.ConfigurationSnapshot;
 import org.apache.nifi.web.NiFiServiceFacade;
 import org.apache.nifi.web.Revision;
-import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
 import org.apache.nifi.web.api.dto.CounterDTO;
 import org.apache.nifi.web.api.dto.CountersDTO;
-import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.entity.AuthorityEntity;
 import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
+import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import org.apache.nifi.web.api.entity.CounterEntity;
 import org.apache.nifi.web.api.entity.CountersEntity;
 import org.apache.nifi.web.api.entity.Entity;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
-import org.apache.nifi.web.api.entity.ReportingTasksEntity;
-import org.apache.nifi.web.api.request.ClientIdParameter;
 
-import com.sun.jersey.api.core.ResourceContext;
-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.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 java.net.URI;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * RESTful endpoint for managing a Flow Controller.
@@ -85,13 +87,36 @@ public class ControllerResource extends ApplicationResource 
{
     private NiFiServiceFacade serviceFacade;
     private WebClusterManager clusterManager;
     private NiFiProperties properties;
+    private Authorizer authorizer;
 
     private ReportingTaskResource reportingTaskResource;
+    private ControllerServiceResource controllerServiceResource;
 
     @Context
     private ResourceContext resourceContext;
 
     /**
+     * Authorizes access to the flow.
+     */
+    private void authorizeController(final RequestAction action) {
+        final NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+        final AuthorizationRequest request = new AuthorizationRequest.Builder()
+                .resource(ResourceFactory.getControllerResource())
+                .identity(user.getIdentity())
+                .anonymous(user.isAnonymous())
+                .accessAttempt(true)
+                .action(action)
+                .build();
+
+        final AuthorizationResult result = authorizer.authorize(request);
+        if (!Result.Approved.equals(result.getResult())) {
+            final String message = 
StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : 
"Access is denied";
+            throw new AccessDeniedException(message);
+        }
+    }
+
+    /**
      * Creates a new archive of this flow controller. Note, this is a POST 
operation that returns a URI that is not representative of the thing that was 
actually created. The archive that is created
      * cannot be referenced at a later time, therefore there is no 
corresponding URI. Instead the request URI is returned.
      *
@@ -311,19 +336,15 @@ public class ControllerResource extends 
ApplicationResource {
             }
     )
     public Response getControllerConfig() {
+        // TODO
+//        authorizeController(RequestAction.READ);
 
         // replicate if cluster manager
         if (properties.isClusterManager()) {
             return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
         }
 
-        final ControllerConfigurationDTO controllerConfig = 
serviceFacade.getControllerConfiguration();
-
-        // create the response entity
-        final ControllerConfigurationEntity entity = new 
ControllerConfigurationEntity();
-        entity.setConfig(controllerConfig);
-
-        // generate the response
+        final ControllerConfigurationEntity entity = 
serviceFacade.getControllerConfiguration();
         return clusterContext(generateOkResponse(entity)).build();
     }
 
@@ -374,31 +395,19 @@ public class ControllerResource extends 
ApplicationResource {
             return clusterManager.applyRequest(HttpMethod.PUT, 
getAbsolutePath(), configEntity, getHeaders()).getResponse();
         }
 
-        final RevisionDTO revisionDto = configEntity.getRevision();
-        final Revision revision = new Revision(revisionDto.getVersion(), 
revisionDto.getClientId(), "controller");
-
-        // handle expects request (usually from the cluster manager)
-        final String expects = 
httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
-        if (expects != null) {
-            return generateContinueResponse().build();
-        }
-
-        final ConfigurationSnapshot<ControllerConfigurationDTO> 
controllerResponse
-            = serviceFacade.updateControllerConfiguration(revision, 
configEntity.getConfig());
-        final ControllerConfigurationDTO controllerConfig = 
controllerResponse.getConfiguration();
-
-        // get the updated revision
-        final RevisionDTO updatedRevision = new RevisionDTO();
-        updatedRevision.setClientId(revision.getClientId());
-        updatedRevision.setVersion(controllerResponse.getVersion());
-
-        // create the response entity
-        final ControllerConfigurationEntity entity = new 
ControllerConfigurationEntity();
-        entity.setRevision(updatedRevision);
-        entity.setConfig(controllerConfig);
-
-        // generate the response
-        return clusterContext(generateOkResponse(entity)).build();
+        final Revision revision = getRevision(configEntity.getRevision(), 
FlowController.class.getSimpleName());
+        return withWriteLock(
+                serviceFacade,
+                revision,
+                lookup -> {
+                    authorizeController(RequestAction.WRITE);
+                },
+                null,
+                () -> {
+                    final ControllerConfigurationEntity entity = 
serviceFacade.updateControllerConfiguration(revision, configEntity.getConfig());
+                    return clusterContext(generateOkResponse(entity)).build();
+                }
+        );
     }
 
     /**x
@@ -519,26 +528,27 @@ public class ControllerResource extends 
ApplicationResource {
         return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
     }
 
+    // -------------------
+    // controller services
+    // -------------------
+
     /**
-     * Retrieves all the of reporting tasks in this NiFi.
+     * Creates a new Controller Service.
      *
-     * @param clientId Optional client id. If the client id is not specified, a
-     * new one will be generated. This value (whether specified or generated) 
is
-     * included in the response.
-     * @return A reportingTasksEntity.
+     * @param httpServletRequest request
+     * @param controllerServiceEntity A controllerServiceEntity.
+     * @return A controllerServiceEntity.
      */
-    @GET
-    @Consumes(MediaType.WILDCARD)
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    @Path("reporting-tasks")
-    // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 
'ROLE_ADMIN')")
+    @Path("controller-services")
+    // TODO - @PreAuthorize("hasRole('ROLE_DFM')")
     @ApiOperation(
-        value = "Gets all reporting tasks",
-        response = ReportingTasksEntity.class,
+        value = "Creates a new controller service",
+        response = ControllerServiceEntity.class,
         authorizations = {
-            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
-            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
-            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
         }
     )
     @ApiResponses(
@@ -549,28 +559,50 @@ public class ControllerResource 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 getReportingTasks(
+    public Response createControllerService(
+        @Context final HttpServletRequest httpServletRequest,
         @ApiParam(
-            value = "If the client id is not specified, new one will be 
generated. This value (whether specified or generated) is included in the 
response.",
-            required = false
-        )
-        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) 
ClientIdParameter clientId) {
+            value = "The controller service configuration details.",
+            required = true
+        ) final ControllerServiceEntity controllerServiceEntity) {
+
+        if (controllerServiceEntity == null || 
controllerServiceEntity.getComponent() == null) {
+            throw new IllegalArgumentException("Controller service details 
must be specified.");
+        }
+
+        if (controllerServiceEntity.getComponent().getId() != null) {
+            throw new IllegalArgumentException("Controller service ID cannot 
be specified.");
+        }
+
+        if 
(StringUtils.isBlank(controllerServiceEntity.getComponent().getType())) {
+            throw new IllegalArgumentException("The type of controller service 
to create must be specified.");
+        }
 
-        // replicate if cluster manager
         if (properties.isClusterManager()) {
-            return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+            return clusterManager.applyRequest(HttpMethod.POST, 
getAbsolutePath(), controllerServiceEntity, getHeaders()).getResponse();
         }
 
-        // get all the reporting tasks
-        final Set<ReportingTaskEntity> reportingTasks = 
serviceFacade.getReportingTasks();
-        
reportingTaskResource.populateRemainingReportingTaskEntitiesContent(reportingTasks);
+        // handle expects request (usually from the cluster manager)
+        final boolean validationPhase = isValidationPhase(httpServletRequest);
+        if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
+            // authorize access
+            serviceFacade.authorizeAccess(lookup -> {
+                // TODO - authorize controller access
+            });
+        }
+        if (validationPhase) {
+            return generateContinueResponse().build();
+        }
 
-            // create the response entity
-        final ReportingTasksEntity entity = new ReportingTasksEntity();
-        entity.setReportingTasks(reportingTasks);
+        // set the processor id as appropriate
+        controllerServiceEntity.getComponent().setId(generateUuid());
 
-        // generate the response
-        return clusterContext(generateOkResponse(entity)).build();
+        // create the controller service and generate the json
+        final ControllerServiceEntity entity = 
serviceFacade.createControllerService(null, 
controllerServiceEntity.getComponent());
+        
controllerServiceResource.populateRemainingControllerServiceContent(entity.getComponent());
+
+        // build the response
+        return 
clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()),
 entity)).build();
     }
 
     // setters
@@ -586,8 +618,15 @@ public class ControllerResource extends 
ApplicationResource {
         this.reportingTaskResource = reportingTaskResource;
     }
 
+    public void setControllerServiceResource(ControllerServiceResource 
controllerServiceResource) {
+        this.controllerServiceResource = controllerServiceResource;
+    }
+
     public void setProperties(NiFiProperties properties) {
         this.properties = properties;
     }
 
+    public void setAuthorizer(Authorizer authorizer) {
+        this.authorizer = authorizer;
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
index e02dac5..a181a84 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
@@ -48,7 +48,6 @@ import org.apache.nifi.web.api.dto.AboutDTO;
 import org.apache.nifi.web.api.dto.BannerDTO;
 import org.apache.nifi.web.api.dto.BulletinBoardDTO;
 import org.apache.nifi.web.api.dto.BulletinQueryDTO;
-import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.dto.flow.FlowDTO;
@@ -81,7 +80,9 @@ import 
org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessorTypesEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
+import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity;
+import org.apache.nifi.web.api.entity.ReportingTasksEntity;
 import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
 import org.apache.nifi.web.api.entity.SearchResultsEntity;
 import org.apache.nifi.web.api.entity.StatusHistoryEntity;
@@ -141,6 +142,7 @@ public class FlowResource extends ApplicationResource {
     private TemplateResource templateResource;
     private ProcessGroupResource processGroupResource;
     private ControllerServiceResource controllerServiceResource;
+    private ReportingTaskResource reportingTaskResource;
 
     /**
      * Populates the remaining fields in the specified process group.
@@ -186,6 +188,9 @@ public class FlowResource extends ApplicationResource {
         return flowStructure;
     }
 
+    /**
+     * Authorizes access to the flow.
+     */
     private void authorizeFlow() {
         final NiFiUser user = NiFiUserUtils.getNiFiUser();
 
@@ -269,6 +274,56 @@ public class FlowResource extends ApplicationResource {
         return clusterContext(generateOkResponse(entity)).build();
     }
 
+    // -------------------
+    // controller services
+    // -------------------
+
+    /**
+     * Retrieves all the of controller services in this NiFi.
+     *
+     * @return A controllerServicesEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("controller/controller-services")
+    // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 
'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets all controller services",
+        response = ControllerServicesEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete 
the request because it was invalid. The request should not be retried without 
modification."),
+            @ApiResponse(code = 401, message = "Client could not be 
authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to 
make this request."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi 
was not in the appropriate state to process it. Retrying the same request later 
may be successful.")
+        }
+    )
+    public Response getControllerServicesFromController() {
+
+        // replicate if cluster manager
+        if (properties.isClusterManager()) {
+            return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+
+        // get all the controller services
+        final Set<ControllerServiceEntity> controllerServices = 
serviceFacade.getControllerServices(null);
+        
controllerServiceResource.populateRemainingControllerServiceEntitiesContent(controllerServices);
+
+        // create the response entity
+        final ControllerServicesEntity entity = new ControllerServicesEntity();
+        entity.setControllerServices(controllerServices);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
     /**
      * Retrieves all the of controller services in this NiFi.
      *
@@ -296,7 +351,7 @@ public class FlowResource 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 getControllerServices(
+    public Response getControllerServicesFromGroup(
         @ApiParam(
             value = "The process group id.",
             required = true
@@ -320,6 +375,64 @@ public class FlowResource extends ApplicationResource {
         return clusterContext(generateOkResponse(entity)).build();
     }
 
+    // ---------------
+    // reporting-tasks
+    // ---------------
+
+    /**
+     * Retrieves all the of reporting tasks in this NiFi.
+     *
+     * @param clientId Optional client id. If the client id is not specified, a
+     * new one will be generated. This value (whether specified or generated) 
is
+     * included in the response.
+     * @return A reportingTasksEntity.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("reporting-tasks")
+    // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 
'ROLE_ADMIN')")
+    @ApiOperation(
+        value = "Gets all reporting tasks",
+        response = ReportingTasksEntity.class,
+        authorizations = {
+            @Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+            @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+            @Authorization(value = "Administrator", type = "ROLE_ADMIN")
+        }
+    )
+    @ApiResponses(
+        value = {
+            @ApiResponse(code = 400, message = "NiFi was unable to complete 
the request because it was invalid. The request should not be retried without 
modification."),
+            @ApiResponse(code = 401, message = "Client could not be 
authenticated."),
+            @ApiResponse(code = 403, message = "Client is not authorized to 
make this request."),
+            @ApiResponse(code = 409, message = "The request was valid but NiFi 
was not in the appropriate state to process it. Retrying the same request later 
may be successful.")
+        }
+    )
+    public Response getReportingTasks(
+        @ApiParam(
+            value = "If the client id is not specified, new one will be 
generated. This value (whether specified or generated) is included in the 
response.",
+            required = false
+        )
+        @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) 
ClientIdParameter clientId) {
+
+        // replicate if cluster manager
+        if (properties.isClusterManager()) {
+            return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+
+        // get all the reporting tasks
+        final Set<ReportingTaskEntity> reportingTasks = 
serviceFacade.getReportingTasks();
+        
reportingTaskResource.populateRemainingReportingTaskEntitiesContent(reportingTasks);
+
+        // create the response entity
+        final ReportingTasksEntity entity = new ReportingTasksEntity();
+        entity.setReportingTasks(reportingTasks);
+
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+
     /**
      * Updates the specified process group.
      *
@@ -358,8 +471,6 @@ public class FlowResource extends ApplicationResource {
         @PathParam("id") String id,
         ScheduleComponentsEntity scheduleComponentsEntity) {
 
-        authorizeFlow();
-
         // ensure the same id is being used
         if (!id.equals(scheduleComponentsEntity.getId())) {
             throw new IllegalArgumentException(String.format("The process 
group id (%s) in the request body does "
@@ -441,6 +552,9 @@ public class FlowResource extends ApplicationResource {
             serviceFacade,
             revisions,
             lookup -> {
+                // ensure access to the flow
+                authorizeFlow();
+
                 // ensure access to every component being scheduled
                 componentsToSchedule.keySet().forEach(componentId -> {
                     final Authorizable connectable = 
lookup.getConnectable(componentId);
@@ -875,11 +989,9 @@ public class FlowResource extends ApplicationResource {
             return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
         }
 
-        final ControllerConfigurationDTO controllerConfig = 
serviceFacade.getControllerConfiguration();
-
         // create the about dto
         final AboutDTO aboutDTO = new AboutDTO();
-        aboutDTO.setTitle(controllerConfig.getName());
+        aboutDTO.setTitle("NiFi"); // TODO - where to load title from
         aboutDTO.setVersion(properties.getUiTitle());
         aboutDTO.setUri(generateResourceUri());
 
@@ -1853,6 +1965,10 @@ public class FlowResource extends ApplicationResource {
         this.controllerServiceResource = controllerServiceResource;
     }
 
+    public void setReportingTaskResource(ReportingTaskResource 
reportingTaskResource) {
+        this.reportingTaskResource = reportingTaskResource;
+    }
+
     public void setAuthorizer(Authorizer authorizer) {
         this.authorizer = authorizer;
     }

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/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 8c8b121..4e15e3b 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
@@ -134,6 +134,7 @@ import 
org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
 import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
+import org.apache.nifi.web.controller.ControllerFacade;
 import org.apache.nifi.web.revision.RevisionManager;
 
 import javax.ws.rs.WebApplicationException;
@@ -154,6 +155,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.TimeZone;
 import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
@@ -174,6 +176,22 @@ public final class DtoFactory {
     private EntityFactory entityFactory;
     private Authorizer authorizer;
 
+    public ControllerConfigurationDTO createControllerConfigurationDto(final 
ControllerFacade controllerFacade, final String autoRefreshInterval) {
+        final ControllerConfigurationDTO dto = new 
ControllerConfigurationDTO();
+        
dto.setMaxTimerDrivenThreadCount(controllerFacade.getMaxTimerDrivenThreadCount());
+        
dto.setMaxEventDrivenThreadCount(controllerFacade.getMaxEventDrivenThreadCount());
+
+        // get the refresh interval
+        final long refreshInterval = 
FormatUtils.getTimeDuration(autoRefreshInterval, TimeUnit.SECONDS);
+        dto.setAutoRefreshIntervalSeconds(refreshInterval);
+
+        final Date now = new Date();
+        dto.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime()));
+        dto.setCurrentTime(now);
+
+        return dto;
+    }
+
     /**
      * Creates an ActionDTO for the specified Action.
      *
@@ -1143,6 +1161,7 @@ public final class DtoFactory {
     public ControllerServiceDTO createControllerServiceDto(final 
ControllerServiceNode controllerServiceNode) {
         final ControllerServiceDTO dto = new ControllerServiceDTO();
         dto.setId(controllerServiceNode.getIdentifier());
+        dto.setParentGroupId(controllerServiceNode.getProcessGroup() == null ? 
null : controllerServiceNode.getProcessGroup().getIdentifier());
         dto.setName(controllerServiceNode.getName());
         
dto.setType(controllerServiceNode.getControllerServiceImplementation().getClass().getName());
         dto.setState(controllerServiceNode.getState().name());

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/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 70155a6..6677301 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
@@ -24,6 +24,7 @@ import 
org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
 import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
+import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import 
org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
 import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
@@ -40,6 +41,19 @@ import org.apache.nifi.web.api.entity.SnippetEntity;
 
 public final class EntityFactory {
 
+    public ControllerConfigurationEntity 
createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final 
RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
+        final ControllerConfigurationEntity entity = new 
ControllerConfigurationEntity();
+        entity.setRevision(revision);
+        if (dto != null) {
+            entity.setAccessPolicy(accessPolicy);
+            // TODO - remove this once contents of 
ControllerConfigurationEntity is updated
+//            if (accessPolicy != null && accessPolicy.getCanRead()) {
+                entity.setConfig(dto);
+//            }
+        }
+        return entity;
+    }
+
     public ProcessGroupFlowEntity createProcessGroupFlowEntity(final 
ProcessGroupFlowDTO dto, final AccessPolicyDTO accessPolicy) {
         final ProcessGroupFlowEntity entity = new ProcessGroupFlowEntity();
         entity.setProcessGroupFlow(dto);

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/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 99dfe6f..aceb693 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
@@ -177,6 +177,7 @@
         <property name="connectionResource" ref="connectionResource"/>
         <property name="templateResource" ref="templateResource"/>
         <property name="controllerServiceResource" 
ref="controllerServiceResource"/>
+        <property name="reportingTaskResource" ref="reportingTaskResource"/>
         <property name="processGroupResource" ref="processGroupResource"/>
     </bean>
     <bean id="resourceResource" 
class="org.apache.nifi.web.api.ResourceResource" scope="singleton">
@@ -190,6 +191,8 @@
         <property name="properties" ref="nifiProperties"/>
         <property name="clusterManager" ref="clusterManager"/>
         <property name="reportingTaskResource" ref="reportingTaskResource"/>
+        <property name="controllerServiceResource" 
ref="controllerServiceResource"/>
+        <property name="authorizer" ref="authorizer"/>
     </bean>
     <bean id="siteToSiteResource" 
class="org.apache.nifi.web.api.SiteToSiteResource" scope="singleton">
         <property name="serviceFacade" ref="serviceFacade"/>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AdminAccessControlTest.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AdminAccessControlTest.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AdminAccessControlTest.java
index 12693b2..7f61e0e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AdminAccessControlTest.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AdminAccessControlTest.java
@@ -184,7 +184,6 @@ public class AdminAccessControlTest {
         ControllerConfigurationEntity entity = 
response.getEntity(ControllerConfigurationEntity.class);
         Assert.assertNotNull(entity);
         Assert.assertNotNull(entity.getConfig());
-        Assert.assertEquals("NiFi Flow", entity.getConfig().getName());
         Assert.assertEquals(10, 
entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
         Assert.assertEquals(5, 
entity.getConfig().getMaxEventDrivenThreadCount().intValue());
         Assert.assertEquals(30, 
entity.getConfig().getAutoRefreshIntervalSeconds().intValue());

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/DfmAccessControlTest.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/DfmAccessControlTest.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/DfmAccessControlTest.java
index 83033f1..769c996 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/DfmAccessControlTest.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/DfmAccessControlTest.java
@@ -207,7 +207,6 @@ public class DfmAccessControlTest {
 
         // create the controller configuration
         ControllerConfigurationDTO controllerConfig = new 
ControllerConfigurationDTO();
-        controllerConfig.setName("new name");
 
         // create the revision
         final RevisionDTO revision = new RevisionDTO();
@@ -229,7 +228,6 @@ public class DfmAccessControlTest {
         entity = response.getEntity(ControllerConfigurationEntity.class);
         Assert.assertNotNull(entity);
         Assert.assertNotNull(entity.getConfig());
-        Assert.assertEquals("new name", entity.getConfig().getName());
         Assert.assertEquals(10, 
entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
         Assert.assertEquals(5, 
entity.getConfig().getMaxEventDrivenThreadCount().intValue());
         Assert.assertEquals(30, 
entity.getConfig().getAutoRefreshIntervalSeconds().intValue());

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ReadOnlyAccessControlTest.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ReadOnlyAccessControlTest.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ReadOnlyAccessControlTest.java
index 98a8cd0..d7e6a7a 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ReadOnlyAccessControlTest.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ReadOnlyAccessControlTest.java
@@ -180,7 +180,6 @@ public class ReadOnlyAccessControlTest {
         ControllerConfigurationEntity entity = 
response.getEntity(ControllerConfigurationEntity.class);
         Assert.assertNotNull(entity);
         Assert.assertNotNull(entity.getConfig());
-        Assert.assertEquals("NiFi Flow", entity.getConfig().getName());
         Assert.assertEquals(10, 
entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
         Assert.assertEquals(5, 
entity.getConfig().getMaxEventDrivenThreadCount().intValue());
         Assert.assertEquals(30, 
entity.getConfig().getAutoRefreshIntervalSeconds().intValue());

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index a2c4daa..9337b12 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -339,6 +339,7 @@
                                                 
<include>${staging.dir}/js/nf/canvas/nf-queue-listing.js</include>
                                                 
<include>${staging.dir}/js/nf/canvas/nf-component-state.js</include>
                                                 
<include>${staging.dir}/js/nf/canvas/nf-controller-service.js</include>
+                                                
<include>${staging.dir}/js/nf/canvas/nf-controller-services.js</include>
                                                 
<include>${staging.dir}/js/nf/canvas/nf-reporting-task.js</include>
                                                 
<include>${staging.dir}/js/nf/canvas/nf-processor-configuration.js</include>
                                                 
<include>${staging.dir}/js/nf/nf-processor-details.js</include>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
index cd58d9f..fc1f2c9 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
@@ -27,6 +27,7 @@ nf.canvas.script.tags=<script type="text/javascript" 
src="js/nf/nf-namespace.js?
 <script type="text/javascript" 
src="js/nf/canvas/nf-component-state.js?${project.version}"></script>\n\
 <script type="text/javascript" 
src="js/nf/canvas/nf-custom-ui.js?${project.version}"></script>\n\
 <script type="text/javascript" 
src="js/nf/canvas/nf-controller-service.js?${project.version}"></script>\n\
+<script type="text/javascript" 
src="js/nf/canvas/nf-controller-services.js?${project.version}"></script>\n\
 <script type="text/javascript" 
src="js/nf/canvas/nf-reporting-task.js?${project.version}"></script>\n\
 <script type="text/javascript" 
src="js/nf/canvas/nf-processor-configuration.js?${project.version}"></script>\n\
 <script type="text/javascript" 
src="js/nf/nf-processor-details.js?${project.version}"></script>\n\

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
index 23a514a..c74a945 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
@@ -83,6 +83,12 @@
         <div class="graph-control-content hidden">
             <div id="operation-buttons">
                 <div>
+                    <div id="operate-configure" class="action-button" 
title="Configuration">
+                        <button 
ng-click="appCtrl.nf.Actions['showConfiguration'](appCtrl.nf.CanvasUtils.getSelection());"
+                                ng-disabled="false">
+                            <i class="graph-control-action-icon fa 
fa-gear"></i></button>
+                    </div>
+                    <div class="button-spacer-large">&nbsp;</div>
                     <div id="operate-enable" class="action-button" 
title="Enable">
                         <button 
ng-click="appCtrl.nf.Actions['enable'](appCtrl.nf.CanvasUtils.getSelection());"
                                 
ng-disabled="!appCtrl.nf.CanvasUtils.canEnable(appCtrl.nf.CanvasUtils.getSelection());">
@@ -112,7 +118,9 @@
                                 ng-disabled="!(appCtrl.nf.Canvas.canWrite() && 
(appCtrl.nf.CanvasUtils.getSelection().empty() || 
appCtrl.nf.CanvasUtils.canRead(appCtrl.nf.CanvasUtils.getSelection())));">
                             <i class="graph-control-action-icon icon 
icon-template"></i></button>
                     </div>
-                    <div class="button-spacer-large">&nbsp;</div>
+                    <div class="clear"></div>
+                </div>
+                <div style="margin-top: 5px;">
                     <div id="operate-copy" class="action-button" title="Copy">
                         <button 
ng-click="appCtrl.nf.Actions['copy'](appCtrl.nf.CanvasUtils.getSelection());"
                                 
ng-disabled="!appCtrl.nf.CanvasUtils.isCopyable(appCtrl.nf.CanvasUtils.getSelection())
 || !appCtrl.nf.CanvasUtils.canRead(appCtrl.nf.CanvasUtils.getSelection());">
@@ -124,9 +132,7 @@
                                 ng-disabled="!appCtrl.nf.Clipboard.isCopied()">
                             <i class="graph-control-action-icon fa 
fa-paste"></i></button>
                     </div>
-                    <div class="clear"></div>
-                </div>
-                <div style="margin-top: 5px;">
+                    <div class="button-spacer-large">&nbsp;</div>
                     <div id="operate-group" class="action-button" 
title="Group">
                         <button 
ng-click="appCtrl.nf.Actions['group'](appCtrl.nf.CanvasUtils.getSelection());"
                                 
ng-disabled="!appCtrl.nf.CanvasUtils.isDisconnected(appCtrl.nf.CanvasUtils.getSelection())
 || !appCtrl.nf.CanvasUtils.canModify(appCtrl.nf.CanvasUtils.getSelection());">

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
index 55bf745..f8e8126 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/process-group-configuration.jsp
@@ -15,24 +15,49 @@
   limitations under the License.
 --%>
 <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
-<div id="process-group-configuration" nf-draggable="{containment: 'parent', 
handle: '.dialog-header'}">
-    <div class="dialog-content">
-        <div class="setting">
-            <div class="setting-name">Name</div>
-            <div class="setting-field">
-                <input type="text" id="process-group-name" 
name="process-group-name" class="process-group-field"/>
+<div id="process-group-configuration">
+    <div id="process-group-configuration-header-text" 
class="settings-header-text">Process Group Configuration</div>
+    <div class="settings-container">
+        <div class="settings-tabs-container">
+            <div id="process-group-configuration-tabs" 
class="settings-tabs"></div>
+            <div id="process-group-configuration-refresh-button" 
class="pointer settings-refresh-button" title="Refresh"></div>
+            <div class="settings-last-refreshed-container">
+                Last updated:&nbsp;<span 
id="process-group-configuration-last-refreshed"></span>
             </div>
+            <div id="process-group-configuration-loading-container" 
class="loading-container"></div>
+            <div id="add-process-group-configuration-controller-service" 
class="add-icon-bg"></div>
+            <div class="clear"></div>
         </div>
-        <div class="setting">
-            <div class="setting-name">Id</div>
-            <div class="setting-field">
-                <span id="process-group-id"></span>
+        <div class="settings-tab-background"></div>
+        <div>
+            <div id="general-process-group-configuration-tab-content" 
class="configuration-tab">
+                <div id="general-process-group-configuration">
+                    <div class="setting">
+                        <div class="setting-name">Process group name</div>
+                        <div class="editable setting-field">
+                            <input type="text" id="process-group-name" 
class="setting-input"/>
+                        </div>
+                        <div class="read-only setting-field">
+                            <span id="read-only-process-group-name"></span>
+                        </div>
+                    </div>
+                    <div class="setting">
+                        <div class="setting-name">Process group comments</div>
+                        <div class="editable setting-field">
+                            <textarea id="process-group-comments" 
class="setting-input"></textarea>
+                        </div>
+                        <div class="read-only setting-field">
+                            <span id="read-only-process-group-comments"></span>
+                        </div>
+                    </div>
+                    <div class="editable settings-buttons">
+                        <div id="process-group-configuration-save" 
class="button">Apply</div>
+                        <div class="clear"></div>
+                    </div>
+                </div>
             </div>
-        </div>
-        <div class="setting">
-            <div class="setting-name">Comments</div>
-            <div class="setting-field">
-                <textarea cols="30" rows="4" id="process-group-comments" 
name="process-group-comments" class="process-group-field"></textarea>
+            <div id="process-group-controller-services-tab-content" 
class="configuration-tab">
+                <div id="process-group-controller-services-table" 
class="settings-table"></div>
             </div>
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/settings-content.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/settings-content.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/settings-content.jsp
index 67e61de..94515cb 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/settings-content.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/settings-content.jsp
@@ -16,50 +16,31 @@
 --%>
 <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
 <div id="settings">
-    <div id="settings-header-text">NiFi Settings</div>
-    <div id="settings-container">
-        <div id="settings-tabs-container">
-            <div id="settings-tabs"></div>
-            <div id="settings-refresh-button" class="pointer" 
title="Refresh"></div>
-            <div id="settings-last-refreshed-container">
+    <div id="settings-header-text" class="settings-header-text">NiFi 
Settings</div>
+    <div class="settings-container">
+        <div class="settings-tabs-container">
+            <div id="settings-tabs" class="settings-tabs"></div>
+            <div id="settings-refresh-button" class="pointer 
settings-refresh-button" title="Refresh"></div>
+            <div class="settings-last-refreshed-container">
                 Last updated:&nbsp;<span id="settings-last-refreshed"></span>
             </div>
-            <div id="settings-refresh-required-icon" class="hidden"></div>
             <div id="settings-loading-container" 
class="loading-container"></div>
             <div id="new-service-or-task" class="add-icon-bg"></div>
             <div class="clear"></div>
         </div>
-        <div id="settings-tab-background"></div>
-        <div id="settings-tabs-content">
+        <div class="settings-tab-background"></div>
+        <div>
             <div id="general-settings-tab-content" class="configuration-tab">
                 <div id="general-settings">
                     <div class="setting">
-                        <div class="setting-name">Data flow name</div>
-                        <div class="editable setting-field">
-                            <input type="text" id="data-flow-title-field" 
name="data-flow-title" class="setting-input"/>
-                            <span id="archive-flow-link" class="link">Back-up 
flow</span>
-                            <img class="setting-icon icon-info" 
src="images/iconInfo.png" alt="Info" title="Archives the flow configuration."/>
-                        </div>
-                        <div class="read-only setting-field">
-                            <span id="read-only-data-flow-title-field"></span>
-                        </div>
-                    </div>
-                    <div class="setting">
-                        <div class="setting-name">Data flow comments</div>
-                        <div class="editable setting-field">
-                            <textarea id="data-flow-comments-field" 
name="data-flow-comments" class="setting-input"></textarea>
-                        </div>
-                        <div class="read-only setting-field">
-                            <span 
id="read-only-data-flow-comments-field"></span>
-                        </div>
-                    </div>
-                    <div class="setting">
                         <div class="setting-name">
                             Maximum timer driven thread count
                             <img class="setting-icon icon-info" 
src="images/iconInfo.png" alt="Info" title="The maximum number of threads for 
timer driven processors available to the system."/>
                         </div>
                         <div class="editable setting-field">
                             <input type="text" 
id="maximum-timer-driven-thread-count-field" class="setting-input"/>
+                            <span id="archive-flow-link" class="link">Back-up 
flow</span>
+                            <img class="setting-icon icon-info" 
src="images/iconInfo.png" alt="Info" title="Archives the flow configuration."/>
                         </div>
                         <div class="read-only setting-field">
                             <span 
id="read-only-maximum-timer-driven-thread-count-field"></span>
@@ -77,7 +58,7 @@
                             <span 
id="read-only-maximum-event-driven-thread-count-field"></span>
                         </div>
                     </div>
-                    <div id="settings-buttons" class="editable">
+                    <div class="editable settings-buttons">
                         <div id="settings-save" class="button">Apply</div>
                         <div class="clear"></div>
                     </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/flow-status.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/flow-status.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/flow-status.css
index 4f99055..fcfd5a2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/flow-status.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/flow-status.css
@@ -14,11 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 /* flow status styles positioned at the top of the graph */
 
 #flow-status {
-    height: 32px;
+    height: 33px;
     background-color: #E3E8EB; /*tint base-color 60%*/
+    border-bottom: 1px solid #aabbc3;
+    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
+    z-index: 3;
+    position: relative;
 }
 
 #flow-status .icon {

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
index 958eb05..9ae72be 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
@@ -24,6 +24,7 @@
     left: 0px;
     bottom: 0px;
     right: 0px;
+    background-color: #f9fafb;
     background-size: 14px 14px;
     background-image: linear-gradient(to right, rgba(229, 235, 237, 1) 1px, 
transparent 1px), linear-gradient(to bottom, rgba(229, 235, 237, 1) 1px, 
transparent 1px);
     z-index: 1;
@@ -64,6 +65,11 @@ g.component rect.body.unauthorized {
     fill: #f4f6f7;
 }
 
+g.component rect.border {
+    stroke: rgba(0,0,0,0.25);
+    stroke-width: 1;
+}
+
 g.component rect.border.unauthorized {
     stroke-width: 1.5;
     stroke: #ba554a;

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
index 783600e..664f930 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
@@ -23,11 +23,15 @@ md-toolbar.md-small {
     height: 56px;
     background-color:#AABBC3; /*tint base-color 40%*/
     min-height: 56px;
-    max-height: 56px; }
+    max-height: 56px;
+    position: relative;
+    z-index: 4;
+}
 md-toolbar.md-small .md-toolbar-tools {
     height: 56px;
     min-height: 56px;
-    max-height: 56px; }
+    max-height: 56px;
+}
 
 #header .icon {
     font-size:30px;

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
index 4d943c5..1c601bb 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
@@ -55,12 +55,11 @@
 }
 
 div.graph-control {
-    background-color: rgba(249, 250, 251, 0.97); /*tint base-color 96%*/
-    border-top: 1px solid #C7D2D7; /*tint base-color 60%*/
-    border-right: 1px solid #C7D2D7; /*tint base-color 60%*/
-    border-bottom: 1px solid #C7D2D7; /*tint base-color 60%*/
-    border-top-right-radius: 2px;
-    border-bottom-right-radius: 2px;
+    box-shadow: 0 1px 6px rgba(0,0,0,0.25);
+    background-color: rgba(249, 250, 251, 0.9);
+    border-top: 1px solid #aabbc3;
+    border-right: 1px solid #aabbc3;
+    border-bottom: 1px solid #aabbc3;
     padding: 10px;
     margin-bottom: 2px;
 }
@@ -75,9 +74,8 @@ div.graph-control button {
     height: 24px;
     width: 24px;
     line-height: 19px;
-    border-radius: 2px;
     border: 1px solid #CCDADB; /*tint link-color 80%*/
-    background-color: rgba(249, 250, 251, 0.97);
+    background-color: rgba(249,250,251,1);
     color: #004849;
 }
 
@@ -186,8 +184,9 @@ rect.birdseye-brush {
 #breadcrumbs {
     position: absolute;
     bottom: 0px;
-    background-color: rgba(249, 250, 251, 0.97); /*tint base-color 96%*/
-    border-top: 1px solid #C7D2D7; /*tint base-color 60%*/
+    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
+    background-color: rgba(249, 250, 251, 0.9);
+    border-top: 1px solid #aabbc3;
     color: #598599;
     z-index: 3;
     height: 31px;

Reply via email to