NIFI-1781: - Including access policies in the breadcrumb's trail. - Updating toolbox according to group access policies. - Updating actions in palette based on selection access policies. NIFI-1554: - Introducing authorization during two phase commit. - Introducing snippet authorization according to the encapsulated components and the action performed. - This closes #461
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/4dd50c80 Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/4dd50c80 Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/4dd50c80 Branch: refs/heads/master Commit: 4dd50c80a4fe086d94998c8e7738dcf149734a84 Parents: d42ea46 Author: Matt Gilman <matt.c.gil...@gmail.com> Authored: Mon May 23 14:14:22 2016 -0400 Committer: Matt Gilman <matt.c.gil...@gmail.com> Committed: Mon May 23 14:15:32 2016 -0400 ---------------------------------------------------------------------- .../org/apache/nifi/controller/Snippet.java | 12 +- .../nifi/web/api/dto/ProcessGroupDTO.java | 15 - .../org/apache/nifi/web/api/dto/SnippetDTO.java | 17 - .../web/api/dto/flow/FlowBreadcrumbDTO.java | 17 - .../apache/nifi/web/api/dto/flow/FlowDTO.java | 15 - .../web/api/dto/flow/ProcessGroupFlowDTO.java | 7 +- .../web/api/entity/FlowBreadcrumbEntity.java | 99 +++ .../web/api/entity/ProcessGroupFlowEntity.java | 19 + .../api/entity/ScheduleComponentsEntity.java | 77 ++ .../nifi/web/api/entity/SnippetEntity.java | 7 +- .../nifi/controller/ConfiguredComponent.java | 3 +- .../nifi/controller/ReportingTaskNode.java | 9 +- .../service/ControllerServiceNode.java | 9 +- .../org/apache/nifi/groups/ProcessGroup.java | 34 +- .../apache/nifi/controller/StandardSnippet.java | 14 - .../nifi/groups/StandardProcessGroup.java | 92 +- .../service/mock/MockProcessGroup.java | 7 + .../apache/nifi/audit/ProcessGroupAuditor.java | 73 +- .../org/apache/nifi/audit/SnippetAuditor.java | 157 ++-- .../org/apache/nifi/web/AuthorizableLookup.java | 154 ++++ .../org/apache/nifi/web/AuthorizeAccess.java | 21 + .../org/apache/nifi/web/NiFiServiceFacade.java | 106 ++- .../nifi/web/StandardNiFiServiceFacade.java | 513 ++++++------ .../nifi/web/api/ApplicationResource.java | 187 ++++- .../apache/nifi/web/api/ConnectionResource.java | 155 ++-- .../nifi/web/api/ControllerServiceResource.java | 195 +++-- .../nifi/web/api/FlowFileQueueResource.java | 159 ++-- .../org/apache/nifi/web/api/FlowResource.java | 209 ++++- .../org/apache/nifi/web/api/FunnelResource.java | 153 ++-- .../apache/nifi/web/api/InputPortResource.java | 139 ++-- .../org/apache/nifi/web/api/LabelResource.java | 143 ++-- .../apache/nifi/web/api/OutputPortResource.java | 151 ++-- .../nifi/web/api/ProcessGroupResource.java | 833 ++++++++----------- .../apache/nifi/web/api/ProcessorResource.java | 154 ++-- .../apache/nifi/web/api/ProvenanceResource.java | 158 ++-- .../web/api/RemoteProcessGroupResource.java | 319 ++++--- .../nifi/web/api/ReportingTaskResource.java | 137 +-- .../apache/nifi/web/api/ResourceResource.java | 35 + .../apache/nifi/web/api/SnippetResource.java | 327 ++++++++ .../nifi/web/api/SystemDiagnosticsResource.java | 33 +- .../apache/nifi/web/api/TemplateResource.java | 37 +- .../org/apache/nifi/web/api/dto/DtoFactory.java | 59 +- .../apache/nifi/web/api/dto/EntityFactory.java | 35 +- .../apache/nifi/web/dao/ProcessGroupDAO.java | 14 +- .../org/apache/nifi/web/dao/SnippetDAO.java | 23 +- .../web/dao/impl/StandardProcessGroupDAO.java | 66 +- .../nifi/web/dao/impl/StandardSnippetDAO.java | 98 +-- .../src/main/resources/nifi-web-api-context.xml | 19 + .../accesscontrol/DfmAccessControlTest.java | 1 - .../nifi/web/revision/NaiveRevisionManager.java | 8 +- .../WEB-INF/partials/canvas/canvas-header.jsp | 8 + .../WEB-INF/partials/canvas/navigation.jsp | 20 +- .../src/main/webapp/css/navigation.css | 1 + .../controllers/nf-ng-breadcrumbs-controller.js | 18 +- .../src/main/webapp/js/nf/canvas/nf-actions.js | 64 +- .../main/webapp/js/nf/canvas/nf-canvas-utils.js | 57 +- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 17 + .../main/webapp/js/nf/canvas/nf-context-menu.js | 2 +- .../js/nf/canvas/nf-processor-configuration.js | 2 +- .../js/nf/canvas/nf-remote-process-group.js | 4 +- .../src/main/webapp/js/nf/canvas/nf-snippet.js | 73 +- .../main/webapp/js/nf/nf-connection-details.js | 2 +- .../main/webapp/js/nf/nf-processor-details.js | 2 +- .../views/nf-ng-breadcrumbs-directive-view.html | 2 +- 64 files changed, 3397 insertions(+), 2199 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java b/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java index 5fad824..702b7cd 100644 --- a/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java +++ b/nifi-api/src/main/java/org/apache/nifi/controller/Snippet.java @@ -16,10 +16,10 @@ */ package org.apache.nifi.controller; -import java.util.Map; - import org.apache.nifi.web.Revision; +import java.util.Map; + /** * A Snippet represents a segment of the flow */ @@ -31,14 +31,6 @@ public interface Snippet { public String getId(); /** - * @return Whether or not this snippet is linked to the data flow. If the Snippet is - * deleted and is linked, then the underlying components will also be - * deleted. If the Snippet is deleted and is NOT linked, only the Snippet is - * removed - */ - public boolean isLinked(); - - /** * @return parent group id of the components in this snippet */ public String getParentGroupId(); http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java index 224db57..dd18cc4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessGroupDTO.java @@ -27,7 +27,6 @@ public class ProcessGroupDTO extends ComponentDTO { private String name; private String comments; - private Boolean running; private Integer runningCount; private Integer stoppedCount; @@ -132,20 +131,6 @@ public class ProcessGroupDTO extends ComponentDTO { } /** - * @return Used in requests, indicates whether this process group should be running - */ - @ApiModelProperty( - value = "Used in requests, indicates whether the process group should be running." - ) - public Boolean isRunning() { - return running; - } - - public void setRunning(Boolean running) { - this.running = running; - } - - /** * @return number of running component in this process group */ @ApiModelProperty( http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java index 8362c18..a617cf9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SnippetDTO.java @@ -32,7 +32,6 @@ public class SnippetDTO { private String id; private String uri; private String parentGroupId; - private Boolean linked; // when specified these are only considered during creation private Map<String, RevisionDTO> processGroups = new HashMap<>(); @@ -87,22 +86,6 @@ public class SnippetDTO { } /** - * @return whether or not this snippet is linked to the underlying data flow - */ - @ApiModelProperty( - value = "Whether or not the snippet is linked to the underlying data flow. For instance if linked was set to true and the snippet was deleted " - + "it would also deleted the components in the snippet. If the snippet was not linked, deleting the snippet would only remove the " - + "snippet and leave the component intact." - ) - public Boolean isLinked() { - return linked; - } - - public void setLinked(Boolean linked) { - this.linked = linked; - } - - /** * @return the ids of the connections in this snippet. These ids will be populated within each response. They can be specified when creating a snippet. However, once a snippet has been created its * contents cannot be modified (these ids are ignored during update requests) */ http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java index afdfb64..a6f12d7 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java @@ -28,7 +28,6 @@ public class FlowBreadcrumbDTO { private String id; private String name; - private FlowBreadcrumbDTO parentBreadcrumb; /** * The id for this group. @@ -61,20 +60,4 @@ public class FlowBreadcrumbDTO { public void setName(final String name) { this.name = name; } - - /** - * The parent breadcrumb for this breadcrumb. - * - * @return The parent breadcrumb for this breadcrumb - */ - @ApiModelProperty( - value = "The parent breadcrumb for this breadcrumb." - ) - public FlowBreadcrumbDTO getParentBreadcrumb() { - return parentBreadcrumb; - } - - public void setParentBreadcrumb(FlowBreadcrumbDTO parentBreadcrumb) { - this.parentBreadcrumb = parentBreadcrumb; - } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java index a3a3ae7..557d72f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowDTO.java @@ -18,7 +18,6 @@ package org.apache.nifi.web.api.dto.flow; import com.wordnik.swagger.annotations.ApiModelProperty; import org.apache.nifi.web.api.entity.ConnectionEntity; -import org.apache.nifi.web.api.entity.ControllerServiceEntity; import org.apache.nifi.web.api.entity.FunnelEntity; import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.PortEntity; @@ -44,7 +43,6 @@ public class FlowDTO { private Set<ConnectionEntity> connections = new LinkedHashSet<>(); private Set<LabelEntity> labels = new LinkedHashSet<>(); private Set<FunnelEntity> funnels = new LinkedHashSet<>(); - private Set<ControllerServiceEntity> controllerServices = new LinkedHashSet<>(); /** * @return connections in this flow @@ -158,17 +156,4 @@ public class FlowDTO { this.remoteProcessGroups = remoteProcessGroups; } - /** - * @return the Controller Services in this flow - */ - @ApiModelProperty( - value = "The controller services in this flow." - ) - public Set<ControllerServiceEntity> getControllerServices() { - return controllerServices; - } - - public void setControllerServices(Set<ControllerServiceEntity> controllerServices) { - this.controllerServices = controllerServices; - } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java index 3970d63..ce5d1e0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/ProcessGroupFlowDTO.java @@ -18,6 +18,7 @@ package org.apache.nifi.web.api.dto.flow; import com.wordnik.swagger.annotations.ApiModelProperty; import org.apache.nifi.web.api.dto.util.TimeAdapter; +import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @@ -32,7 +33,7 @@ public class ProcessGroupFlowDTO { private String id; private String uri; private String parentGroupId; - private FlowBreadcrumbDTO breadcrumb; + private FlowBreadcrumbEntity breadcrumb; private FlowDTO flow; private Date lastRefreshed; @@ -74,11 +75,11 @@ public class ProcessGroupFlowDTO { @ApiModelProperty( value = "The breadcrumb of the process group." ) - public FlowBreadcrumbDTO getBreadcrumb() { + public FlowBreadcrumbEntity getBreadcrumb() { return breadcrumb; } - public void setBreadcrumb(FlowBreadcrumbDTO breadcrumb) { + public void setBreadcrumb(FlowBreadcrumbEntity breadcrumb) { this.breadcrumb = breadcrumb; } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java new file mode 100644 index 0000000..ddd8407 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/FlowBreadcrumbEntity.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.AccessPolicyDTO; +import org.apache.nifi.web.api.dto.flow.FlowBreadcrumbDTO; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a FlowBreadcrumbDTO. + */ +@XmlRootElement(name = "flowEntity") +public class FlowBreadcrumbEntity extends Entity { + + private String id; + private AccessPolicyDTO accessPolicy; + private FlowBreadcrumbDTO breadcrumb; + private FlowBreadcrumbEntity parentBreadcrumb; + + /** + * The id for this ancestor ProcessGroup. + * + * @return The id + */ + @ApiModelProperty( + value = "The id of this ancestor ProcessGroup." + ) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * The access policy for this ancestor ProcessGroup. + * + * @return The access policy + */ + @ApiModelProperty( + value = "The access policy for this ancestor ProcessGroup." + ) + public AccessPolicyDTO getAccessPolicy() { + return accessPolicy; + } + + public void setAccessPolicy(AccessPolicyDTO accessPolicy) { + this.accessPolicy = accessPolicy; + } + + /** + * The FlowBreadcrumbDTO that is being serialized. + * + * @return The FlowBreadcrumbDTO object + */ + @ApiModelProperty( + value = "This breadcrumb." + ) + public FlowBreadcrumbDTO getBreadcrumb() { + return breadcrumb; + } + + public void setBreadcrumb(FlowBreadcrumbDTO breadcrumb) { + this.breadcrumb = breadcrumb; + } + + /** + * The parent breadcrumb for this breadcrumb. + * + * @return The parent breadcrumb for this breadcrumb + */ + @ApiModelProperty( + value = "The parent breadcrumb for this breadcrumb." + ) + public FlowBreadcrumbEntity getParentBreadcrumb() { + return parentBreadcrumb; + } + + public void setParentBreadcrumb(FlowBreadcrumbEntity parentBreadcrumb) { + this.parentBreadcrumb = parentBreadcrumb; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java index 8ab1327..8dd3b05 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessGroupFlowEntity.java @@ -16,6 +16,8 @@ */ package org.apache.nifi.web.api.entity; +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.AccessPolicyDTO; import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO; import javax.xml.bind.annotation.XmlRootElement; @@ -26,9 +28,26 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "processGroupFlowEntity") public class ProcessGroupFlowEntity extends Entity { + private AccessPolicyDTO accessPolicy; private ProcessGroupFlowDTO processGroupFlow; /** + * The access policy for this component. + * + * @return The access policy + */ + @ApiModelProperty( + value = "The access policy for this process group." + ) + public AccessPolicyDTO getAccessPolicy() { + return accessPolicy; + } + + public void setAccessPolicy(AccessPolicyDTO accessPolicy) { + this.accessPolicy = accessPolicy; + } + + /** * The ProcessGroupFlowDTO that is being serialized. * * @return The ProcessGroupFlowDTO object http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java new file mode 100644 index 0000000..9aeef40 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ScheduleComponentsEntity.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.api.entity; + +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.RevisionDTO; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +/** + * A serialized representation of this class can be placed in the entity body of a request to the API. + */ +@XmlRootElement(name = "scheduleComponentEntity") +public class ScheduleComponentsEntity extends Entity { + + private String id; + private String state; + private Map<String, RevisionDTO> components; + + /** + * @return The id of the ProcessGroup + */ + @ApiModelProperty( + value = "The id of the ProcessGroup" + ) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * @return The desired state of the descendant components. Possible states are 'RUNNING' and 'STOPPED' + */ + @ApiModelProperty( + value = "The desired state of the descendant components", + allowableValues = "RUNNING, STOPPED" + ) + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + /** + * @return The components to schedule. If not specified, all authorized descendant components will be used. + */ + @ApiModelProperty( + value = "Optional components to schedule. If not specified, all authorized descendant components will be used." + ) + public Map<String, RevisionDTO> getComponents() { + return components; + } + + public void setComponents(Map<String, RevisionDTO> components) { + this.components = components; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java index 205dc17..7ec8de6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SnippetEntity.java @@ -16,14 +16,16 @@ */ package org.apache.nifi.web.api.entity; -import javax.xml.bind.annotation.XmlRootElement; +import com.wordnik.swagger.annotations.ApiModelProperty; import org.apache.nifi.web.api.dto.SnippetDTO; +import javax.xml.bind.annotation.XmlRootElement; + /** * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a SnippetDTO. */ @XmlRootElement(name = "snippetEntity") -public class SnippetEntity extends ComponentEntity { +public class SnippetEntity extends Entity { private SnippetDTO snippet; @@ -32,6 +34,7 @@ public class SnippetEntity extends ComponentEntity { * * @return The SnippetDTO object */ + @ApiModelProperty("The snippet.") public SnippetDTO getSnippet() { return snippet; } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java index 0fcccdd..d053466 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ConfiguredComponent.java @@ -19,10 +19,11 @@ package org.apache.nifi.controller; import java.util.Collection; import java.util.Map; +import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.ValidationResult; -public interface ConfiguredComponent { +public interface ConfiguredComponent extends Authorizable { public String getIdentifier(); http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java index a230bcb..28e848f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/ReportingTaskNode.java @@ -16,16 +16,15 @@ */ package org.apache.nifi.controller; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.reporting.ReportingContext; import org.apache.nifi.reporting.ReportingTask; import org.apache.nifi.scheduling.SchedulingStrategy; -public interface ReportingTaskNode extends ConfiguredComponent, Authorizable { +import java.util.Set; +import java.util.concurrent.TimeUnit; + +public interface ReportingTaskNode extends ConfiguredComponent { void setSchedulingStrategy(SchedulingStrategy schedulingStrategy); http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java index 710a771..bd3a42b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java @@ -16,15 +16,14 @@ */ package org.apache.nifi.controller.service; -import java.util.Set; -import java.util.concurrent.ScheduledExecutorService; - -import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.controller.ConfiguredComponent; import org.apache.nifi.controller.ControllerService; import org.apache.nifi.groups.ProcessGroup; -public interface ControllerServiceNode extends ConfiguredComponent, Authorizable { +import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; + +public interface ControllerServiceNode extends ConfiguredComponent { /** * @return the Process Group that this Controller Service belongs to, or <code>null</code> if the Controller Service http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java index c3a4c8e..8d026f0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java @@ -16,10 +16,6 @@ */ package org.apache.nifi.groups; -import java.util.Collection; -import java.util.List; -import java.util.Set; - import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.connectable.Connectable; import org.apache.nifi.connectable.Connection; @@ -27,6 +23,7 @@ import org.apache.nifi.connectable.Funnel; import org.apache.nifi.connectable.Port; import org.apache.nifi.connectable.Position; import org.apache.nifi.controller.ProcessorNode; +import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.Snippet; import org.apache.nifi.controller.Template; import org.apache.nifi.controller.label.Label; @@ -34,6 +31,11 @@ import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.Processor; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + /** * <p> * ProcessGroup objects are containers for processing entities, such as @@ -46,6 +48,26 @@ import org.apache.nifi.processor.Processor; public interface ProcessGroup extends Authorizable { /** + * Predicate for filtering schedulable Processors. + */ + Predicate<ProcessorNode> SCHEDULABLE_PROCESSORS = node -> !node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED; + + /** + * Predicate for filtering unschedulable Processors. + */ + Predicate<ProcessorNode> UNSCHEDULABLE_PROCESSORS = node -> node.isRunning(); + + /** + * Predicate for filtering schedulable Ports + */ + Predicate<Port> SCHEDULABLE_PORTS = port -> port.getScheduledState() != ScheduledState.DISABLED; + + /** + * Predicate for filtering schedulable Ports + */ + Predicate<Port> UNSCHEDULABLE_PORTS = port -> port.getScheduledState() == ScheduledState.RUNNING; + + /** * @return a reference to this ProcessGroup's parent. This will be * <tt>null</tt> if and only if this is the root group. */ @@ -743,8 +765,12 @@ public interface ProcessGroup extends Authorizable { */ void verifyCanDelete(boolean ignorePortConnections); + void verifyCanStart(Connectable connectable); + void verifyCanStart(); + void verifyCanStop(Connectable connectable); + void verifyCanStop(); /** http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java index 7060699..e17301b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardSnippet.java @@ -33,7 +33,6 @@ public class StandardSnippet implements Snippet { private String id; private String parentGroupId; - private Boolean linked; private Map<String, Revision> processGroups = new HashMap<>(); private Map<String, Revision> remoteProcessGroups = new HashMap<>(); @@ -54,19 +53,6 @@ public class StandardSnippet implements Snippet { } @Override - public boolean isLinked() { - if (linked == null) { - return false; - } else { - return linked; - } - } - - public void setLinked(Boolean linked) { - this.linked = linked; - } - - @Override public String getParentGroupId() { return parentGroupId; } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java index 1a3ab52..d3f5a1a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java @@ -283,38 +283,21 @@ public final class StandardProcessGroup implements ProcessGroup { public void startProcessing() { readLock.lock(); try { - for (final ProcessorNode node : processors.values()) { + findAllProcessors().stream().filter(SCHEDULABLE_PROCESSORS).forEach(node -> { try { - if (!node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED) { - startProcessor(node); - } + node.getProcessGroup().startProcessor(node); } catch (final Throwable t) { LOG.error("Unable to start {} due to {}", new Object[]{node, t}); } - } - - for (final Port inputPort : getInputPorts()) { - if (inputPort.getScheduledState() != ScheduledState.DISABLED) { - startInputPort(inputPort); - } - } - - for (final Port outputPort : getOutputPorts()) { - if (outputPort.getScheduledState() != ScheduledState.DISABLED) { - startOutputPort(outputPort); - } - } + }); - for (final Funnel funnel : getFunnels()) { - if (funnel.getScheduledState() != ScheduledState.DISABLED) { - startFunnel(funnel); - } - } + findAllInputPorts().stream().filter(SCHEDULABLE_PORTS).forEach(port -> { + port.getProcessGroup().startInputPort(port); + }); - // Recursively start child groups. - for (final ProcessGroup group : processGroups.values()) { - group.startProcessing(); - } + findAllOutputPorts().stream().filter(SCHEDULABLE_PORTS).forEach(port -> { + port.getProcessGroup().startOutputPort(port); + }); } finally { readLock.unlock(); } @@ -324,32 +307,21 @@ public final class StandardProcessGroup implements ProcessGroup { public void stopProcessing() { readLock.lock(); try { - for (final ProcessorNode node : processors.values()) { + findAllProcessors().stream().filter(UNSCHEDULABLE_PROCESSORS).forEach(node -> { try { - if (node.isRunning()) { - stopProcessor(node); - } + node.getProcessGroup().stopProcessor(node); } catch (final Throwable t) { LOG.error("Unable to stop {} due to {}", new Object[]{node, t}); } - } - - for (final Port inputPort : getInputPorts()) { - if (inputPort.getScheduledState() == ScheduledState.RUNNING) { - stopInputPort(inputPort); - } - } + }); - for (final Port outputPort : getOutputPorts()) { - if (outputPort.getScheduledState() == ScheduledState.RUNNING) { - stopOutputPort(outputPort); - } - } + findAllInputPorts().stream().filter(UNSCHEDULABLE_PORTS).forEach(port -> { + port.getProcessGroup().stopInputPort(port); + }); - // Recursively stop child groups. - for (final ProcessGroup group : processGroups.values()) { - group.stopProcessing(); - } + findAllOutputPorts().stream().filter(UNSCHEDULABLE_PORTS).forEach(port -> { + port.getProcessGroup().stopOutputPort(port); + }); } finally { readLock.unlock(); } @@ -2292,21 +2264,35 @@ public final class StandardProcessGroup implements ProcessGroup { } @Override + public void verifyCanStop(Connectable connectable) { + } + + @Override public void verifyCanStop() { } @Override + public void verifyCanStart(Connectable connectable) { + readLock.lock(); + try { + if (connectable.getScheduledState() == ScheduledState.STOPPED) { + if (scheduler.getActiveThreadCount(connectable) > 0) { + throw new IllegalStateException("Cannot start " + connectable + " because it is currently stopping"); + } + + connectable.verifyCanStart(); + } + } finally { + readLock.unlock(); + } + } + + @Override public void verifyCanStart() { readLock.lock(); try { for (final Connectable connectable : findAllConnectables(this, false)) { - if (connectable.getScheduledState() == ScheduledState.STOPPED) { - if (scheduler.getActiveThreadCount(connectable) > 0) { - throw new IllegalStateException("Cannot start " + connectable + " because it is currently stopping"); - } - - connectable.verifyCanStart(); - } + verifyCanStart(connectable); } } finally { readLock.unlock(); http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java index 11724f4..eebcfa5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java @@ -557,4 +557,11 @@ public class MockProcessGroup implements ProcessGroup { return null; } + @Override + public void verifyCanStart(Connectable connectable) { + } + + @Override + public void verifyCanStop(Connectable connectable) { + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java index 04dca11..a4277c6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java @@ -16,9 +16,6 @@ */ package org.apache.nifi.audit; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; import org.apache.nifi.action.Action; import org.apache.nifi.action.Component; import org.apache.nifi.action.FlowChangeAction; @@ -26,9 +23,10 @@ import org.apache.nifi.action.Operation; import org.apache.nifi.action.details.ActionDetails; import org.apache.nifi.action.details.FlowChangeConfigureDetails; import org.apache.nifi.action.details.FlowChangeMoveDetails; +import org.apache.nifi.authorization.user.NiFiUser; import org.apache.nifi.authorization.user.NiFiUserUtils; +import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.groups.ProcessGroup; -import org.apache.nifi.authorization.user.NiFiUser; import org.apache.nifi.web.api.dto.ProcessGroupDTO; import org.apache.nifi.web.dao.ProcessGroupDAO; import org.aspectj.lang.ProceedingJoinPoint; @@ -37,6 +35,10 @@ import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + /** * Audits process group creation/removal and configuration changes. */ @@ -153,28 +155,6 @@ public class ProcessGroupAuditor extends NiFiAuditor { } } - // if the user was starting/stopping this process group - if (processGroupDTO.isRunning() != null) { - // create a process group action - FlowChangeAction processGroupAction = new FlowChangeAction(); - processGroupAction.setUserIdentity(user.getIdentity()); - processGroupAction.setUserName(user.getUserName()); - processGroupAction.setSourceId(processGroup.getIdentifier()); - processGroupAction.setSourceName(processGroup.getName()); - processGroupAction.setSourceType(Component.ProcessGroup); - processGroupAction.setTimestamp(new Date()); - - // determine the running state - if (processGroupDTO.isRunning()) { - processGroupAction.setOperation(Operation.Start); - } else { - processGroupAction.setOperation(Operation.Stop); - } - - // add this action - actions.add(processGroupAction); - } - // save actions if necessary if (!actions.isEmpty()) { saveActions(actions, logger); @@ -185,6 +165,47 @@ public class ProcessGroupAuditor extends NiFiAuditor { } /** + * Audits the update of process group configuration. + * + * @param proceedingJoinPoint join point + * @param groupId group id + * @param state scheduled state + * @throws Throwable ex + */ + @Around("within(org.apache.nifi.web.dao.ProcessGroupDAO+) && " + + "execution(void scheduleComponents(java.lang.String, org.apache.nifi.controller.ScheduledState, java.util.Set)) && " + + "args(groupId, state)") + public void scheduleComponentsAdvice(ProceedingJoinPoint proceedingJoinPoint, String groupId, ScheduledState state) throws Throwable { + ProcessGroupDAO processGroupDAO = getProcessGroupDAO(); + ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); + + // perform the action + proceedingJoinPoint.proceed(); + + // get the current user + NiFiUser user = NiFiUserUtils.getNiFiUser(); + + // if the user was starting/stopping this process group + FlowChangeAction action = new FlowChangeAction(); + action.setUserIdentity(user.getIdentity()); + action.setUserName(user.getUserName()); + action.setSourceId(processGroup.getIdentifier()); + action.setSourceName(processGroup.getName()); + action.setSourceType(Component.ProcessGroup); + action.setTimestamp(new Date()); + + // determine the running state + if (ScheduledState.RUNNING.equals(state)) { + action.setOperation(Operation.Start); + } else { + action.setOperation(Operation.Stop); + } + + // add this action + saveAction(action, logger); + } + + /** * Audits the removal of a process group via deleteProcessGroup(). * * @param proceedingJoinPoint join point http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java index bb96e88..27b76b1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/SnippetAuditor.java @@ -253,7 +253,7 @@ public class SnippetAuditor extends NiFiAuditor { * @throws Throwable ex */ @Around("within(org.apache.nifi.web.dao.SnippetDAO+) && " - + "execution(org.apache.nifi.controller.Snippet updateSnippet(org.apache.nifi.web.api.dto.SnippetDTO)) && " + + "execution(org.apache.nifi.controller.Snippet updateSnippetComponents(org.apache.nifi.web.api.dto.SnippetDTO)) && " + "args(snippetDTO) && " + "target(snippetDAO)") public Snippet updateSnippetAdvice(ProceedingJoinPoint proceedingJoinPoint, SnippetDTO snippetDTO, SnippetDAO snippetDAO) throws Throwable { @@ -266,7 +266,7 @@ public class SnippetAuditor extends NiFiAuditor { // if this snippet is linked and its parent group id has changed final String groupId = snippetDTO.getParentGroupId(); - if (snippet.isLinked() && !previousGroupId.equals(groupId)) { + if (!previousGroupId.equals(groupId)) { // create move audit records for all items in this snippet final Collection<Action> actions = new ArrayList<>(); @@ -346,114 +346,109 @@ public class SnippetAuditor extends NiFiAuditor { * @throws Throwable ex */ @Around("within(org.apache.nifi.web.dao.SnippetDAO+) && " - + "execution(void deleteSnippet(java.lang.String)) && " + + "execution(void deleteSnippetComponents(java.lang.String)) && " + "args(snippetId) && " + "target(snippetDAO)") public void removeSnippetAdvice(ProceedingJoinPoint proceedingJoinPoint, String snippetId, SnippetDAO snippetDAO) throws Throwable { // get the snippet before removing it final Snippet snippet = snippetDAO.getSnippet(snippetId); - if (snippet.isLinked()) { - // locate all the components being removed - final Set<Funnel> funnels = new HashSet<>(); - for (String id : snippet.getFunnels().keySet()) { - funnels.add(funnelDAO.getFunnel(id)); - } + // locate all the components being removed + final Set<Funnel> funnels = new HashSet<>(); + for (String id : snippet.getFunnels().keySet()) { + funnels.add(funnelDAO.getFunnel(id)); + } - final Set<Port> inputPorts = new HashSet<>(); - for (String id : snippet.getInputPorts().keySet()) { - inputPorts.add(inputPortDAO.getPort(id)); - } + final Set<Port> inputPorts = new HashSet<>(); + for (String id : snippet.getInputPorts().keySet()) { + inputPorts.add(inputPortDAO.getPort(id)); + } - final Set<Port> outputPorts = new HashSet<>(); - for (String id : snippet.getOutputPorts().keySet()) { - outputPorts.add(outputPortDAO.getPort(id)); - } + final Set<Port> outputPorts = new HashSet<>(); + for (String id : snippet.getOutputPorts().keySet()) { + outputPorts.add(outputPortDAO.getPort(id)); + } - final Set<RemoteProcessGroup> remoteProcessGroups = new HashSet<>(); - for (String id : snippet.getRemoteProcessGroups().keySet()) { - remoteProcessGroups.add(remoteProcessGroupDAO.getRemoteProcessGroup(id)); - } + final Set<RemoteProcessGroup> remoteProcessGroups = new HashSet<>(); + for (String id : snippet.getRemoteProcessGroups().keySet()) { + remoteProcessGroups.add(remoteProcessGroupDAO.getRemoteProcessGroup(id)); + } - final Set<ProcessGroup> processGroups = new HashSet<>(); - final ProcessGroupDAO processGroupDAO = getProcessGroupDAO(); - for (String id : snippet.getProcessGroups().keySet()) { - processGroups.add(processGroupDAO.getProcessGroup(id)); - } + final Set<ProcessGroup> processGroups = new HashSet<>(); + final ProcessGroupDAO processGroupDAO = getProcessGroupDAO(); + for (String id : snippet.getProcessGroups().keySet()) { + processGroups.add(processGroupDAO.getProcessGroup(id)); + } - final Set<ProcessorNode> processors = new HashSet<>(); - for (String id : snippet.getProcessors().keySet()) { - processors.add(processorDAO.getProcessor(id)); - } + final Set<ProcessorNode> processors = new HashSet<>(); + for (String id : snippet.getProcessors().keySet()) { + processors.add(processorDAO.getProcessor(id)); + } - final Set<Connection> connections = new HashSet<>(); - for (String id : snippet.getConnections().keySet()) { - connections.add(connectionDAO.getConnection(id)); - } + final Set<Connection> connections = new HashSet<>(); + for (String id : snippet.getConnections().keySet()) { + connections.add(connectionDAO.getConnection(id)); + } - // remove the snippet and components - proceedingJoinPoint.proceed(); + // remove the snippet and components + proceedingJoinPoint.proceed(); - final Collection<Action> actions = new ArrayList<>(); + final Collection<Action> actions = new ArrayList<>(); - // audit funnel removal - for (Funnel funnel : funnels) { - final Action action = funnelAuditor.generateAuditRecord(funnel, Operation.Remove); - if (action != null) { - actions.add(action); - } + // audit funnel removal + for (Funnel funnel : funnels) { + final Action action = funnelAuditor.generateAuditRecord(funnel, Operation.Remove); + if (action != null) { + actions.add(action); } + } - for (Port inputPort : inputPorts) { - final Action action = portAuditor.generateAuditRecord(inputPort, Operation.Remove); - if (action != null) { - actions.add(action); - } + for (Port inputPort : inputPorts) { + final Action action = portAuditor.generateAuditRecord(inputPort, Operation.Remove); + if (action != null) { + actions.add(action); } + } - for (Port outputPort : outputPorts) { - final Action action = portAuditor.generateAuditRecord(outputPort, Operation.Remove); - if (action != null) { - actions.add(action); - } + for (Port outputPort : outputPorts) { + final Action action = portAuditor.generateAuditRecord(outputPort, Operation.Remove); + if (action != null) { + actions.add(action); } + } - for (RemoteProcessGroup remoteProcessGroup : remoteProcessGroups) { - final Action action = remoteProcessGroupAuditor.generateAuditRecord(remoteProcessGroup, Operation.Remove); - if (action != null) { - actions.add(action); - } + for (RemoteProcessGroup remoteProcessGroup : remoteProcessGroups) { + final Action action = remoteProcessGroupAuditor.generateAuditRecord(remoteProcessGroup, Operation.Remove); + if (action != null) { + actions.add(action); } + } - for (ProcessGroup processGroup : processGroups) { - final Action action = processGroupAuditor.generateAuditRecord(processGroup, Operation.Remove); - if (action != null) { - actions.add(action); - } + for (ProcessGroup processGroup : processGroups) { + final Action action = processGroupAuditor.generateAuditRecord(processGroup, Operation.Remove); + if (action != null) { + actions.add(action); } + } - for (ProcessorNode processor : processors) { - final Action action = processorAuditor.generateAuditRecord(processor, Operation.Remove); - if (action != null) { - actions.add(action); - } + for (ProcessorNode processor : processors) { + final Action action = processorAuditor.generateAuditRecord(processor, Operation.Remove); + if (action != null) { + actions.add(action); } + } - for (Connection connection : connections) { - final ConnectDetails connectDetails = relationshipAuditor.createConnectDetails(connection, connection.getRelationships()); - final Action action = relationshipAuditor.generateAuditRecordForConnection(connection, Operation.Disconnect, connectDetails); - if (action != null) { - actions.add(action); - } + for (Connection connection : connections) { + final ConnectDetails connectDetails = relationshipAuditor.createConnectDetails(connection, connection.getRelationships()); + final Action action = relationshipAuditor.generateAuditRecordForConnection(connection, Operation.Disconnect, connectDetails); + if (action != null) { + actions.add(action); } + } - // save the actions - if (CollectionUtils.isNotEmpty(actions)) { - saveActions(actions, logger); - } - } else { - // remove the snippet but not the components since this snippet isn't linked - proceedingJoinPoint.proceed(); + // save the actions + if (CollectionUtils.isNotEmpty(actions)) { + saveActions(actions, logger); } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java new file mode 100644 index 0000000..d6db1f0 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizableLookup.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web; + +import org.apache.nifi.authorization.resource.Authorizable; +import org.apache.nifi.controller.Snippet; + +public interface AuthorizableLookup { + + /** + * Get the authorizable Processor. + * + * @param id processor id + * @return authorizable + */ + Authorizable getProcessor(String id); + + /** + * Get the authorizable InputPort. + * + * @param id input port id + * @return authorizable + */ + Authorizable getInputPort(String id); + + /** + * Get the authorizable OutputPort. + * + * @param id output port id + * @return authorizable + */ + Authorizable getOutputPort(String id); + + /** + * Get the authorizable Connection. + * + * @param id connection id + * @return authorizable + */ + Authorizable getConnection(String id); + + /** + * Get the authorizable ProcessGroup. + * + * @param id process group id + * @return authorizable + */ + Authorizable getProcessGroup(String id); + + /** + * Get the authorizable RemoteProcessGroup. + * + * @param id remote process group id + * @return authorizable + */ + Authorizable getRemoteProcessGroup(String id); + + /** + * Get the authorizable RemoteProcessGroup input port. + * + * @param remoteProcessGroupId remote process group id + * @param id input port id + * @return authorizable + */ + Authorizable getRemoteProcessGroupInputPort(String remoteProcessGroupId, String id); + + /** + * Get the authorizable RemoteProcessGroup output port. + * + * @param remoteProcessGroupId remote process group id + * @param id output port id + * @return authorizable + */ + Authorizable getRemoteProcessGroupOutputPort(String remoteProcessGroupId, String id); + + /** + * Get the authorizable Label. + * + * @param id label id + * @return authorizable + */ + Authorizable getLabel(String id); + + /** + * Get the authorizable Funnel. + * + * @param id funnel id + * @return authorizable + */ + Authorizable getFunnel(String id); + + /** + * Get the authorizable ControllerService. + * + * @param id controller service id + * @return authorizable + */ + Authorizable getControllerService(String id); + + /** + * Get the authorizable referencing component. + * + * @param controllerSeriveId controller service id + * @param id component id + * @return authorizable + */ + Authorizable getControllerServiceReferencingComponent(String controllerSeriveId, String id); + + /** + * Get the authorizable ReportingTask. + * + * @param id reporting task id + * @return authorizable + */ + Authorizable getReportingTask(String id); + + /** + * Get the authorizable Template. + * + * @param id template id + * @return authorizable + */ + Authorizable getTemplate(String id); + + /** + * Get the authorizable connectable. + * + * @param id connectable id + * @return authorizable + */ + Authorizable getConnectable(String id); + + /** + * Get the snippet of authorizable's. + * + * @param id snippet id + * @return snippet of authorizable's + */ + Snippet getSnippet(String id); +} http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java new file mode 100644 index 0000000..29fd523 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/AuthorizeAccess.java @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web; + +public interface AuthorizeAccess { + void authorize(AuthorizableLookup lookup); +} http://git-wip-us.apache.org/repos/asf/nifi/blob/4dd50c80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 41b9867..f372812 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -16,9 +16,11 @@ */ package org.apache.nifi.web; +import org.apache.nifi.authorization.user.NiFiUser; import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.repository.claim.ContentDirection; import org.apache.nifi.controller.service.ControllerServiceState; +import org.apache.nifi.groups.ProcessGroup; import org.apache.nifi.web.api.dto.BulletinBoardDTO; import org.apache.nifi.web.api.dto.BulletinQueryDTO; import org.apache.nifi.web.api.dto.ClusterDTO; @@ -51,7 +53,6 @@ import org.apache.nifi.web.api.dto.TemplateDTO; import org.apache.nifi.web.api.dto.action.ActionDTO; import org.apache.nifi.web.api.dto.action.HistoryDTO; import org.apache.nifi.web.api.dto.action.HistoryQueryDTO; -import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO; import org.apache.nifi.web.api.dto.provenance.ProvenanceDTO; import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO; import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO; @@ -72,10 +73,12 @@ import org.apache.nifi.web.api.entity.FunnelEntity; import org.apache.nifi.web.api.entity.LabelEntity; import org.apache.nifi.web.api.entity.PortEntity; import org.apache.nifi.web.api.entity.ProcessGroupEntity; +import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; import org.apache.nifi.web.api.entity.ProcessorEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; +import org.apache.nifi.web.api.entity.ScheduleComponentsEntity; import org.apache.nifi.web.api.entity.SnippetEntity; import java.util.Date; @@ -83,6 +86,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Function; /** * Defines the NiFiServiceFacade interface. @@ -92,7 +96,64 @@ public interface NiFiServiceFacade { // ---------------------------------------- // Synchronization methods // ---------------------------------------- - void claimRevision(Revision revision) throws InvalidRevisionException; + + /** + * Authorizes access to the service facade. + * + * @param authorizeAccess authorize access callback + */ + void authorizeAccess(AuthorizeAccess authorizeAccess); + + /** + * Claims the specified revision for the specified user. + * + * @param revision revision + * @param user user + * @throws InvalidRevisionException invalid revision + */ + void claimRevision(Revision revision, NiFiUser user) throws InvalidRevisionException; + + /** + * Claims the specified revisions for the specified user. + * + * @param revisions revisions + * @param user user + * @throws InvalidRevisionException invalid revision + */ + void claimRevisions(Set<Revision> revisions, NiFiUser user) throws InvalidRevisionException; + + /** + * Cancels the specified revision. Cancellation is only supported based on the current thread. + * + * @param revision revision + * @throws InvalidRevisionException invalid revision + */ + void cancelRevision(Revision revision) throws InvalidRevisionException; + + /** + * Cancels the specified revisions. Cancellation is only supported based on the current thread. + * + * @param revisions revision + * @throws InvalidRevisionException invalid revision + */ + void cancelRevisions(Set<Revision> revisions) throws InvalidRevisionException; + + /** + * Gets the current revisions for the components based on the specified function. + * + * @param groupId group + * @param getComponents callback + * @return component revisions + */ + Set<Revision> getRevisionsFromGroup(String groupId, Function<ProcessGroup, Set<String>> getComponents); + + /** + * Gets the revisions from the specified snippet. + * + * @param snippetId snippet + * @return component revisions from the snippet + */ + Set<Revision> getRevisionsFromSnippet(String snippetId); // ---------------------------------------- // Controller methods @@ -754,7 +815,7 @@ public interface NiFiServiceFacade { * @param recurse recurse * @return the flow */ - ConfigurationSnapshot<ProcessGroupFlowDTO> getProcessGroupFlow(String groupId, boolean recurse); + ProcessGroupFlowEntity getProcessGroupFlow(String groupId, boolean recurse); // ---------------------------------------- // ProcessGroup methods @@ -785,11 +846,23 @@ public interface NiFiServiceFacade { Set<ProcessGroupEntity> getProcessGroups(String parentGroupId); /** - * Verifies the specified process group can be updated. + * Verifies the contents of the specified process group can be scheduled or unscheduled. * - * @param processGroupDTO The ProcessGroupDTO + * @param processGroupId The ProcessGroup id + * @param componentIds the components + * @param state scheduled state + */ + void verifyScheduleComponents(String processGroupId, ScheduledState state, Set<String> componentIds); + + /** + * Schedules all applicable components under the specified ProcessGroup. + * + * @param processGroupId The ProcessGroup id + * @param state schedule state + * @param componentRevisions components and their revision + * @return snapshot */ - void verifyUpdateProcessGroup(ProcessGroupDTO processGroupDTO); + ScheduleComponentsEntity scheduleComponents(String processGroupId, ScheduledState state, Map<String, Revision> componentRevisions); /** * Updates the specified process group. @@ -1320,44 +1393,37 @@ public interface NiFiServiceFacade { SnippetEntity createSnippet(SnippetDTO snippet); /** - * Gets the specified snippet. - * - * @param snippetId id - * @return snippet - */ - SnippetEntity getSnippet(String snippetId); - - /** * Determines if this snippet can be updated. * * @param snippetDto snippet */ - void verifyUpdateSnippet(SnippetDTO snippetDto); + void verifyUpdateSnippet(SnippetDTO snippetDto, Set<String> affectedComponentIds); /** * If group id is specified, moves the specified snippet to the specified group. * - * @param revision revision + * @param revisions revisions * @param snippetDto snippet * @return snapshot */ - UpdateResult<SnippetEntity> updateSnippet(Revision revision, SnippetDTO snippetDto); + SnippetEntity updateSnippet(Set<Revision> revisions, SnippetDTO snippetDto); /** * Determines if this snippet can be removed. * * @param id id + * @param affectedComponentIds affected components */ - void verifyDeleteSnippet(String id); + void verifyDeleteSnippet(String id, Set<String> affectedComponentIds); /** * Removes the specified snippet. * - * @param revision revision + * @param revisions revisions * @param snippetId snippet * @return snapshot */ - SnippetEntity deleteSnippet(Revision revision, String snippetId); + SnippetEntity deleteSnippet(Set<Revision> revisions, String snippetId); // ---------------------------------------- // Cluster methods