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"> </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"> </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"> </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: <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: <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;
