[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread asfgit
Github user asfgit closed the pull request at:

https://github.com/apache/nifi/pull/461


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on the pull request:

https://github.com/apache/nifi/pull/461#issuecomment-221051044
  
Thanks @markap14 

All changes have been applied.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64262070
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
 ---
@@ -2024,6 +1843,24 @@ public Response instantiateTemplate(
 // templates
 // -
 
+private void authorizeSnippetUsage(final AuthorizableLookup lookup, 
final String groupId, final String snippetId) {
+// ensure write access to the target process group
+lookup.getProcessGroup(groupId).authorize(authorizer, 
RequestAction.WRITE);
+
+// ensure read permission to every component in the snippet
+final Snippet snippet = lookup.getSnippet(snippetId);
+final Set authorizables = new HashSet<>();
+
authorizables.addAll(snippet.getProcessGroups().keySet().stream().map(id -> 
lookup.getProcessGroup(id)).collect(Collectors.toSet()));
--- End diff --

Awesome. Will do!


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64259242
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java
 ---
@@ -0,0 +1,397 @@
+/*
+ * 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;
+
+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.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.RequestAction;
+import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.authorization.user.NiFiUserUtils;
+import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.controller.Snippet;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.NiFiServiceFacade;
+import org.apache.nifi.web.Revision;
+import org.apache.nifi.web.api.dto.SnippetDTO;
+import org.apache.nifi.web.api.entity.SnippetEntity;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+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.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * RESTful endpoint for querying dataflow snippets.
+ */
+@Path("/snippets")
+@Api(
+value = "/snippets",
+description = "Endpoint for accessing dataflow snippets."
+)
+public class SnippetResource extends ApplicationResource {
+
+private NiFiServiceFacade serviceFacade;
+private WebClusterManager clusterManager;
+private NiFiProperties properties;
+private Authorizer authorizer;
+
+/**
+ * Populate the uri's for the specified snippet.
+ *
+ * @param entity processors
+ * @return dtos
+ */
+private SnippetEntity 
populateRemainingSnippetEntityContent(SnippetEntity entity) {
+if (entity.getSnippet() != null) {
+populateRemainingSnippetContent(entity.getSnippet());
+}
+return entity;
+}
+
+/**
+ * Populates the uri for the specified snippet.
+ */
+private SnippetDTO populateRemainingSnippetContent(SnippetDTO snippet) 
{
+String snippetGroupId = snippet.getParentGroupId();
+
+// populate the snippet href
+snippet.setUri(generateResourceUri("process-groups", 
snippetGroupId, "snippets", snippet.getId()));
+
+return snippet;
+}
+
+// 
+// snippets
+// 
+
+/**
+ * Creates a snippet based off the specified configuration.
+ *
+ * @param httpServletRequest request
+ * @param snippetEntity A snippetEntity
+ * @return A snippetEntity
+ */
+@POST
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
+@ApiOperation(
+value = "Creates a snippet",
+response = SnippetEntity.class,
+authorizations = {
+@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+@Authorization(value = "Administrator", type = "ROLE_ADMIN")

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64259949
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
 ---
@@ -321,6 +320,157 @@ public Response getControllerServices(
 return clusterContext(generateOkResponse(entity)).build();
 }
 
+/**
+ * Updates the specified process group.
+ *
+ * @param httpServletRequest request
+ * @param id The id of the process group.
+ * @param scheduleComponentsEntity A scheduleComponentsEntity.
+ * @return A processGroupEntity.
+ */
+@PUT
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Path("process-groups/{id}")
+// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
+@ApiOperation(
+value = "Updates a process group",
+response = ScheduleComponentsEntity.class,
+authorizations = {
+@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
+}
+)
+@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 = 404, message = "The specified resource 
could not be found."),
+@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 scheduleComponents(
+@Context HttpServletRequest httpServletRequest,
+@ApiParam(
+value = "The process group id.",
+required = true
+)
+@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 "
++ "not equal the process group id of the requested 
resource (%s).", scheduleComponentsEntity.getId(), id));
+}
+
+final ScheduledState state;
+if (scheduleComponentsEntity.getState() == null) {
+throw new IllegalArgumentException("The scheduled state must 
be specified.");
+} else {
+try {
+state = 
ScheduledState.valueOf(scheduleComponentsEntity.getState());
+} catch (final IllegalArgumentException iae) {
+throw new IllegalArgumentException(String.format("The 
scheduled must be one of [].", 
StringUtils.join(EnumSet.of(ScheduledState.RUNNING, ScheduledState.STOPPED), ", 
")));
+}
+}
+
+// ensure its a supported scheduled state
+if (ScheduledState.DISABLED.equals(state) || 
ScheduledState.STARTING.equals(state) || ScheduledState.STOPPING.equals(state)) 
{
+throw new IllegalArgumentException(String.format("The 
scheduled must be one of [].", 
StringUtils.join(EnumSet.of(ScheduledState.RUNNING, ScheduledState.STOPPED), ", 
")));
+}
+
+// if the components are not specified, gather all components and 
their current revision
+if (scheduleComponentsEntity.getComponents() == null) {
+// TODO - this will break while clustered until nodes are able 
to process/replicate requests
+// get the current revisions for the components being updated
+final Set revisions = 
serviceFacade.getRevisionsFromGroup(id, group -> {
+final Set componentIds = new HashSet<>();
+
+// ensure authorized for each processor we will attempt to 
schedule
+
group.findAllProcessors().stream().filter(ScheduledState.RUNNING.equals(state) 
? ProcessGroup.SCHEDULABLE_PROCESSORS : 
ProcessGroup.UNSCHEDULABLE_PROCESSORS).forEach(processor -> {
+if (processor.isAuthorized(authorizer, 
RequestAction.WRITE)) {
--- End diff --

Will do!


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64259092
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java
 ---
@@ -0,0 +1,397 @@
+/*
+ * 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;
+
+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.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.RequestAction;
+import org.apache.nifi.authorization.resource.Authorizable;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.authorization.user.NiFiUserUtils;
+import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.controller.Snippet;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.NiFiServiceFacade;
+import org.apache.nifi.web.Revision;
+import org.apache.nifi.web.api.dto.SnippetDTO;
+import org.apache.nifi.web.api.entity.SnippetEntity;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+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.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * RESTful endpoint for querying dataflow snippets.
+ */
+@Path("/snippets")
+@Api(
+value = "/snippets",
+description = "Endpoint for accessing dataflow snippets."
+)
+public class SnippetResource extends ApplicationResource {
+
+private NiFiServiceFacade serviceFacade;
+private WebClusterManager clusterManager;
+private NiFiProperties properties;
+private Authorizer authorizer;
+
+/**
+ * Populate the uri's for the specified snippet.
+ *
+ * @param entity processors
+ * @return dtos
+ */
+private SnippetEntity 
populateRemainingSnippetEntityContent(SnippetEntity entity) {
+if (entity.getSnippet() != null) {
+populateRemainingSnippetContent(entity.getSnippet());
+}
+return entity;
+}
+
+/**
+ * Populates the uri for the specified snippet.
+ */
+private SnippetDTO populateRemainingSnippetContent(SnippetDTO snippet) 
{
+String snippetGroupId = snippet.getParentGroupId();
+
+// populate the snippet href
+snippet.setUri(generateResourceUri("process-groups", 
snippetGroupId, "snippets", snippet.getId()));
+
+return snippet;
+}
+
+// 
+// snippets
+// 
+
+/**
+ * Creates a snippet based off the specified configuration.
+ *
+ * @param httpServletRequest request
+ * @param snippetEntity A snippetEntity
+ * @return A snippetEntity
+ */
+@POST
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
+@ApiOperation(
+value = "Creates a snippet",
+response = SnippetEntity.class,
+authorizations = {
+@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
+@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
+@Authorization(value = "Administrator", type = "ROLE_ADMIN")

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64256472
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
 ---
@@ -321,6 +320,157 @@ public Response getControllerServices(
 return clusterContext(generateOkResponse(entity)).build();
 }
 
+/**
+ * Updates the specified process group.
+ *
+ * @param httpServletRequest request
+ * @param id The id of the process group.
+ * @param scheduleComponentsEntity A scheduleComponentsEntity.
+ * @return A processGroupEntity.
+ */
+@PUT
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Path("process-groups/{id}")
+// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
+@ApiOperation(
+value = "Updates a process group",
+response = ScheduleComponentsEntity.class,
+authorizations = {
+@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
+}
+)
+@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 = 404, message = "The specified resource 
could not be found."),
+@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 scheduleComponents(
+@Context HttpServletRequest httpServletRequest,
+@ApiParam(
+value = "The process group id.",
+required = true
+)
+@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 "
++ "not equal the process group id of the requested 
resource (%s).", scheduleComponentsEntity.getId(), id));
+}
+
+final ScheduledState state;
+if (scheduleComponentsEntity.getState() == null) {
+throw new IllegalArgumentException("The scheduled state must 
be specified.");
+} else {
+try {
+state = 
ScheduledState.valueOf(scheduleComponentsEntity.getState());
+} catch (final IllegalArgumentException iae) {
+throw new IllegalArgumentException(String.format("The 
scheduled must be one of [].", 
StringUtils.join(EnumSet.of(ScheduledState.RUNNING, ScheduledState.STOPPED), ", 
")));
+}
+}
+
+// ensure its a supported scheduled state
+if (ScheduledState.DISABLED.equals(state) || 
ScheduledState.STARTING.equals(state) || ScheduledState.STOPPING.equals(state)) 
{
+throw new IllegalArgumentException(String.format("The 
scheduled must be one of [].", 
StringUtils.join(EnumSet.of(ScheduledState.RUNNING, ScheduledState.STOPPED), ", 
")));
+}
+
+// if the components are not specified, gather all components and 
their current revision
+if (scheduleComponentsEntity.getComponents() == null) {
+// TODO - this will break while clustered until nodes are able 
to process/replicate requests
+// get the current revisions for the components being updated
+final Set revisions = 
serviceFacade.getRevisionsFromGroup(id, group -> {
+final Set componentIds = new HashSet<>();
+
+// ensure authorized for each processor we will attempt to 
schedule
+
group.findAllProcessors().stream().filter(ScheduledState.RUNNING.equals(state) 
? ProcessGroup.SCHEDULABLE_PROCESSORS : 
ProcessGroup.UNSCHEDULABLE_PROCESSORS).forEach(processor -> {
+if (processor.isAuthorized(authorizer, 
RequestAction.WRITE)) {
+componentIds.add(processor.getIdentifier());
+}
+});
+
+// ensure authorized for each input port we will attempt 
to schedule
+
group.findAllInputPorts().stream().filter(ScheduledState.RUNNING.equals(state) 
? 

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64256311
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
 ---
@@ -321,6 +320,157 @@ public Response getControllerServices(
 return clusterContext(generateOkResponse(entity)).build();
 }
 
+/**
+ * Updates the specified process group.
+ *
+ * @param httpServletRequest request
+ * @param id The id of the process group.
+ * @param scheduleComponentsEntity A scheduleComponentsEntity.
+ * @return A processGroupEntity.
+ */
+@PUT
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Path("process-groups/{id}")
+// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
+@ApiOperation(
+value = "Updates a process group",
+response = ScheduleComponentsEntity.class,
+authorizations = {
+@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
+}
+)
+@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 = 404, message = "The specified resource 
could not be found."),
+@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 scheduleComponents(
+@Context HttpServletRequest httpServletRequest,
+@ApiParam(
+value = "The process group id.",
+required = true
+)
+@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 "
++ "not equal the process group id of the requested 
resource (%s).", scheduleComponentsEntity.getId(), id));
+}
+
+final ScheduledState state;
+if (scheduleComponentsEntity.getState() == null) {
+throw new IllegalArgumentException("The scheduled state must 
be specified.");
+} else {
+try {
+state = 
ScheduledState.valueOf(scheduleComponentsEntity.getState());
+} catch (final IllegalArgumentException iae) {
+throw new IllegalArgumentException(String.format("The 
scheduled must be one of [].", 
StringUtils.join(EnumSet.of(ScheduledState.RUNNING, ScheduledState.STOPPED), ", 
")));
+}
+}
+
+// ensure its a supported scheduled state
+if (ScheduledState.DISABLED.equals(state) || 
ScheduledState.STARTING.equals(state) || ScheduledState.STOPPING.equals(state)) 
{
+throw new IllegalArgumentException(String.format("The 
scheduled must be one of [].", 
StringUtils.join(EnumSet.of(ScheduledState.RUNNING, ScheduledState.STOPPED), ", 
")));
+}
+
+// if the components are not specified, gather all components and 
their current revision
+if (scheduleComponentsEntity.getComponents() == null) {
+// TODO - this will break while clustered until nodes are able 
to process/replicate requests
+// get the current revisions for the components being updated
+final Set revisions = 
serviceFacade.getRevisionsFromGroup(id, group -> {
+final Set componentIds = new HashSet<>();
+
+// ensure authorized for each processor we will attempt to 
schedule
+
group.findAllProcessors().stream().filter(ScheduledState.RUNNING.equals(state) 
? ProcessGroup.SCHEDULABLE_PROCESSORS : 
ProcessGroup.UNSCHEDULABLE_PROCESSORS).forEach(processor -> {
+if (processor.isAuthorized(authorizer, 
RequestAction.WRITE)) {
--- End diff --

It seems cleaner to me to use a filter here to check if the processor is 
authorized, rather than mixing stream filters with a forEach and then 
performing additional if-checks. I.e., instead of "if 
(processor.isAuthorized...) {...}" we could just do ".filter(processor -> 
processor.isAuthorized(...).forEach(...)" 

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64251051
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
 ---
@@ -46,6 +48,26 @@
 public interface ProcessGroup extends Authorizable {
 
 /**
+ * Predicate for filtering schedulable Processors.
+ */
+Predicate SCHEDULABLE_PROCESSORS = node -> 
!node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED;
+
+/**
+ * Predicate for filtering unschedulable Processors.
+ */
+Predicate UNSCHEDULABLE_PROCESSORS = node -> 
node.isRunning();
+
+/**
+ * Predicate for filtering schedulable Ports
+ */
+Predicate SCHEDULABLE_PORTS = port -> port.getScheduledState() 
!= ScheduledState.DISABLED;
+
+/**
+ * Predicate for filtering schedulable Ports
+ */
+Predicate UNSCHEDULABLE_PORTS = port -> port.getScheduledState() 
== ScheduledState.RUNNING;
--- End diff --

Happy to update the logic to whatever it needs to be. However, this is how 
it was previously.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64250889
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 ---
@@ -568,164 +699,50 @@ public void verifyDeleteReportingTask(String 
reportingTaskId) {
 
 
 @Override
-public void verifyUpdateSnippet(SnippetDTO snippetDto) {
+public void verifyUpdateSnippet(SnippetDTO snippetDto, final 
Set affectedComponentIds) {
 try {
 // if snippet does not exist, then the update request is 
likely creating it
 // so we don't verify since it will fail
 if (snippetDAO.hasSnippet(snippetDto.getId())) {
 snippetDAO.verifyUpdate(snippetDto);
 }
 } catch (final Exception e) {
-revisionManager.cancelClaim(snippetDto.getId());
+affectedComponentIds.forEach(id -> 
revisionManager.cancelClaim(snippetDto.getId()));
 throw e;
 }
 }
 
-private Set getRevisionsForGroup(final String groupId) {
-final Set revisions = new HashSet<>();
-
-revisions.add(revisionManager.getRevision(groupId));
-final ProcessGroup processGroup = 
processGroupDAO.getProcessGroup(groupId);
-if (processGroup == null) {
-throw new IllegalArgumentException("Snippet contains a 
reference to Process Group with ID " + groupId + " but no Process Group exists 
with that ID");
-}
-
-processGroup.getConnections().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getFunnels().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getInputPorts().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getOutputPorts().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getLabels().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getProcessors().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getRemoteProcessGroups().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getProcessGroups().stream().map(c -> 
c.getIdentifier()).forEach(id -> revisions.addAll(getRevisionsForGroup(id)));
-
-return revisions;
-}
-
-private Set getRevisionsForSnippet(final SnippetDTO 
snippetDto) {
-final Set requiredRevisions = new HashSet<>();
-
requiredRevisions.add(revisionManager.getRevision(snippetDto.getId()));
-snippetDto.getConnections().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getFunnels().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getInputPorts().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getOutputPorts().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getLabels().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getProcessors().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getRemoteProcessGroups().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-  

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64250267
  
--- Diff: 
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 boolean isRootGroup() {
 public void startProcessing() {
 readLock.lock();
 try {
-for (final ProcessorNode node : processors.values()) {
+
findAllProcessors().stream().filter(SCHEDULABLE_PROCESSORS).forEach(node -> {
--- End diff --

Totally agree. There are a number of improvements that we can make with 
Java 8 available. Let's create a separate JIRA to identify those.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
Github user mcgilman commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64250769
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
 ---
@@ -46,6 +48,26 @@
 public interface ProcessGroup extends Authorizable {
 
 /**
+ * Predicate for filtering schedulable Processors.
+ */
+Predicate SCHEDULABLE_PROCESSORS = node -> 
!node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED;
+
+/**
+ * Predicate for filtering unschedulable Processors.
+ */
+Predicate UNSCHEDULABLE_PROCESSORS = node -> 
node.isRunning();
+
+/**
+ * Predicate for filtering schedulable Ports
+ */
+Predicate SCHEDULABLE_PORTS = port -> port.getScheduledState() 
!= ScheduledState.DISABLED;
--- End diff --

I did not modify any logic here. Simply relocated to not repeat. If that 
logic is incorrect, I can certainly update it, but it hasn't changed here.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64249465
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 ---
@@ -568,164 +699,50 @@ public void verifyDeleteReportingTask(String 
reportingTaskId) {
 
 
 @Override
-public void verifyUpdateSnippet(SnippetDTO snippetDto) {
+public void verifyUpdateSnippet(SnippetDTO snippetDto, final 
Set affectedComponentIds) {
 try {
 // if snippet does not exist, then the update request is 
likely creating it
 // so we don't verify since it will fail
 if (snippetDAO.hasSnippet(snippetDto.getId())) {
 snippetDAO.verifyUpdate(snippetDto);
 }
 } catch (final Exception e) {
-revisionManager.cancelClaim(snippetDto.getId());
+affectedComponentIds.forEach(id -> 
revisionManager.cancelClaim(snippetDto.getId()));
 throw e;
 }
 }
 
-private Set getRevisionsForGroup(final String groupId) {
-final Set revisions = new HashSet<>();
-
-revisions.add(revisionManager.getRevision(groupId));
-final ProcessGroup processGroup = 
processGroupDAO.getProcessGroup(groupId);
-if (processGroup == null) {
-throw new IllegalArgumentException("Snippet contains a 
reference to Process Group with ID " + groupId + " but no Process Group exists 
with that ID");
-}
-
-processGroup.getConnections().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getFunnels().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getInputPorts().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getOutputPorts().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getLabels().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getProcessors().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getRemoteProcessGroups().stream().map(c -> 
c.getIdentifier()).map(id -> revisionManager.getRevision(id)).forEach(rev -> 
revisions.add(rev));
-processGroup.getProcessGroups().stream().map(c -> 
c.getIdentifier()).forEach(id -> revisions.addAll(getRevisionsForGroup(id)));
-
-return revisions;
-}
-
-private Set getRevisionsForSnippet(final SnippetDTO 
snippetDto) {
-final Set requiredRevisions = new HashSet<>();
-
requiredRevisions.add(revisionManager.getRevision(snippetDto.getId()));
-snippetDto.getConnections().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getFunnels().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getInputPorts().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getOutputPorts().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getLabels().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getProcessors().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-snippetDto.getRemoteProcessGroups().entrySet().stream()
-.map(entry -> new Revision(entry.getValue().getVersion(), 
entry.getValue().getClientId(), entry.getKey()))
-.forEach(rev -> requiredRevisions.add(rev));
-
-  

[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64248276
  
--- Diff: 
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 boolean isRootGroup() {
 public void startProcessing() {
 readLock.lock();
 try {
-for (final ProcessorNode node : processors.values()) {
+
findAllProcessors().stream().filter(SCHEDULABLE_PROCESSORS).forEach(node -> {
--- End diff --

It seems like here, rather than finding all processors and putting them 
into a set, then converting to a stream and filtering, we should allow a 
Predicate to be passed into the findAllProcessors() method? Same for 
input/output ports


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64248023
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
 ---
@@ -46,6 +48,26 @@
 public interface ProcessGroup extends Authorizable {
 
 /**
+ * Predicate for filtering schedulable Processors.
+ */
+Predicate SCHEDULABLE_PROCESSORS = node -> 
!node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED;
+
+/**
+ * Predicate for filtering unschedulable Processors.
+ */
+Predicate UNSCHEDULABLE_PROCESSORS = node -> 
node.isRunning();
+
+/**
+ * Predicate for filtering schedulable Ports
+ */
+Predicate SCHEDULABLE_PORTS = port -> port.getScheduledState() 
!= ScheduledState.DISABLED;
+
+/**
+ * Predicate for filtering schedulable Ports
+ */
+Predicate UNSCHEDULABLE_PORTS = port -> port.getScheduledState() 
== ScheduledState.RUNNING;
--- End diff --

Shouldn't this be "port.isRunning()" instead, like we do for Processor? It 
seems like we could actually just have a SCHEDULABLE_TRIGGERABLE and an 
UNSCHEDULABLE_TRIGGERABLE rather than separate ones for ports & processors?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread markap14
Github user markap14 commented on a diff in the pull request:

https://github.com/apache/nifi/pull/461#discussion_r64247888
  
--- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
 ---
@@ -46,6 +48,26 @@
 public interface ProcessGroup extends Authorizable {
 
 /**
+ * Predicate for filtering schedulable Processors.
+ */
+Predicate SCHEDULABLE_PROCESSORS = node -> 
!node.isRunning() && node.getScheduledState() != ScheduledState.DISABLED;
+
+/**
+ * Predicate for filtering unschedulable Processors.
+ */
+Predicate UNSCHEDULABLE_PROCESSORS = node -> 
node.isRunning();
+
+/**
+ * Predicate for filtering schedulable Ports
+ */
+Predicate SCHEDULABLE_PORTS = port -> port.getScheduledState() 
!= ScheduledState.DISABLED;
--- End diff --

It seems odd to me that we are checking "!node.isRunning()" for 
ProcessorsNode but not checking "!port.isRunning()" for ports.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] nifi pull request: NIFI-1781: UI authorization updates

2016-05-23 Thread mcgilman
GitHub user mcgilman opened a pull request:

https://github.com/apache/nifi/pull/461

NIFI-1781: UI authorization updates

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.

You can merge this pull request into a Git repository by running:

$ git pull https://github.com/mcgilman/nifi NIFI-1781

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/nifi/pull/461.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #461






---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---