diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java index 426e7fd5aa..25f5ec3107 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java @@ -34,30 +34,6 @@ public final class ResourceFactory { } }; - private final static Resource CONTROLLER_SERVICE_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.ControllerService.getValue(); - } - - @Override - public String getName() { - return "Controller Service"; - } - }; - - private final static Resource FUNNEL_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.Funnel.getValue(); - } - - @Override - public String getName() { - return "Funnel"; - } - }; - private final static Resource FLOW_RESOURCE = new Resource() { @Override public String getIdentifier() { @@ -70,42 +46,6 @@ public final class ResourceFactory { } }; - private final static Resource INPUT_PORT_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.InputPort.getValue(); - } - - @Override - public String getName() { - return "Input Port"; - } - }; - - private final static Resource LABEL_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.Label.getValue(); - } - - @Override - public String getName() { - return "Label"; - } - }; - - private final static Resource OUTPUT_PORT_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.OutputPort.getValue(); - } - - @Override - public String getName() { - return "Output Port"; - } - }; - private final static Resource POLICY_RESOURCE = new Resource() { @Override public String getIdentifier() { @@ -118,30 +58,6 @@ public final class ResourceFactory { } }; - private final static Resource PROCESSOR_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.Processor.getValue(); - } - - @Override - public String getName() { - return "Processor"; - } - }; - - private final static Resource PROCESS_GROUP_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.ProcessGroup.getValue(); - } - - @Override - public String getName() { - return "Process Group"; - } - }; - private final static Resource COUNTERS_RESOURCE = new Resource() { @Override public String getIdentifier() { @@ -190,30 +106,6 @@ public final class ResourceFactory { } }; - private final static Resource REMOTE_PROCESS_GROUP_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.RemoteProcessGroup.getValue(); - } - - @Override - public String getName() { - return "Remote Process Group"; - } - }; - - private final static Resource REPORTING_TASK_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.ReportingTask.getValue(); - } - - @Override - public String getName() { - return "Reporting Task"; - } - }; - private final static Resource RESOURCE_RESOURCE = new Resource() { @Override public String getIdentifier() { @@ -250,18 +142,6 @@ public final class ResourceFactory { } }; - private final static Resource TEMPLATE_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.Template.getValue(); - } - - @Override - public String getName() { - return "Template"; - } - }; - private final static Resource TENANT_RESOURCE = new Resource() { @Override public String getIdentifier() { @@ -296,24 +176,6 @@ public final class ResourceFactory { return CONTROLLER_RESOURCE; } - /** - * Gets the Resource for accessing Controller Services. - * - * @return The resource for accessing Controller Services - */ - public static Resource getControllerServiceResource() { - return CONTROLLER_SERVICE_RESOURCE; - } - - /** - * Gets the Resource for accessing Funnels. - * - * @return The resource for accessing Funnels. - */ - public static Resource getFunnelResource() { - return FUNNEL_RESOURCE; - } - /** * Gets the Resource for accessing the NiFi flow. This includes the data flow structure, component status, search results, and banner/about text. * @@ -323,51 +185,6 @@ public final class ResourceFactory { return FLOW_RESOURCE; } - /** - * Gets the Resource for accessing Input Ports. - * - * @return The resource for accessing Input Ports - */ - public static Resource getInputPortResource() { - return INPUT_PORT_RESOURCE; - } - - /** - * Gets the Resource for accessing Labels. - * - * @return The resource for accessing Labels - */ - public static Resource getLabelResource() { - return LABEL_RESOURCE; - } - - /** - * Gets the Resource for accessing Output Ports. - * - * @return The resource for accessing Output Ports - */ - public static Resource getOutputPortResource() { - return OUTPUT_PORT_RESOURCE; - } - - /** - * Gets the Resource for accessing Processors. - * - * @return The resource for accessing Processors - */ - public static Resource getProcessorResource() { - return PROCESSOR_RESOURCE; - } - - /** - * Gets the Resource for accessing Process Groups. - * - * @return The resource for accessing Process Groups - */ - public static Resource getProcessGroupResource() { - return PROCESS_GROUP_RESOURCE; - } - /** * Gets the Resource for accessing the Counters.. * @@ -396,24 +213,6 @@ public final class ResourceFactory { return PROXY_RESOURCE; } - /** - * Gets the Resource for accessing Remote Process Groups. - * - * @return The resource accessing Remote Process Groups - */ - public static Resource getRemoteProcessGroupResource() { - return REMOTE_PROCESS_GROUP_RESOURCE; - } - - /** - * Gets the Resource for accessing Reporting Tasks. - * - * @return The resource for accessing Reporting Tasks - */ - public static Resource getReportingTaskResource() { - return REPORTING_TASK_RESOURCE; - } - /** * Gets the Resource for detailing all available NiFi Resources. * @@ -442,15 +241,6 @@ public final class ResourceFactory { return SYSTEM_RESOURCE; } - /** - * Gets the Resource for accessing Templates. - * - * @return The Resource for accessing Tempaltes - */ - public static Resource getTemplateResource() { - return TEMPLATE_RESOURCE; - } - /** * Gets the Resource for accessing Tenants which includes creating, modifying, and deleting Users and UserGroups. * diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java index 54f98f14cd..9bfcbc00c1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java @@ -102,14 +102,18 @@ public class AccessPolicyResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{action}/{resource: .+}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets an access policy", + value = "Gets an access policy for the specified action and resource", + notes = "Will return the effective policy if no component specific policy exists for the specified action and resource. " + + "Must have Read permissions to the policy with the desired action and resource. Permissions for the policy that is " + + "returned will be indicated in the response. This means the client could be authorized to get the policy for a " + + "given component but the effective policy may be inherited from an ancestor Process Group. If the client does not " + + "have permissions to that policy, the response will not include the policy and the permissions in the response " + + "will be marked accordingly. If the client does not have permissions to the policy of the desired action and resource " + + "a 403 response will be returned.", response = AccessPolicyEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /policies/{resource}", type = "") } ) @ApiResponses( @@ -172,12 +176,11 @@ public class AccessPolicyResource extends ApplicationResource { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Creates an access policy", response = AccessPolicyEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /policies/{resource}", type = "") } ) @ApiResponses( @@ -263,14 +266,11 @@ public class AccessPolicyResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets an access policy", response = AccessPolicyEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /policies/{resource}", type = "") } ) @ApiResponses( @@ -300,7 +300,7 @@ public class AccessPolicyResource extends ApplicationResource { // authorize access serviceFacade.authorizeAccess(lookup -> { - Authorizable authorizable = lookup.getAccessPolicyById(id); + Authorizable authorizable = lookup.getAccessPolicyById(id); authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); }); @@ -323,12 +323,11 @@ public class AccessPolicyResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a access policy", response = AccessPolicyEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /policies/{resource}", type = "") } ) @ApiResponses( @@ -382,7 +381,7 @@ public class AccessPolicyResource extends ApplicationResource { serviceFacade, revision, lookup -> { - Authorizable authorizable = lookup.getAccessPolicyById(id); + Authorizable authorizable = lookup.getAccessPolicyById(id); authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, @@ -412,12 +411,11 @@ public class AccessPolicyResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes an access policy", response = AccessPolicyEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /policies/{resource}", type = "") } ) @ApiResponses( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java index 6f79a234c8..5657fdb520 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java @@ -29,13 +29,6 @@ import org.apache.nifi.authentication.LoginIdentityProvider; import org.apache.nifi.authentication.exception.IdentityAccessException; import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException; import org.apache.nifi.authorization.AccessDeniedException; -import org.apache.nifi.authorization.AuthorizationRequest; -import org.apache.nifi.authorization.AuthorizationResult; -import org.apache.nifi.authorization.AuthorizationResult.Result; -import org.apache.nifi.authorization.Authorizer; -import org.apache.nifi.authorization.RequestAction; -import org.apache.nifi.authorization.UserContextKeys; -import org.apache.nifi.authorization.resource.ResourceFactory; import org.apache.nifi.authorization.user.NiFiUser; import org.apache.nifi.authorization.user.NiFiUserDetails; import org.apache.nifi.authorization.user.NiFiUserUtils; @@ -78,8 +71,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.net.URI; import java.security.cert.X509Certificate; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.TimeUnit; /** @@ -87,8 +78,8 @@ import java.util.concurrent.TimeUnit; */ @Path("/access") @Api( - value = "/access", - description = "Endpoints for obtaining an access token or checking access status." + value = "/access", + description = "Endpoints for obtaining an access token or checking access status." ) public class AccessResource extends ApplicationResource { @@ -105,33 +96,6 @@ public class AccessResource extends ApplicationResource { private KerberosService kerberosService; - private Authorizer authorizer; - - /** - * Authorizes access to the flow. - */ - private boolean hasFlowAccess(final NiFiUser user) { - final Map userContext; - if (!StringUtils.isBlank(user.getClientAddress())) { - userContext = new HashMap<>(); - userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); - } else { - userContext = null; - } - - final AuthorizationRequest request = new AuthorizationRequest.Builder() - .resource(ResourceFactory.getFlowResource()) - .identity(user.getIdentity()) - .anonymous(user.isAnonymous()) - .accessAttempt(true) - .action(RequestAction.READ) - .userContext(userContext) - .build(); - - final AuthorizationResult result = authorizer.authorize(request); - return Result.Approved.equals(result.getResult()); - } - /** * Retrieves the access configuration for this NiFi. * @@ -173,6 +137,7 @@ public class AccessResource extends ApplicationResource { @Path("") @ApiOperation( value = "Gets the status the client's access", + notes = NON_GUARANTEED_ENDPOINT, response = AccessStatusEntity.class ) @ApiResponses( @@ -507,9 +472,6 @@ public class AccessResource extends ApplicationResource { } // setters - public void setAuthorizer(Authorizer authorizer) { - this.authorizer = authorizer; - } public void setLoginIdentityProvider(LoginIdentityProvider loginIdentityProvider) { this.loginIdentityProvider = loginIdentityProvider; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java index 2c5b43eb78..17017643e0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java @@ -95,6 +95,8 @@ public abstract class ApplicationResource { public static final String PROXY_PORT_HTTP_HEADER = "X-ProxyPort"; public static final String PROXY_CONTEXT_PATH_HTTP_HEADER = "X-ProxyContextPath"; + protected static final String NON_GUARANTEED_ENDPOINT = "Note: This endpoint is subject to change as the NiFi and it's REST API evolve."; + private static final Logger logger = LoggerFactory.getLogger(ApplicationResource.class); public static final String NODEWISE = "false"; @@ -459,7 +461,7 @@ public abstract class ApplicationResource { final NiFiUser user = NiFiUserUtils.getNiFiUser(); return withWriteLock(serviceFacade, authorizer, verifier, action, - () -> serviceFacade.verifyRevision(revision, user)); + () -> serviceFacade.verifyRevision(revision, user)); } /** @@ -476,23 +478,23 @@ public abstract class ApplicationResource { final Runnable verifier, final Supplier action) { final NiFiUser user = NiFiUserUtils.getNiFiUser(); return withWriteLock(serviceFacade, authorizer, verifier, action, - () -> serviceFacade.verifyRevisions(revisions, user)); + () -> serviceFacade.verifyRevisions(revisions, user)); } /** * Executes an action through the service facade using the specified revision. * - * @param serviceFacade service facade - * @param authorizer authorizer - * @param verifier verifier - * @param action the action to execute + * @param serviceFacade service facade + * @param authorizer authorizer + * @param verifier verifier + * @param action the action to execute * @param verifyRevision a callback that will claim the necessary revisions for the operation * @return the response */ private Response withWriteLock( final NiFiServiceFacade serviceFacade, final AuthorizeAccess authorizer, final Runnable verifier, final Supplier action, - final Runnable verifyRevision) { + final Runnable verifyRevision) { final boolean validationPhase = isValidationPhase(httpServletRequest); if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { @@ -570,7 +572,7 @@ public abstract class ApplicationResource { } else { headers.put(RequestReplicator.REPLICATION_TARGET_NODE_UUID_HEADER, nodeId.getId()); return requestReplicator.replicate(Collections.singleton(getClusterCoordinatorNode()), method, - path, entity, headers, false, true).awaitMergedResponse().getResponse(); + path, entity, headers, false, true).awaitMergedResponse().getResponse(); } } catch (final InterruptedException ie) { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Request to " + method + " " + path + " was interrupted").type("text/plain").build(); @@ -663,8 +665,8 @@ public abstract class ApplicationResource { * used will be those provided by the {@link #getHeaders()} method. The URI that will be used will be * that provided by the {@link #getAbsolutePath()} method * - * @param method the HTTP method to use - * @param entity the entity to replicate + * @param method the HTTP method to use + * @param entity the entity to replicate * @param headersToOverride the headers to override * @return the response from the request * @see #replicateNodeResponse(String, Object, Map) @@ -683,12 +685,10 @@ public abstract class ApplicationResource { * that provided by the {@link #getAbsolutePath()} method. This method returns the NodeResponse, * rather than a Response object. * - * @param method the HTTP method to use - * @param entity the entity to replicate + * @param method the HTTP method to use + * @param entity the entity to replicate * @param headersToOverride the headers to override - * * @return the response from the request - * * @throws InterruptedException if interrupted while replicating the request * @see #replicate(String, Object, Map) */ @@ -851,7 +851,7 @@ public abstract class ApplicationResource { } public Response handshakeExceptionResponse(HandshakeException e) { - if(logger.isDebugEnabled()){ + if (logger.isDebugEnabled()) { logger.debug("Handshake failed, {}", e.getMessage()); } ResponseCode handshakeRes = e.getResponseCode(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java index 06bba2a02a..f7fdadfa72 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java @@ -32,8 +32,6 @@ import org.apache.nifi.connectable.Connectable; import org.apache.nifi.web.NiFiServiceFacade; import org.apache.nifi.web.Revision; import org.apache.nifi.web.api.dto.ConnectionDTO; -import org.apache.nifi.web.api.dto.FlowFileSummaryDTO; -import org.apache.nifi.web.api.dto.ListingRequestDTO; import org.apache.nifi.web.api.entity.ConnectionEntity; import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.LongParameter; @@ -59,8 +57,8 @@ import java.util.Set; */ @Path("/connections") @Api( - value = "/connections", - description = "Endpoint for managing a Connection." + value = "/connections", + description = "Endpoint for managing a Connection." ) public class ConnectionResource extends ApplicationResource { @@ -87,42 +85,10 @@ public class ConnectionResource extends ApplicationResource { * @return dto */ public ConnectionEntity populateRemainingConnectionEntityContent(ConnectionEntity connectionEntity) { - connectionEntity.setUri(generateResourceUri("connections", connectionEntity.getId())); + connectionEntity.setUri(generateResourceUri("connections", connectionEntity.getId())); return connectionEntity; } - /** - * Populate the URIs for the specified flowfile listing. - * - * @param connectionId connection - * @param flowFileListing flowfile listing - * @return dto - */ - public ListingRequestDTO populateRemainingFlowFileListingContent(final String connectionId, final ListingRequestDTO flowFileListing) { - // uri of the listing - flowFileListing.setUri(generateResourceUri("connections", connectionId, "listing-requests", flowFileListing.getId())); - - // uri of each flowfile - if (flowFileListing.getFlowFileSummaries() != null) { - for (final FlowFileSummaryDTO flowFile : flowFileListing.getFlowFileSummaries()) { - populateRemainingFlowFileContent(connectionId, flowFile); - } - } - return flowFileListing; - } - - /** - * Populate the URIs for the specified flowfile. - * - * @param connectionId the connection id - * @param flowFile the flowfile - * @return the dto - */ - public FlowFileSummaryDTO populateRemainingFlowFileContent(final String connectionId, final FlowFileSummaryDTO flowFile) { - flowFile.setUri(generateResourceUri("connections", connectionId, "flowfiles", flowFile.getUuid())); - return flowFile; - } - /** * Retrieves the specified connection. * @@ -134,23 +100,21 @@ public class ConnectionResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a connection", response = ConnectionEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read Source - /{component-type}/{uuid}", type = ""), + @Authorization(value = "Read Destination - /{component-type}/{uuid}", type = "") } ) @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.") + @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 getConnection( @@ -158,7 +122,7 @@ public class ConnectionResource extends ApplicationResource { value = "The connection id.", required = true ) - @PathParam("id") final String id) throws InterruptedException { + @PathParam("id") final String id) throws InterruptedException { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -183,8 +147,8 @@ public class ConnectionResource extends ApplicationResource { * Updates the specified connection. * * @param httpServletRequest request - * @param id The id of the connection. - * @param connectionEntity A connectionEntity. + * @param id The id of the connection. + * @param connectionEntity A connectionEntity. * @return A connectionEntity. * @throws InterruptedException if interrupted */ @@ -192,21 +156,23 @@ public class ConnectionResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a connection", response = ConnectionEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write Source - /{component-type}/{uuid}", type = ""), + @Authorization(value = "Write Destination - /{component-type}/{uuid}", type = ""), + @Authorization(value = "Write New Destination - /{component-type}/{uuid} - if updating Destination", type = ""), + @Authorization(value = "Write Process Group - /process-groups/{uuid} - if updating Destination", type = "") } ) @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.") + @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 updateConnection( @@ -219,7 +185,7 @@ public class ConnectionResource extends ApplicationResource { @ApiParam( value = "The connection configuration details.", required = true - ) final ConnectionEntity connectionEntity) throws InterruptedException { + ) final ConnectionEntity connectionEntity) throws InterruptedException { if (connectionEntity == null || connectionEntity.getComponent() == null) { throw new IllegalArgumentException("Connection details must be specified."); @@ -247,41 +213,41 @@ public class ConnectionResource extends ApplicationResource { final Revision revision = getRevision(connectionEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - // verifies write access to this connection (this checks the current source and destination) - ConnectionAuthorizable connAuth = lookup.getConnection(id); - connAuth.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + serviceFacade, + revision, + lookup -> { + // verifies write access to this connection (this checks the current source and destination) + ConnectionAuthorizable connAuth = lookup.getConnection(id); + connAuth.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - // if a destination has been specified and is different - final Connectable currentDestination = connAuth.getDestination(); - if (connection.getDestination() != null && currentDestination.getIdentifier().equals(connection.getDestination().getId())) { - // verify access of the new destination (current destination was already authorized as part of the connection check) - final Authorizable newDestinationAuthorizable = lookup.getConnectable(connection.getDestination().getId()); - newDestinationAuthorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + // if a destination has been specified and is different + final Connectable currentDestination = connAuth.getDestination(); + if (connection.getDestination() != null && currentDestination.getIdentifier().equals(connection.getDestination().getId())) { + // verify access of the new destination (current destination was already authorized as part of the connection check) + final Authorizable newDestinationAuthorizable = lookup.getConnectable(connection.getDestination().getId()); + newDestinationAuthorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - // verify access of the parent group (this is the same check that is performed when creating the connection) - connAuth.getParentGroup().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - } - }, - () -> serviceFacade.verifyUpdateConnection(connection), - () -> { - final ConnectionEntity entity = serviceFacade.updateConnection(revision, connection); - populateRemainingConnectionEntityContent(entity); + // verify access of the parent group (this is the same check that is performed when creating the connection) + connAuth.getParentGroup().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + } + }, + () -> serviceFacade.verifyUpdateConnection(connection), + () -> { + final ConnectionEntity entity = serviceFacade.updateConnection(revision, connection); + populateRemainingConnectionEntityContent(entity); - // generate the response - return clusterContext(generateOkResponse(entity)).build(); - }); + // generate the response + return clusterContext(generateOkResponse(entity)).build(); + }); } /** * Removes the specified connection. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the connection. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the connection. * @return An Entity containing the client id and an updated revision. * @throws InterruptedException if interrupted */ @@ -289,21 +255,21 @@ public class ConnectionResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a connection", response = ConnectionEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write Source - /{component-type}/{uuid}", type = ""), + @Authorization(value = "Write Destination - /{component-type}/{uuid}", type = "") } ) @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.") + @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 deleteConnection( @@ -322,7 +288,7 @@ public class ConnectionResource extends ApplicationResource { value = "The connection id.", required = true ) - @PathParam("id") final String id) throws InterruptedException { + @PathParam("id") final String id) throws InterruptedException { if (isReplicateRequest()) { return replicate(HttpMethod.DELETE); @@ -334,21 +300,21 @@ public class ConnectionResource extends ApplicationResource { // get the current user return withWriteLock( - serviceFacade, - revision, - lookup -> { - // verifies write access to the source and destination - final Authorizable authorizable = lookup.getConnection(id).getAuthorizable(); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteConnection(id), - () -> { - // delete the connection - final ConnectionEntity entity = serviceFacade.deleteConnection(revision, id); + serviceFacade, + revision, + lookup -> { + // verifies write access to the source and destination + final Authorizable authorizable = lookup.getConnection(id).getAuthorizable(); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteConnection(id), + () -> { + // delete the connection + final ConnectionEntity entity = serviceFacade.deleteConnection(revision, id); - // generate the response - return clusterContext(generateOkResponse(entity)).build(); - } + // generate the response + return clusterContext(generateOkResponse(entity)).build(); + } ); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java index 7a5dab74f5..e622b04d2a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java @@ -16,25 +16,13 @@ */ package org.apache.nifi.web.api; -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HttpMethod; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - +import com.sun.jersey.api.core.ResourceContext; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; +import com.wordnik.swagger.annotations.Authorization; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.authorization.AccessDeniedException; import org.apache.nifi.authorization.AuthorizationRequest; @@ -60,21 +48,31 @@ import org.apache.nifi.web.api.entity.NodeEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; import org.apache.nifi.web.api.request.DateTimeParameter; -import com.sun.jersey.api.core.ResourceContext; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; -import com.wordnik.swagger.annotations.ApiParam; -import com.wordnik.swagger.annotations.ApiResponse; -import com.wordnik.swagger.annotations.ApiResponses; -import com.wordnik.swagger.annotations.Authorization; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HttpMethod; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; /** * RESTful endpoint for managing a Flow Controller. */ @Path("/controller") @Api( - value = "/controller", - description = "Provides realtime command and control of this NiFi instance" + value = "/controller", + description = "Provides realtime command and control of this NiFi instance" ) public class ControllerResource extends ApplicationResource { @@ -93,7 +91,7 @@ public class ControllerResource extends ApplicationResource { private void authorizeController(final RequestAction action) { final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Map userContext; + final Map userContext; if (!StringUtils.isBlank(user.getClientAddress())) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -126,23 +124,19 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("config") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN', 'ROLE_NIFI')") @ApiOperation( value = "Retrieves the configuration for this NiFi Controller", response = ControllerConfigurationEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN"), - @Authorization(value = "ROLE_NIFI", type = "ROLE_NIFI") + @Authorization(value = "Read - /controller", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getControllerConfig() { @@ -161,27 +155,26 @@ public class ControllerResource extends ApplicationResource { * Update the configuration for this NiFi. * * @param httpServletRequest request - * @param configEntity A controllerConfigurationEntity. + * @param configEntity A controllerConfigurationEntity. * @return A controllerConfigurationEntity. */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("config") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Retrieves the configuration for this NiFi", response = ControllerConfigurationEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /controller", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response updateControllerConfig( @@ -225,7 +218,7 @@ public class ControllerResource extends ApplicationResource { /** * Creates a new Reporting Task. * - * @param httpServletRequest request + * @param httpServletRequest request * @param reportingTaskEntity A reportingTaskEntity. * @return A reportingTaskEntity. */ @@ -233,28 +226,27 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("reporting-tasks") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a new reporting task", - response = ReportingTaskEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a new reporting task", + response = ReportingTaskEntity.class, + authorizations = { + @Authorization(value = "Write - /controller", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) public Response createReportingTask( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The reporting task configuration details.", - required = true - ) final ReportingTaskEntity reportingTaskEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The reporting task configuration details.", + required = true + ) final ReportingTaskEntity reportingTaskEntity) { if (reportingTaskEntity == null || reportingTaskEntity.getComponent() == null) { throw new IllegalArgumentException("Reporting task details must be specified."); @@ -307,7 +299,7 @@ public class ControllerResource extends ApplicationResource { /** * Creates a new Controller Service. * - * @param httpServletRequest request + * @param httpServletRequest request * @param controllerServiceEntity A controllerServiceEntity. * @return A controllerServiceEntity. */ @@ -315,28 +307,27 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("controller-services") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a new controller service", - response = ControllerServiceEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a new controller service", + response = ControllerServiceEntity.class, + authorizations = { + @Authorization(value = "Write - /controller", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) public Response createControllerService( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The controller service configuration details.", - required = true - ) final ControllerServiceEntity controllerServiceEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The controller service configuration details.", + required = true + ) final ControllerServiceEntity controllerServiceEntity) { if (controllerServiceEntity == null || controllerServiceEntity.getComponent() == null) { throw new IllegalArgumentException("Controller service details must be specified."); @@ -395,15 +386,12 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("cluster") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the contents of the cluster", notes = "Returns the contents of the cluster including all nodes and their status.", response = ClusterEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "DFM", type = "ROLE_DFM"), - @Authorization(value = "Admin", type = "ROLE_ADMIN") + @Authorization(value = "Read - /controller", type = "") } ) @ApiResponses( @@ -447,14 +435,11 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("cluster/nodes/{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a node in the cluster", response = NodeEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /controller", type = "") } ) @ApiResponses( @@ -494,7 +479,7 @@ public class ControllerResource extends ApplicationResource { /** * Updates the contents of the specified node in this NiFi cluster. * - * @param id The id of the node + * @param id The id of the node * @param nodeEntity A nodeEntity * @return A nodeEntity */ @@ -507,7 +492,7 @@ public class ControllerResource extends ApplicationResource { value = "Updates a node in the cluster", response = NodeEntity.class, authorizations = { - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /controller", type = "") } ) @ApiResponses( @@ -573,12 +558,11 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("cluster/nodes/{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')") @ApiOperation( value = "Removes a node from the cluster", response = NodeEntity.class, authorizations = { - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /controller", type = "") } ) @ApiResponses( @@ -631,12 +615,11 @@ public class ControllerResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("history") - // TODO - @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation( value = "Purges history", response = HistoryEntity.class, authorizations = { - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /controller", type = "") } ) @ApiResponses( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java index 4eb1d1ae2e..51d732c1f6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java @@ -75,8 +75,8 @@ import java.util.stream.Collectors; */ @Path("/controller-services") @Api( - value = "/controller-services", - description = "Endpoint for managing a Controller Service." + value = "/controller-services", + description = "Endpoint for managing a Controller Service." ) public class ControllerServiceResource extends ApplicationResource { @@ -148,23 +148,20 @@ public class ControllerServiceResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a controller service", response = ControllerServiceEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /controller-services/{uuid}", type = "") } ) @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.") + @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 getControllerService( @@ -194,7 +191,7 @@ public class ControllerServiceResource extends ApplicationResource { /** * Returns the descriptor for the specified property. * - * @param id The id of the controller service. + * @param id The id of the controller service. * @param propertyName The property * @return a propertyDescriptorEntity */ @@ -202,23 +199,20 @@ public class ControllerServiceResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/descriptors") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a controller service property descriptor", response = PropertyDescriptorEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /controller-services/{uuid}", type = "") } ) @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.") + @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 getPropertyDescriptor( @@ -269,29 +263,28 @@ public class ControllerServiceResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/state") - // TODO - @PreAuthorize("hasAnyRole('ROLE_DFM')") @ApiOperation( - value = "Gets the state for a controller service", - response = ComponentStateDTO.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Gets the state for a controller service", + response = ComponentStateDTO.class, + authorizations = { + @Authorization(value = "Write - /controller-services/{uuid}", type = "") + } ) @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.") - } + 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 getState( - @ApiParam( - value = "The controller service id.", - required = true - ) - @PathParam("id") final String id) { + @ApiParam( + value = "The controller service id.", + required = true + ) + @PathParam("id") final String id) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -318,37 +311,36 @@ public class ControllerServiceResource extends ApplicationResource { * Clears the state for a controller service. * * @param httpServletRequest servlet request - * @param id The id of the controller service + * @param id The id of the controller service * @return a componentStateEntity */ @POST @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/state/clear-requests") - // TODO - @PreAuthorize("hasAnyRole('ROLE_DFM')") @ApiOperation( - value = "Clears the state for a controller service", - response = ComponentStateDTO.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Clears the state for a controller service", + response = ComponentStateDTO.class, + authorizations = { + @Authorization(value = "Write - /controller-services/{uuid}", type = "") + } ) @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.") - } + 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 clearState( - @Context HttpServletRequest httpServletRequest, - @ApiParam( - value = "The controller service id.", - required = true - ) - @PathParam("id") final String id) { + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The controller service id.", + required = true + ) + @PathParam("id") final String id) { if (isReplicateRequest()) { return replicate(HttpMethod.POST); @@ -358,8 +350,8 @@ public class ControllerServiceResource extends ApplicationResource { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { // authorize access serviceFacade.authorizeAccess(lookup -> { - final Authorizable processor = lookup.getControllerService(id); - processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + final Authorizable controllerService = lookup.getControllerService(id); + controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }); } if (validationPhase) { @@ -387,23 +379,20 @@ public class ControllerServiceResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/references") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a controller service", response = ControllerServiceEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /controller-services/{uuid}", type = "") } ) @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.") + @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 getControllerServiceReferences( @@ -432,7 +421,7 @@ public class ControllerServiceResource extends ApplicationResource { /** * Updates the references of the specified controller service. * - * @param httpServletRequest request + * @param httpServletRequest request * @param updateReferenceRequest The update request * @return A controllerServiceReferencingComponentsEntity. */ @@ -440,33 +429,32 @@ public class ControllerServiceResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/references") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a controller services references", response = ControllerServiceReferencingComponentsEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /{component-type}/{uuid} - For each referencing component specified", type = "") } ) @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.") + @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 updateControllerServiceReferences( @Context final HttpServletRequest httpServletRequest, @ApiParam( - value = "The controller service id.", - required = true + value = "The controller service id.", + required = true ) @PathParam("id") final String id, @ApiParam( - value = "The controller service request update request.", - required = true + value = "The controller service request update request.", + required = true ) final UpdateControllerServiceReferenceRequestEntity updateReferenceRequest) { if (updateReferenceRequest.getId() == null) { @@ -504,7 +492,7 @@ public class ControllerServiceResource extends ApplicationResource { // ensure the controller service state is not ENABLING or DISABLING if (requestControllerServiceState != null - && (ControllerServiceState.ENABLING.equals(requestControllerServiceState) || ControllerServiceState.DISABLING.equals(requestControllerServiceState))) { + && (ControllerServiceState.ENABLING.equals(requestControllerServiceState) || ControllerServiceState.DISABLING.equals(requestControllerServiceState))) { throw new IllegalArgumentException("Cannot set the referencing services to ENABLING or DISABLING"); } @@ -515,39 +503,39 @@ public class ControllerServiceResource extends ApplicationResource { // convert the referencing revisions final Map referencingRevisions = updateReferenceRequest.getReferencingComponentRevisions().entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> { - final RevisionDTO rev = e.getValue(); - return new Revision(rev.getVersion(), rev.getClientId(), e.getKey()); - })); + .collect(Collectors.toMap(Map.Entry::getKey, e -> { + final RevisionDTO rev = e.getValue(); + return new Revision(rev.getVersion(), rev.getClientId(), e.getKey()); + })); final Set revisions = new HashSet<>(referencingRevisions.values()); final ScheduledState scheduledState = requestScheduledState; final ControllerServiceState controllerServiceState = requestControllerServiceState; return withWriteLock( - serviceFacade, - revisions, - lookup -> { - referencingRevisions.entrySet().stream().forEach(e -> { - final Authorizable controllerService = lookup.getControllerServiceReferencingComponent(id, e.getKey()); - controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }); - }, - () -> serviceFacade.verifyUpdateControllerServiceReferencingComponents(updateReferenceRequest.getId(), scheduledState, controllerServiceState), - () -> { - // update the controller service references - final ControllerServiceReferencingComponentsEntity entity = serviceFacade.updateControllerServiceReferencingComponents( - referencingRevisions, updateReferenceRequest.getId(), scheduledState, controllerServiceState); + serviceFacade, + revisions, + lookup -> { + referencingRevisions.entrySet().stream().forEach(e -> { + final Authorizable controllerService = lookup.getControllerServiceReferencingComponent(id, e.getKey()); + controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }); + }, + () -> serviceFacade.verifyUpdateControllerServiceReferencingComponents(updateReferenceRequest.getId(), scheduledState, controllerServiceState), + () -> { + // update the controller service references + final ControllerServiceReferencingComponentsEntity entity = serviceFacade.updateControllerServiceReferencingComponents( + referencingRevisions, updateReferenceRequest.getId(), scheduledState, controllerServiceState); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } /** * Updates the specified a new Controller Service. * - * @param httpServletRequest request - * @param id The id of the controller service to update. + * @param httpServletRequest request + * @param id The id of the controller service to update. * @param controllerServiceEntity A controllerServiceEntity. * @return A controllerServiceEntity. */ @@ -555,21 +543,20 @@ public class ControllerServiceResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a controller service", response = ControllerServiceEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /controller-services/{uuid}", type = "") } ) @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.") + @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 updateControllerService( @@ -606,20 +593,20 @@ public class ControllerServiceResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(controllerServiceEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getControllerService(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO), - () -> { - // update the controller service - final ControllerServiceEntity entity = serviceFacade.updateControllerService(revision, requestControllerServiceDTO); - populateRemainingControllerServiceEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getControllerService(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO), + () -> { + // update the controller service + final ControllerServiceEntity entity = serviceFacade.updateControllerService(revision, requestControllerServiceDTO); + populateRemainingControllerServiceEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -627,33 +614,32 @@ public class ControllerServiceResource extends ApplicationResource { * Removes the specified controller service. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with - * the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a - * new one will be generated. This value (whether specified or generated) is - * included in the response. - * @param id The id of the controller service to remove. + * @param version The revision is used to verify the client is working with + * the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a + * new one will be generated. This value (whether specified or generated) is + * included in the response. + * @param id The id of the controller service to remove. * @return A entity containing the client id and an updated revision. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a controller service", response = ControllerServiceEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /controller-services/{uuid}", type = "") } ) @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.") + @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 removeControllerService( @@ -681,18 +667,18 @@ public class ControllerServiceResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable controllerService = lookup.getControllerService(id); - controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteControllerService(id), - () -> { - // delete the specified controller service - final ControllerServiceEntity entity = serviceFacade.deleteControllerService(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable controllerService = lookup.getControllerService(id); + controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteControllerService(id), + () -> { + // delete the specified controller service + final ControllerServiceEntity entity = serviceFacade.deleteControllerService(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java index 26a708c81d..4a6667731b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java @@ -42,7 +42,6 @@ import org.apache.nifi.web.api.dto.CounterDTO; import org.apache.nifi.web.api.dto.CountersDTO; import org.apache.nifi.web.api.entity.CounterEntity; import org.apache.nifi.web.api.entity.CountersEntity; -import org.apache.nifi.web.api.entity.Entity; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -85,7 +84,7 @@ public class CountersResource extends ApplicationResource { private void authorizeCounters(final RequestAction action) { final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Map userContext; + final Map userContext; if (!StringUtils.isBlank(user.getClientAddress())) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -119,14 +118,12 @@ public class CountersResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("") // necessary due to a bug in swagger - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the current counters for this NiFi", - response = Entity.class, + notes = NON_GUARANTEED_ENDPOINT, + response = CountersEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /counters", type = "") } ) @ApiResponses( @@ -204,7 +201,7 @@ public class CountersResource extends ApplicationResource { * Update the specified counter. This will reset the counter value to 0. * * @param httpServletRequest request - * @param id The id of the counter. + * @param id The id of the counter. * @return A counterEntity. */ @PUT @@ -214,9 +211,10 @@ public class CountersResource extends ApplicationResource { // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates the specified counter. This will reset the counter value to 0", + notes = NON_GUARANTEED_ENDPOINT, response = CounterEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /counters", type = "") } ) @ApiResponses( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/DataTransferResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/DataTransferResource.java index e2de588a68..d5e7d36497 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/DataTransferResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/DataTransferResource.java @@ -119,7 +119,7 @@ public class DataTransferResource extends ApplicationResource { /** * Authorizes access to data transfers. - * + *

* Note: Protected for testing purposes */ protected void authorizeDataTransfer(final ResourceType resourceType, final String identifier) { @@ -129,7 +129,7 @@ public class DataTransferResource extends ApplicationResource { throw new IllegalArgumentException("The resource must be an Input or Output Port."); } - final Map userContext; + final Map userContext; if (user.getClientAddress() != null && !user.getClientAddress().trim().isEmpty()) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -137,7 +137,6 @@ public class DataTransferResource extends ApplicationResource { userContext = null; } - // TODO - use DataTransferAuthorizable after looking up underlying component for consistentency final Resource resource = ResourceFactory.getComponentResource(resourceType, identifier, identifier); final AuthorizationRequest request = new AuthorizationRequest.Builder() .resource(ResourceFactory.getDataTransferResource(resource)) @@ -158,14 +157,11 @@ public class DataTransferResource extends ApplicationResource { @POST @Produces(MediaType.APPLICATION_JSON) @Path("{portType}/{portId}/transactions") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Create a transaction to the specified output port or input port", response = TransactionResultEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/{component-type}/{uuid}", type = "") } ) @ApiResponses( @@ -192,7 +188,7 @@ public class DataTransferResource extends ApplicationResource { InputStream inputStream) { - if(!PORT_TYPE_INPUT.equals(portType) && !PORT_TYPE_OUTPUT.equals(portType)){ + if (!PORT_TYPE_INPUT.equals(portType) && !PORT_TYPE_OUTPUT.equals(portType)) { return responseCreator.wrongPortTypeResponse(portType, portId); } @@ -235,14 +231,11 @@ public class DataTransferResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.TEXT_PLAIN) @Path("input-ports/{portId}/transactions/{transactionId}/flow-files") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Transfer flow files to the input port", response = String.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/input-ports/{uuid}", type = "") } ) @ApiResponses( @@ -301,7 +294,7 @@ public class DataTransferResource extends ApplicationResource { return responseCreator.unexpectedErrorResponse(portId, e); } - String serverChecksum = ((HttpServerCommunicationsSession)peer.getCommunicationsSession()).getChecksum(); + String serverChecksum = ((HttpServerCommunicationsSession) peer.getCommunicationsSession()).getChecksum(); return responseCreator.acceptedResponse(transactionManager, serverChecksum, transportProtocolVersion); } @@ -379,14 +372,11 @@ public class DataTransferResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) @Path("output-ports/{portId}/transactions/{transactionId}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Commit or cancel the specified transaction", response = TransactionResultEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/output-ports/{uuid}", type = "") } ) @ApiResponses( @@ -445,12 +435,12 @@ public class DataTransferResource extends ApplicationResource { String inputErrMessage = null; if (responseCode == null) { inputErrMessage = "responseCode is required."; - } else if(ResponseCode.CONFIRM_TRANSACTION.getCode() != responseCode + } else if (ResponseCode.CONFIRM_TRANSACTION.getCode() != responseCode && ResponseCode.CANCEL_TRANSACTION.getCode() != responseCode) { inputErrMessage = "responseCode " + responseCode + " is invalid. "; } - if (inputErrMessage != null){ + if (inputErrMessage != null) { entity.setMessage(inputErrMessage); entity.setResponseCode(ResponseCode.ABORT.getCode()); return Response.status(Response.Status.BAD_REQUEST).entity(entity).build(); @@ -470,7 +460,7 @@ public class DataTransferResource extends ApplicationResource { } catch (Exception e) { HttpServerCommunicationsSession commsSession = (HttpServerCommunicationsSession) peer.getCommunicationsSession(); logger.error("Failed to process the request", e); - if(ResponseCode.BAD_CHECKSUM.equals(commsSession.getResponseCode())){ + if (ResponseCode.BAD_CHECKSUM.equals(commsSession.getResponseCode())) { entity.setResponseCode(commsSession.getResponseCode().getCode()); entity.setMessage(e.getMessage()); @@ -489,14 +479,11 @@ public class DataTransferResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_JSON) @Path("input-ports/{portId}/transactions/{transactionId}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Commit or cancel the specified transaction", response = TransactionResultEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/input-ports/{uuid}", type = "") } ) @ApiResponses( @@ -552,13 +539,13 @@ public class DataTransferResource extends ApplicationResource { String inputErrMessage = null; if (responseCode == null) { inputErrMessage = "responseCode is required."; - } else if(ResponseCode.BAD_CHECKSUM.getCode() != responseCode + } else if (ResponseCode.BAD_CHECKSUM.getCode() != responseCode && ResponseCode.CONFIRM_TRANSACTION.getCode() != responseCode && ResponseCode.CANCEL_TRANSACTION.getCode() != responseCode) { inputErrMessage = "responseCode " + responseCode + " is invalid. "; } - if (inputErrMessage != null){ + if (inputErrMessage != null) { entity.setMessage(inputErrMessage); entity.setResponseCode(ResponseCode.ABORT.getCode()); return Response.status(Response.Status.BAD_REQUEST).entity(entity).build(); @@ -575,8 +562,8 @@ public class DataTransferResource extends ApplicationResource { entity.setResponseCode(commsSession.getResponseCode().getCode()); entity.setFlowFileSent(flowFileSent); - } catch (IOException e){ - if (ResponseCode.BAD_CHECKSUM.getCode() == responseCode && e.getMessage().contains("Received a BadChecksum response")){ + } catch (IOException e) { + if (ResponseCode.BAD_CHECKSUM.getCode() == responseCode && e.getMessage().contains("Received a BadChecksum response")) { // AbstractFlowFileServerProtocol throws IOException after it canceled transaction. // This is a known behavior and if we return 500 with this exception, // it's not clear if there is an issue at server side, or cancel operation has been accomplished. @@ -610,14 +597,11 @@ public class DataTransferResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_OCTET_STREAM) @Path("output-ports/{portId}/transactions/{transactionId}/flow-files") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Transfer flow files from the output port", response = StreamingOutput.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/output-ports/{uuid}", type = "") } ) @ApiResponses( @@ -665,13 +649,13 @@ public class DataTransferResource extends ApplicationResource { @Override public void write(OutputStream outputStream) throws IOException, WebApplicationException { - HttpOutput output = (HttpOutput)peer.getCommunicationsSession().getOutput(); + HttpOutput output = (HttpOutput) peer.getCommunicationsSession().getOutput(); output.setOutputStream(outputStream); try { int numOfFlowFiles = serverProtocol.getPort().transferFlowFiles(peer, serverProtocol); logger.debug("finished transferring flow files, numOfFlowFiles={}", numOfFlowFiles); - if(numOfFlowFiles < 1){ + if (numOfFlowFiles < 1) { // There was no flow file to transfer. Throw this exception to stop responding with SEE OTHER. throw new WebApplicationException(Response.Status.OK); } @@ -697,14 +681,11 @@ public class DataTransferResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("input-ports/{portId}/transactions/{transactionId}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Extend transaction TTL", response = TransactionResultEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/input-ports/{uuid}", type = "") } ) @ApiResponses( @@ -735,14 +716,11 @@ public class DataTransferResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("output-ports/{portId}/transactions/{transactionId}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Extend transaction TTL", response = TransactionResultEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Write - /data-transfer/output-ports/{uuid}", type = "") } ) @ApiResponses( @@ -785,7 +763,7 @@ public class DataTransferResource extends ApplicationResource { return validationResult.errResponse; } - if(!PORT_TYPE_INPUT.equals(portType) && !PORT_TYPE_OUTPUT.equals(portType)){ + if (!PORT_TYPE_INPUT.equals(portType) && !PORT_TYPE_OUTPUT.equals(portType)) { return responseCreator.wrongPortTypeResponse(portType, portId); } @@ -826,7 +804,7 @@ public class DataTransferResource extends ApplicationResource { private ValidateRequestResult validateResult(HttpServletRequest req, String portId, String transactionId) { ValidateRequestResult result = new ValidateRequestResult(); - if(!properties.isSiteToSiteHttpEnabled()) { + if (!properties.isSiteToSiteHttpEnabled()) { result.errResponse = responseCreator.httpSiteToSiteIsNotEnabledResponse(); return result; } @@ -838,9 +816,9 @@ public class DataTransferResource extends ApplicationResource { return result; } - if(!isEmpty(transactionId) && !transactionManager.isTransactionActive(transactionId)) { + if (!isEmpty(transactionId) && !transactionManager.isTransactionActive(transactionId)) { result.errResponse = responseCreator.transactionNotFoundResponse(portId, transactionId); - return result; + return result; } return result; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowFileQueueResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowFileQueueResource.java index e5c10ba593..69b2567c30 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowFileQueueResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowFileQueueResource.java @@ -69,8 +69,8 @@ import java.net.URI; */ @Path("/flowfile-queues") @Api( - value = "/flowfile-queues", - description = "Endpoint for managing a FlowFile Queue." + value = "/flowfile-queues", + description = "Endpoint for managing a FlowFile Queue." ) public class FlowFileQueueResource extends ApplicationResource { @@ -80,7 +80,7 @@ public class FlowFileQueueResource extends ApplicationResource { /** * Populate the URIs for the specified flowfile listing. * - * @param connectionId connection + * @param connectionId connection * @param flowFileListing flowfile listing * @return dto */ @@ -101,7 +101,7 @@ public class FlowFileQueueResource extends ApplicationResource { * Populate the URIs for the specified flowfile. * * @param connectionId the connection id - * @param flowFile the flowfile + * @param flowFile the flowfile * @return the dto */ public FlowFileSummaryDTO populateRemainingFlowFileContent(final String connectionId, final FlowFileSummaryDTO flowFile) { @@ -112,8 +112,8 @@ public class FlowFileQueueResource extends ApplicationResource { /** * Gets the specified flowfile from the specified connection. * - * @param connectionId The connection id - * @param flowFileUuid The flowfile uuid + * @param connectionId The connection id + * @param flowFileUuid The flowfile uuid * @param clusterNodeId The cluster node id where the flowfile resides * @return a flowFileDTO * @throws InterruptedException if interrupted @@ -122,38 +122,37 @@ public class FlowFileQueueResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/flowfiles/{flowfile-uuid}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Gets a FlowFile from a Connection.", - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Gets a FlowFile from a Connection.", + authorizations = { + @Authorization(value = "Read Source Data - /data/{component-type}/{uuid}", type = "") + } ) @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.") - } + 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 getFlowFile( @ApiParam( - value = "The connection id.", - required = true + value = "The connection id.", + required = true ) @PathParam("id") final String connectionId, @ApiParam( - value = "The flowfile uuid.", - required = true + value = "The flowfile uuid.", + required = true ) @PathParam("flowfile-uuid") final String flowFileUuid, @ApiParam( - value = "The id of the node where the content exists if clustered.", - required = false + value = "The id of the node where the content exists if clustered.", + required = false ) - @QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException { + @QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException { // replicate if cluster manager if (isReplicateRequest()) { @@ -187,9 +186,9 @@ public class FlowFileQueueResource extends ApplicationResource { /** * Gets the content for the specified flowfile in the specified connection. * - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param connectionId The connection id - * @param flowFileUuid The flowfile uuid + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param connectionId The connection id + * @param flowFileUuid The flowfile uuid * @param clusterNodeId The cluster node id * @return The content stream * @throws InterruptedException if interrupted @@ -198,43 +197,42 @@ public class FlowFileQueueResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.WILDCARD) @Path("{id}/flowfiles/{flowfile-uuid}/content") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Gets the content for a FlowFile in a Connection.", - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Gets the content for a FlowFile in a Connection.", + authorizations = { + @Authorization(value = "Read Source Data - /data/{component-type}/{uuid}", type = "") + } ) @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.") - } + 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 downloadFlowFileContent( @ApiParam( - value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", - required = false + value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", + required = false ) @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final ClientIdParameter clientId, @ApiParam( - value = "The connection id.", - required = true + value = "The connection id.", + required = true ) @PathParam("id") final String connectionId, @ApiParam( - value = "The flowfile uuid.", - required = true + value = "The flowfile uuid.", + required = true ) @PathParam("flowfile-uuid") final String flowFileUuid, @ApiParam( - value = "The id of the node where the content exists if clustered.", - required = false + value = "The id of the node where the content exists if clustered.", + required = false ) - @QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException { + @QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException { // replicate if cluster manager if (isReplicateRequest()) { @@ -287,36 +285,35 @@ public class FlowFileQueueResource extends ApplicationResource { * Creates a request to list the flowfiles in the queue of the specified connection. * * @param httpServletRequest request - * @param id The id of the connection + * @param id The id of the connection * @return A listRequestEntity */ @POST @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/listing-requests") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Lists the contents of the queue in this connection.", - response = ListingRequestEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Lists the contents of the queue in this connection.", + response = ListingRequestEntity.class, + authorizations = { + @Authorization(value = "Read Source Data - /data/{component-type}/{uuid}", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 202, message = "The request has been accepted. A HTTP response header will contain the URI where the response can be polled."), - @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.") - } + value = { + @ApiResponse(code = 202, message = "The request has been accepted. A HTTP response header will contain the URI where the response can be polled."), + @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 createFlowFileListing( @Context final HttpServletRequest httpServletRequest, @ApiParam( - value = "The connection id.", - required = true + value = "The connection id.", + required = true ) @PathParam("id") final String id) { @@ -358,7 +355,7 @@ public class FlowFileQueueResource extends ApplicationResource { /** * Checks the status of an outstanding listing request. * - * @param connectionId The id of the connection + * @param connectionId The id of the connection * @param listingRequestId The id of the drop request * @return A dropRequestEntity */ @@ -366,32 +363,31 @@ public class FlowFileQueueResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/listing-requests/{listing-request-id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Gets the current status of a listing request for the specified connection.", - response = ListingRequestEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Gets the current status of a listing request for the specified connection.", + response = ListingRequestEntity.class, + authorizations = { + @Authorization(value = "Read Source Data - /data/{component-type}/{uuid}", type = "") + } ) @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.") - } + 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 getListingRequest( @ApiParam( - value = "The connection id.", - required = true + value = "The connection id.", + required = true ) @PathParam("id") final String connectionId, @ApiParam( - value = "The listing request id.", - required = true + value = "The listing request id.", + required = true ) @PathParam("listing-request-id") final String listingRequestId) { @@ -421,41 +417,40 @@ public class FlowFileQueueResource extends ApplicationResource { * Deletes the specified listing request. * * @param httpServletRequest request - * @param connectionId The connection id - * @param listingRequestId The drop request id + * @param connectionId The connection id + * @param listingRequestId The drop request id * @return A dropRequestEntity */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/listing-requests/{listing-request-id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Cancels and/or removes a request to list the contents of this connection.", - response = DropRequestEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Cancels and/or removes a request to list the contents of this connection.", + response = DropRequestEntity.class, + authorizations = { + @Authorization(value = "Read Source Data - /data/{component-type}/{uuid}", type = "") + } ) @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.") - } + 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 deleteListingRequest( @Context final HttpServletRequest httpServletRequest, @ApiParam( - value = "The connection id.", - required = true + value = "The connection id.", + required = true ) @PathParam("id") final String connectionId, @ApiParam( - value = "The listing request id.", - required = true + value = "The listing request id.", + required = true ) @PathParam("listing-request-id") final String listingRequestId) { @@ -497,38 +492,37 @@ public class FlowFileQueueResource extends ApplicationResource { * Creates a request to delete the flowfiles in the queue of the specified connection. * * @param httpServletRequest request - * @param id The id of the connection + * @param id The id of the connection * @return A dropRequestEntity */ @POST @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/drop-requests") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a request to drop the contents of the queue in this connection.", - response = DropRequestEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a request to drop the contents of the queue in this connection.", + response = DropRequestEntity.class, + authorizations = { + @Authorization(value = "Write Source Data - /data/{component-type}/{uuid}", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 202, message = "The request has been accepted. A HTTP response header will contain the URI where the response can be polled."), - @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.") - } + value = { + @ApiResponse(code = 202, message = "The request has been accepted. A HTTP response header will contain the URI where the response can be polled."), + @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 createDropRequest( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The connection id.", - required = true - ) - @PathParam("id") final String id) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The connection id.", + required = true + ) + @PathParam("id") final String id) { if (isReplicateRequest()) { return replicate(HttpMethod.POST); @@ -567,7 +561,7 @@ public class FlowFileQueueResource extends ApplicationResource { /** * Checks the status of an outstanding drop request. * - * @param connectionId The id of the connection + * @param connectionId The id of the connection * @param dropRequestId The id of the drop request * @return A dropRequestEntity */ @@ -575,21 +569,20 @@ public class FlowFileQueueResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/drop-requests/{drop-request-id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Gets the current status of a drop request for the specified connection.", response = DropRequestEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write Source Data - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 getDropRequest( @@ -630,29 +623,28 @@ public class FlowFileQueueResource extends ApplicationResource { * Deletes the specified drop request. * * @param httpServletRequest request - * @param connectionId The connection id - * @param dropRequestId The drop request id + * @param connectionId The connection id + * @param dropRequestId The drop request id * @return A dropRequestEntity */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/drop-requests/{drop-request-id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Cancels and/or removes a request to drop the contents of this connection.", response = DropRequestEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write Source Data - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 removeDropRequest( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java index 96e7dbcdba..6cb29d0684 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java @@ -103,7 +103,6 @@ import org.apache.nifi.web.api.entity.StatusHistoryEntity; import org.apache.nifi.web.api.entity.TemplateEntity; import org.apache.nifi.web.api.entity.TemplatesEntity; import org.apache.nifi.web.api.request.BulletinBoardPatternParameter; -import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.DateTimeParameter; import org.apache.nifi.web.api.request.IntegerParameter; import org.apache.nifi.web.api.request.LongParameter; @@ -137,8 +136,8 @@ import java.util.stream.Collectors; */ @Path("/flow") @Api( - value = "/flow", - description = "Endpoint for accessing the flow structure and component status." + value = "/flow", + description = "Endpoint for accessing the flow structure and component status." ) public class FlowResource extends ApplicationResource { @@ -177,7 +176,7 @@ public class FlowResource extends ApplicationResource { } // set the process group uri - flow.setUri(generateResourceUri("flow", "process-groups", flow.getId())); + flow.setUri(generateResourceUri("flow", "process-groups", flow.getId())); return flow; } @@ -212,7 +211,7 @@ public class FlowResource extends ApplicationResource { private void authorizeFlow() { final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Map userContext; + final Map userContext; if (!StringUtils.isBlank(user.getClientAddress())) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -221,13 +220,13 @@ public class FlowResource extends ApplicationResource { } final AuthorizationRequest request = new AuthorizationRequest.Builder() - .resource(ResourceFactory.getFlowResource()) - .identity(user.getIdentity()) - .anonymous(user.isAnonymous()) - .accessAttempt(true) - .action(RequestAction.READ) - .userContext(userContext) - .build(); + .resource(ResourceFactory.getFlowResource()) + .identity(user.getIdentity()) + .anonymous(user.isAnonymous()) + .accessAttempt(true) + .action(RequestAction.READ) + .userContext(userContext) + .build(); final AuthorizationResult result = authorizer.authorize(request); if (!Result.Approved.equals(result.getResult())) { @@ -249,9 +248,7 @@ public class FlowResource extends ApplicationResource { value = "Generates a client id.", response = String.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -259,7 +256,6 @@ public class FlowResource extends ApplicationResource { @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.") } ) @@ -277,15 +273,11 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("config") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN', 'ROLE_NIFI')") @ApiOperation( value = "Retrieves the configuration for this NiFi flow", response = FlowConfigurationEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN"), - @Authorization(value = "ROLE_NIFI", type = "ROLE_NIFI") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -319,7 +311,10 @@ public class FlowResource extends ApplicationResource { @Path("current-user") @ApiOperation( value = "Retrieves the user identity of the user making the request", - response = CurrentUserEntity.class + response = CurrentUserEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) public Response getCurrentUser() { @@ -354,29 +349,27 @@ public class FlowResource extends ApplicationResource { @Produces(MediaType.APPLICATION_JSON) @Path("process-groups/{id}") @ApiOperation( - value = "Gets a process group", - response = ProcessGroupFlowEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets a process group", + response = ProcessGroupFlowEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getFlow( - @ApiParam( - value = "The process group id.", - required = false - ) - @PathParam("id") String groupId) throws InterruptedException { + @ApiParam( + value = "The process group id.", + required = false + ) + @PathParam("id") String groupId) throws InterruptedException { authorizeFlow(); @@ -403,23 +396,20 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("controller/controller-services") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all controller services", - response = ControllerServicesEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all controller services", + response = ControllerServicesEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) public Response getControllerServicesFromController() { @@ -451,30 +441,27 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("process-groups/{id}/controller-services") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all controller services", - response = ControllerServicesEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all controller services", + response = ControllerServicesEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) public Response getControllerServicesFromGroup( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") String groupId) throws InterruptedException { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String groupId) throws InterruptedException { authorizeFlow(); @@ -497,39 +484,28 @@ public class FlowResource extends ApplicationResource { /** * Retrieves all the of reporting tasks in this NiFi. * - * @param clientId Optional client id. If the client id is not specified, a - * new one will be generated. This value (whether specified or generated) is - * included in the response. * @return A reportingTasksEntity. */ @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("reporting-tasks") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all reporting tasks", - response = ReportingTasksEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all reporting tasks", + response = ReportingTasksEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) - public Response getReportingTasks( - @ApiParam( - value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", - required = false - ) - @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) { + public Response getReportingTasks() { authorizeFlow(); @@ -552,8 +528,8 @@ public class FlowResource extends ApplicationResource { /** * Updates the specified process group. * - * @param httpServletRequest request - * @param id The id of the process group. + * @param httpServletRequest request + * @param id The id of the process group. * @param scheduleComponentsEntity A scheduleComponentsEntity. * @return A processGroupEntity. */ @@ -561,38 +537,37 @@ public class FlowResource extends ApplicationResource { @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") - } + value = "Schedule or unschedule comopnents in the specified Process Group.", + notes = "", + response = ScheduleComponentsEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = ""), + @Authorization(value = "Write - /{component-type}/{uuid} - For every component being scheduled/unscheduled", type = "") + } ) @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.") - } + 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(); + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String id, + ScheduleComponentsEntity scheduleComponentsEntity) { // 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)); + + "not equal the process group id of the requested resource (%s).", scheduleComponentsEntity.getId(), id)); } final ScheduledState state; @@ -619,27 +594,27 @@ public class FlowResource extends ApplicationResource { // ensure authorized for each processor we will attempt to schedule group.findAllProcessors().stream() - .filter(ScheduledState.RUNNING.equals(state) ? ProcessGroup.SCHEDULABLE_PROCESSORS : ProcessGroup.UNSCHEDULABLE_PROCESSORS) - .filter(processor -> processor.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser())) - .forEach(processor -> { - componentIds.add(processor.getIdentifier()); - }); + .filter(ScheduledState.RUNNING.equals(state) ? ProcessGroup.SCHEDULABLE_PROCESSORS : ProcessGroup.UNSCHEDULABLE_PROCESSORS) + .filter(processor -> processor.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser())) + .forEach(processor -> { + componentIds.add(processor.getIdentifier()); + }); // ensure authorized for each input port we will attempt to schedule group.findAllInputPorts().stream() - .filter(ScheduledState.RUNNING.equals(state) ? ProcessGroup.SCHEDULABLE_PORTS : ProcessGroup.UNSCHEDULABLE_PORTS) - .filter(inputPort -> inputPort.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser())) - .forEach(inputPort -> { - componentIds.add(inputPort.getIdentifier()); - }); + .filter(ScheduledState.RUNNING.equals(state) ? ProcessGroup.SCHEDULABLE_PORTS : ProcessGroup.UNSCHEDULABLE_PORTS) + .filter(inputPort -> inputPort.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser())) + .forEach(inputPort -> { + componentIds.add(inputPort.getIdentifier()); + }); // ensure authorized for each output port we will attempt to schedule group.findAllOutputPorts().stream() - .filter(ScheduledState.RUNNING.equals(state) ? ProcessGroup.SCHEDULABLE_PORTS : ProcessGroup.UNSCHEDULABLE_PORTS) - .filter(outputPort -> outputPort.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser())) - .forEach(outputPort -> { - componentIds.add(outputPort.getIdentifier()); - }); + .filter(ScheduledState.RUNNING.equals(state) ? ProcessGroup.SCHEDULABLE_PORTS : ProcessGroup.UNSCHEDULABLE_PORTS) + .filter(outputPort -> outputPort.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser())) + .forEach(outputPort -> { + componentIds.add(outputPort.getIdentifier()); + }); return componentIds; }); @@ -666,21 +641,24 @@ public class FlowResource extends ApplicationResource { final Set revisions = new HashSet<>(componentRevisions.values()); return withWriteLock( - serviceFacade, - revisions, - lookup -> { - // ensure access to every component being scheduled - componentsToSchedule.keySet().forEach(componentId -> { - final Authorizable connectable = lookup.getConnectable(componentId); - connectable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }); - }, - () -> serviceFacade.verifyScheduleComponents(id, state, componentRevisions.keySet()), - () -> { - // update the process group - final ScheduleComponentsEntity entity = serviceFacade.scheduleComponents(id, state, componentRevisions); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revisions, + lookup -> { + // ensure access to the flow + authorizeFlow(); + + // ensure access to every component being scheduled + componentsToSchedule.keySet().forEach(componentId -> { + final Authorizable connectable = lookup.getConnectable(componentId); + connectable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }); + }, + () -> serviceFacade.verifyScheduleComponents(id, state, componentRevisions.keySet()), + () -> { + // update the process group + final ScheduleComponentsEntity entity = serviceFacade.scheduleComponents(id, state, componentRevisions); + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -699,22 +677,20 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("search-results") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Performs a search against this NiFi using the specified search term", + notes = "Only search results from authorized components will be returned.", response = SearchResultsEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response searchFlow(@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) throws InterruptedException { @@ -741,22 +717,19 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the current status of this NiFi", response = ControllerStatusEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getControllerStatus() throws InterruptedException { @@ -787,14 +760,11 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("cluster/summary") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the current status of this NiFi", response = ControllerStatusEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -846,14 +816,11 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("controller/bulletins") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves Controller level bulletins", response = ControllerBulletinsEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -886,22 +853,19 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("banners") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves the banners for this NiFi", response = BannerEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getBanners() { @@ -934,22 +898,20 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("processor-types") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves the types of processors that this NiFi supports", + notes = NON_GUARANTEED_ENDPOINT, response = ProcessorTypesEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getProcessorTypes() throws InterruptedException { @@ -974,22 +936,20 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("controller-service-types") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves the types of controller services that this NiFi supports", + notes = NON_GUARANTEED_ENDPOINT, response = ControllerServiceTypesEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getControllerServiceTypes( @@ -997,7 +957,8 @@ public class FlowResource extends ApplicationResource { value = "If specified, will only return controller services of this type.", required = false ) - @QueryParam("serviceType") String serviceType) throws InterruptedException { + @QueryParam("serviceType") String serviceType) throws InterruptedException { + authorizeFlow(); // create response entity @@ -1018,22 +979,20 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("reporting-task-types") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves the types of reporting tasks that this NiFi supports", + notes = NON_GUARANTEED_ENDPOINT, response = ReportingTaskTypesEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getReportingTaskTypes() throws InterruptedException { @@ -1057,22 +1016,20 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("prioritizers") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves the types of prioritizers that this NiFi supports", + notes = NON_GUARANTEED_ENDPOINT, response = PrioritizerTypesEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getPrioritizers() throws InterruptedException { @@ -1095,22 +1052,19 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("about") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Retrieves details about this NiFi to put in the About dialog", response = AboutEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getAboutInfo() { @@ -1118,7 +1072,7 @@ public class FlowResource extends ApplicationResource { // create the about dto final AboutDTO aboutDTO = new AboutDTO(); - aboutDTO.setTitle("NiFi"); // TODO - where to load title from + aboutDTO.setTitle("NiFi"); aboutDTO.setVersion(getProperties().getUiTitle()); aboutDTO.setUri(generateResourceUri()); @@ -1140,13 +1094,13 @@ public class FlowResource extends ApplicationResource { /** * Retrieves all the of bulletins in this NiFi. * - * @param after Supporting querying for bulletins after a particular - * bulletin id. - * @param limit The max number of bulletins to return. + * @param after Supporting querying for bulletins after a particular + * bulletin id. + * @param limit The max number of bulletins to return. * @param sourceName Source name filter. Supports a regular expression. - * @param message Message filter. Supports a regular expression. - * @param sourceId Source id filter. Supports a regular expression. - * @param groupId Group id filter. Supports a regular expression. + * @param message Message filter. Supports a regular expression. + * @param sourceId Source id filter. Supports a regular expression. + * @param groupId Group id filter. Supports a regular expression. * @return A bulletinBoardEntity. * @throws InterruptedException if interrupted */ @@ -1154,55 +1108,52 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("bulletin-board") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets current bulletins", - response = BulletinBoardEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets current bulletins", + response = BulletinBoardEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) public Response getBulletinBoard( - @ApiParam( - value = "Includes bulletins with an id after this value.", - required = false - ) - @QueryParam("after") LongParameter after, - @ApiParam( - value = "Includes bulletins originating from this sources whose name match this regular expression.", - required = false - ) - @QueryParam("sourceName") BulletinBoardPatternParameter sourceName, - @ApiParam( - value = "Includes bulletins whose message that match this regular expression.", - required = false - ) - @QueryParam("message") BulletinBoardPatternParameter message, - @ApiParam( - value = "Includes bulletins originating from this sources whose id match this regular expression.", - required = false - ) - @QueryParam("sourceId") BulletinBoardPatternParameter sourceId, - @ApiParam( - value = "Includes bulletins originating from this sources whose group id match this regular expression.", - required = false - ) - @QueryParam("groupId") BulletinBoardPatternParameter groupId, - @ApiParam( - value = "The number of bulletins to limit the response to.", - required = false - ) - @QueryParam("limit") IntegerParameter limit) throws InterruptedException { + @ApiParam( + value = "Includes bulletins with an id after this value.", + required = false + ) + @QueryParam("after") LongParameter after, + @ApiParam( + value = "Includes bulletins originating from this sources whose name match this regular expression.", + required = false + ) + @QueryParam("sourceName") BulletinBoardPatternParameter sourceName, + @ApiParam( + value = "Includes bulletins whose message that match this regular expression.", + required = false + ) + @QueryParam("message") BulletinBoardPatternParameter message, + @ApiParam( + value = "Includes bulletins originating from this sources whose id match this regular expression.", + required = false + ) + @QueryParam("sourceId") BulletinBoardPatternParameter sourceId, + @ApiParam( + value = "Includes bulletins originating from this sources whose group id match this regular expression.", + required = false + ) + @QueryParam("groupId") BulletinBoardPatternParameter groupId, + @ApiParam( + value = "The number of bulletins to limit the response to.", + required = false + ) + @QueryParam("limit") IntegerParameter limit) throws InterruptedException { authorizeFlow(); @@ -1259,41 +1210,38 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("processors/{id}/status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status for a processor", - response = ProcessorStatusEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status for a processor", + response = ProcessorStatusEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getProcessorStatus( - @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false - ) - @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, - @ApiParam( - value = "The id of the node where to get the status.", - required = false - ) - @QueryParam("clusterNodeId") String clusterNodeId, - @ApiParam( - value = "The processor id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false + ) + @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, + @ApiParam( + value = "The id of the node where to get the status.", + required = false + ) + @QueryParam("clusterNodeId") String clusterNodeId, + @ApiParam( + value = "The processor id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1341,41 +1289,38 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("input-ports/{id}/status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status for an input port", - response = PortStatusEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status for an input port", + response = PortStatusEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getInputPortStatus( - @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false - ) - @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, - @ApiParam( - value = "The id of the node where to get the status.", - required = false - ) - @QueryParam("clusterNodeId") String clusterNodeId, - @ApiParam( - value = "The input port id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false + ) + @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, + @ApiParam( + value = "The id of the node where to get the status.", + required = false + ) + @QueryParam("clusterNodeId") String clusterNodeId, + @ApiParam( + value = "The input port id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1423,41 +1368,38 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("output-ports/{id}/status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status for an output port", - response = PortStatusEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status for an output port", + response = PortStatusEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getOutputPortStatus( - @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false - ) - @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, - @ApiParam( - value = "The id of the node where to get the status.", - required = false - ) - @QueryParam("clusterNodeId") String clusterNodeId, - @ApiParam( - value = "The output port id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false + ) + @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, + @ApiParam( + value = "The id of the node where to get the status.", + required = false + ) + @QueryParam("clusterNodeId") String clusterNodeId, + @ApiParam( + value = "The output port id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1505,41 +1447,38 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("remote-process-groups/{id}/status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status for a remote process group", - response = ProcessorStatusEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status for a remote process group", + response = ProcessorStatusEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getRemoteProcessGroupStatus( - @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false - ) - @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, - @ApiParam( - value = "The id of the node where to get the status.", - required = false - ) - @QueryParam("clusterNodeId") String clusterNodeId, - @ApiParam( - value = "The remote process group id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false + ) + @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, + @ApiParam( + value = "The id of the node where to get the status.", + required = false + ) + @QueryParam("clusterNodeId") String clusterNodeId, + @ApiParam( + value = "The remote process group id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1580,7 +1519,7 @@ public class FlowResource extends ApplicationResource { * Retrieves the status report for this NiFi. * * @param recursive Optional recursive flag that defaults to false. If set to true, all descendant groups and the status of their content will be included. - * @param groupId The group id + * @param groupId The group id * @return A processGroupStatusEntity. * @throws InterruptedException if interrupted */ @@ -1588,49 +1527,45 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("process-groups/{id}/status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN', 'ROLE_NIFI')") @ApiOperation( - value = "Gets the status for a process group", - notes = "The status for a process group includes status for all descendent components. When invoked on the root group with " - + "recursive set to true, it will return the current status of every component in the flow.", - response = ProcessGroupStatusEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN"), - @Authorization(value = "NiFi", type = "ROLE_NIFI") - } + value = "Gets the status for a process group", + notes = "The status for a process group includes status for all descendent components. When invoked on the root group with " + + "recursive set to true, it will return the current status of every component in the flow.", + response = ProcessGroupStatusEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getProcessGroupStatus( - @ApiParam( - value = "Whether all descendant groups and the status of their content will be included. Optional, defaults to false", - required = false - ) - @QueryParam("recursive") @DefaultValue(RECURSIVE) Boolean recursive, - @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false - ) - @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, - @ApiParam( - value = "The id of the node where to get the status.", - required = false - ) - @QueryParam("clusterNodeId") String clusterNodeId, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") String groupId) throws InterruptedException { + @ApiParam( + value = "Whether all descendant groups and the status of their content will be included. Optional, defaults to false", + required = false + ) + @QueryParam("recursive") @DefaultValue(RECURSIVE) Boolean recursive, + @ApiParam( + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false + ) + @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, + @ApiParam( + value = "The id of the node where to get the status.", + required = false + ) + @QueryParam("clusterNodeId") String clusterNodeId, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String groupId) throws InterruptedException { authorizeFlow(); @@ -1699,41 +1634,38 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("connections/{id}/status") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status for a connection", - response = ConnectionStatusEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status for a connection", + response = ConnectionStatusEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getConnectionStatus( - @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false - ) - @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, - @ApiParam( - value = "The id of the node where to get the status.", - required = false - ) - @QueryParam("clusterNodeId") String clusterNodeId, - @ApiParam( - value = "The connection id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false + ) + @QueryParam("nodewise") @DefaultValue(NODEWISE) Boolean nodewise, + @ApiParam( + value = "The id of the node where to get the status.", + required = false + ) + @QueryParam("clusterNodeId") String clusterNodeId, + @ApiParam( + value = "The connection id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1785,31 +1717,28 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("processors/{id}/status/history") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status history for a processor", - response = StatusHistoryEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status history for a processor", + response = StatusHistoryEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getProcessorStatusHistory( - @ApiParam( - value = "The processor id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "The processor id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1840,31 +1769,28 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("process-groups/{id}/status/history") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets status history for a remote process group", - response = StatusHistoryEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets status history for a remote process group", + response = StatusHistoryEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getProcessGroupStatusHistory( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") String groupId) throws InterruptedException { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String groupId) throws InterruptedException { authorizeFlow(); @@ -1895,31 +1821,28 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("remote-process-groups/{id}/status/history") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets the status history", - response = StatusHistoryEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets the status history", + response = StatusHistoryEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getRemoteProcessGroupStatusHistory( - @ApiParam( - value = "The remote process group id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "The remote process group id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -1950,31 +1873,28 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("connections/{id}/status/history") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets the status history for a connection", - response = StatusHistoryEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets the status history for a connection", + response = StatusHistoryEntity.class, + authorizations = { + @Authorization(value = "Read - /flow", type = "") + } ) @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.") - } + 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 getConnectionStatusHistory( - @ApiParam( - value = "The connection id.", - required = true - ) - @PathParam("id") String id) throws InterruptedException { + @ApiParam( + value = "The connection id.", + required = true + ) + @PathParam("id") String id) throws InterruptedException { authorizeFlow(); @@ -2001,40 +1921,38 @@ public class FlowResource extends ApplicationResource { /** * Queries the history of this Controller. * - * @param offset The offset into the data. This parameter is required and is - * used in conjunction with count. - * @param count The number of rows that should be returned. This parameter - * is required and is used in conjunction with page. - * @param sortColumn The column to sort on. This parameter is optional. If - * not specified the results will be returned with the most recent first. - * @param sortOrder The sort order. - * @param startDate The start date/time for the query. The start date/time - * must be formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional - * and must be specified in the timezone of the server. The server's - * timezone can be determined by inspecting the result of a status or - * history request. - * @param endDate The end date/time for the query. The end date/time must be - * formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional and must - * be specified in the timezone of the server. The server's timezone can be - * determined by inspecting the result of a status or history request. + * @param offset The offset into the data. This parameter is required and is + * used in conjunction with count. + * @param count The number of rows that should be returned. This parameter + * is required and is used in conjunction with page. + * @param sortColumn The column to sort on. This parameter is optional. If + * not specified the results will be returned with the most recent first. + * @param sortOrder The sort order. + * @param startDate The start date/time for the query. The start date/time + * must be formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional + * and must be specified in the timezone of the server. The server's + * timezone can be determined by inspecting the result of a status or + * history request. + * @param endDate The end date/time for the query. The end date/time must be + * formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional and must + * be specified in the timezone of the server. The server's timezone can be + * determined by inspecting the result of a status or history request. * @param userIdentity The user name of the user who's actions are being - * queried. This parameter is optional. - * @param sourceId The id of the source being queried (usually a processor - * id). This parameter is optional. + * queried. This parameter is optional. + * @param sourceId The id of the source being queried (usually a processor + * id). This parameter is optional. * @return A historyEntity. */ @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("history") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets configuration history", + notes = NON_GUARANTEED_ENDPOINT, response = HistoryEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -2166,15 +2084,13 @@ public class FlowResource extends ApplicationResource { @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @Path("history/{id}") @ApiOperation( value = "Gets an action", + notes = NON_GUARANTEED_ENDPOINT, response = ActionEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -2223,14 +2139,12 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("history/components/{componentId}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets configuration history for a processor", + notes = NON_GUARANTEED_ENDPOINT, response = ComponentHistoryEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -2274,14 +2188,11 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("templates") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets all templates", response = TemplatesEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -2328,14 +2239,12 @@ public class FlowResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("cluster/search-results") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Searches the cluster for a node with the specified address", + notes = NON_GUARANTEED_ENDPOINT, response = ClusterSearchResultsEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "DFM", type = "ROLE_DFM"), - @Authorization(value = "Admin", type = "ROLE_ADMIN") + @Authorization(value = "Read - /flow", type = "") } ) @ApiResponses( @@ -2394,6 +2303,7 @@ public class FlowResource extends ApplicationResource { } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java index 42c8932c9a..c23b1b9f0a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FunnelResource.java @@ -55,8 +55,8 @@ import java.util.Set; */ @Path("/funnels") @Api( - value = "/funnel", - description = "Endpoint for managing a Funnel." + value = "/funnel", + description = "Endpoint for managing a Funnel." ) public class FunnelResource extends ApplicationResource { @@ -97,23 +97,20 @@ public class FunnelResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a funnel", response = FunnelEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /funnels/{uuid}", type = "") } ) @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.") + @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 getFunnel( @@ -144,29 +141,28 @@ public class FunnelResource extends ApplicationResource { * Creates a new Funnel. * * @param httpServletRequest request - * @param id The id of the funnel to update. - * @param funnelEntity A funnelEntity. + * @param id The id of the funnel to update. + * @param funnelEntity A funnelEntity. * @return A funnelEntity. */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a funnel", response = FunnelEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /funnels/{uuid}", type = "") } ) @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.") + @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 updateFunnel( @@ -203,20 +199,20 @@ public class FunnelResource extends ApplicationResource { // Extract the revision final Revision revision = getRevision(funnelEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getFunnel(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - null, - () -> { - // update the funnel - final FunnelEntity entity = serviceFacade.updateFunnel(revision, requestFunnelDTO); - populateRemainingFunnelEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getFunnel(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + () -> { + // update the funnel + final FunnelEntity entity = serviceFacade.updateFunnel(revision, requestFunnelDTO); + populateRemainingFunnelEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -224,33 +220,32 @@ public class FunnelResource extends ApplicationResource { * Removes the specified funnel. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with - * the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a - * new one will be generated. This value (whether specified or generated) is - * included in the response. - * @param id The id of the funnel to remove. + * @param version The revision is used to verify the client is working with + * the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a + * new one will be generated. This value (whether specified or generated) is + * included in the response. + * @param id The id of the funnel to remove. * @return A entity containing the client id and an updated revision. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a funnel", response = FunnelEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /funnels/{uuid}", type = "") } ) @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.") + @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 removeFunnel( @@ -278,22 +273,23 @@ public class FunnelResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable funnel = lookup.getFunnel(id); - funnel.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteFunnel(id), - () -> { - // delete the specified funnel - final FunnelEntity entity = serviceFacade.deleteFunnel(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable funnel = lookup.getFunnel(id); + funnel.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteFunnel(id), + () -> { + // delete the specified funnel + final FunnelEntity entity = serviceFacade.deleteFunnel(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java index ee4cc4ade9..a57e8aa0e9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/InputPortResource.java @@ -55,8 +55,8 @@ import java.util.Set; */ @Path("/input-ports") @Api( - value = "/input-ports", - description = "Endpoint for managing an Input Port." + value = "/input-ports", + description = "Endpoint for managing an Input Port." ) public class InputPortResource extends ApplicationResource { @@ -76,12 +76,12 @@ public class InputPortResource extends ApplicationResource { return inputPortEntites; } - /** - * Populates the uri for the specified input port. - * - * @param inputPortEntity port - * @return ports - */ + /** + * Populates the uri for the specified input port. + * + * @param inputPortEntity port + * @return ports + */ public PortEntity populateRemainingInputPortEntityContent(PortEntity inputPortEntity) { inputPortEntity.setUri(generateResourceUri("input-ports", inputPortEntity.getId())); return inputPortEntity; @@ -97,23 +97,20 @@ public class InputPortResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets an input port", response = PortEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /input-ports/{uuid}", type = "") } ) @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.") + @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 getInputPort( @@ -144,29 +141,28 @@ public class InputPortResource extends ApplicationResource { * Updates the specified input port. * * @param httpServletRequest request - * @param id The id of the input port to update. - * @param portEntity A inputPortEntity. + * @param id The id of the input port to update. + * @param portEntity A inputPortEntity. * @return A inputPortEntity. */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates an input port", response = PortEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /input-ports/{uuid}", type = "") } ) @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.") + @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 updateInputPort( @@ -203,20 +199,20 @@ public class InputPortResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(portEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getInputPort(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateInputPort(requestPortDTO), - () -> { - // update the input port - final PortEntity entity = serviceFacade.updateInputPort(revision, requestPortDTO); - populateRemainingInputPortEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getInputPort(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateInputPort(requestPortDTO), + () -> { + // update the input port + final PortEntity entity = serviceFacade.updateInputPort(revision, requestPortDTO); + populateRemainingInputPortEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -224,30 +220,29 @@ public class InputPortResource extends ApplicationResource { * Removes the specified input port. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the input port to remove. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the input port to remove. * @return A inputPortEntity. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes an input port", response = PortEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /input-ports/{uuid}", type = "") } ) @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.") + @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 removeInputPort( @@ -275,22 +270,23 @@ public class InputPortResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable inputPort = lookup.getInputPort(id); - inputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteInputPort(id), - () -> { - // delete the specified input port - final PortEntity entity = serviceFacade.deleteInputPort(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable inputPort = lookup.getInputPort(id); + inputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteInputPort(id), + () -> { + // delete the specified input port + final PortEntity entity = serviceFacade.deleteInputPort(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java index 1742218062..ddde515f3f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/LabelResource.java @@ -55,8 +55,8 @@ import java.util.Set; */ @Path("/labels") @Api( - value = "/labels", - description = "Endpoint for managing a Label." + value = "/labels", + description = "Endpoint for managing a Label." ) public class LabelResource extends ApplicationResource { @@ -97,23 +97,20 @@ public class LabelResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a label", response = LabelEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /labels/{uuid}", type = "") } ) @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.") + @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 getLabel( @@ -144,29 +141,28 @@ public class LabelResource extends ApplicationResource { * Updates the specified label. * * @param httpServletRequest request - * @param id The id of the label to update. - * @param labelEntity A labelEntity. + * @param id The id of the label to update. + * @param labelEntity A labelEntity. * @return A labelEntity. */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a label", response = LabelEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /labels/{uuid}", type = "") } ) @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.") + @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 updateLabel( @@ -203,20 +199,20 @@ public class LabelResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(labelEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getLabel(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - null, - () -> { - // update the label - final LabelEntity entity = serviceFacade.updateLabel(revision, requestLabelDTO); - populateRemainingLabelEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getLabel(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + () -> { + // update the label + final LabelEntity entity = serviceFacade.updateLabel(revision, requestLabelDTO); + populateRemainingLabelEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -224,30 +220,29 @@ public class LabelResource extends ApplicationResource { * Removes the specified label. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the label to remove. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the label to remove. * @return A entity containing the client id and an updated revision. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a label", response = LabelEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /labels/{uuid}", type = "") } ) @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.") + @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 removeLabel( @@ -275,22 +270,23 @@ public class LabelResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable label = lookup.getLabel(id); - label.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - null, - () -> { - // delete the specified label - final LabelEntity entity = serviceFacade.deleteLabel(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable label = lookup.getLabel(id); + label.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + () -> { + // delete the specified label + final LabelEntity entity = serviceFacade.deleteLabel(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java index 55681dc673..70a9e2df37 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/OutputPortResource.java @@ -55,8 +55,8 @@ import java.util.Set; */ @Path("/output-ports") @Api( - value = "/output-ports", - description = "Endpoint for managing an Output Port." + value = "/output-ports", + description = "Endpoint for managing an Output Port." ) public class OutputPortResource extends ApplicationResource { @@ -97,23 +97,20 @@ public class OutputPortResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets an output port", response = PortEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /output-ports/{uuid}", type = "") } ) @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.") + @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 getOutputPort( @@ -144,29 +141,28 @@ public class OutputPortResource extends ApplicationResource { * Updates the specified output port. * * @param httpServletRequest request - * @param id The id of the output port to update. - * @param portEntity A outputPortEntity. + * @param id The id of the output port to update. + * @param portEntity A outputPortEntity. * @return A outputPortEntity. */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates an output port", response = PortEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /output-ports/{uuid}", type = "") } ) @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.") + @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 updateOutputPort( @@ -203,20 +199,20 @@ public class OutputPortResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(portEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getOutputPort(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateOutputPort(requestPortDTO), - () -> { - // update the output port - final PortEntity entity = serviceFacade.updateOutputPort(revision, requestPortDTO); - populateRemainingOutputPortEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getOutputPort(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateOutputPort(requestPortDTO), + () -> { + // update the output port + final PortEntity entity = serviceFacade.updateOutputPort(revision, requestPortDTO); + populateRemainingOutputPortEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -224,30 +220,29 @@ public class OutputPortResource extends ApplicationResource { * Removes the specified output port. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the output port to remove. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the output port to remove. * @return A outputPortEntity. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes an output port", response = PortEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /output-ports/{uuid}", type = "") } ) @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.") + @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 removeOutputPort( @@ -275,22 +270,23 @@ public class OutputPortResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable outputPort = lookup.getOutputPort(id); - outputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteOutputPort(id), - () -> { - // delete the specified output port - final PortEntity entity = serviceFacade.deleteOutputPort(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable outputPort = lookup.getOutputPort(id); + outputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteOutputPort(id), + () -> { + // delete the specified output port + final PortEntity entity = serviceFacade.deleteOutputPort(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java index 549e31208a..56bd398e05 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java @@ -100,8 +100,8 @@ import java.util.Set; */ @Path("/process-groups") @Api( - value = "/process-groups", - description = "Endpoint for managing a Process Group." + value = "/process-groups", + description = "Endpoint for managing a Process Group." ) public class ProcessGroupResource extends ApplicationResource { @@ -145,7 +145,7 @@ public class ProcessGroupResource extends ApplicationResource { * @return group dto */ public ProcessGroupEntity populateRemainingProcessGroupEntityContent(ProcessGroupEntity processGroupEntity) { - processGroupEntity.setUri(generateResourceUri("process-groups", processGroupEntity.getId())); + processGroupEntity.setUri(generateResourceUri("process-groups", processGroupEntity.getId())); return processGroupEntity; } @@ -179,23 +179,20 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a process group", response = ProcessGroupEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /process-groups/{uuid}", type = "") } ) @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.") + @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 getProcessGroup( @@ -230,7 +227,7 @@ public class ProcessGroupResource extends ApplicationResource { * Updates the specified process group. * * @param httpServletRequest request - * @param id The id of the process group. + * @param id The id of the process group. * @param processGroupEntity A processGroupEntity. * @return A processGroupEntity. */ @@ -238,21 +235,20 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a process group", response = ProcessGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /process-groups/{uuid}", type = "") } ) @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.") + @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 updateProcessGroup( @@ -289,20 +285,20 @@ public class ProcessGroupResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(processGroupEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getProcessGroup(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - null, - () -> { - // update the process group - final ProcessGroupEntity entity = serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO); - populateRemainingProcessGroupEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getProcessGroup(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + () -> { + // update the process group + final ProcessGroupEntity entity = serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO); + populateRemainingProcessGroupEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -310,30 +306,29 @@ public class ProcessGroupResource extends ApplicationResource { * Removes the specified process group reference. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the process group to be removed. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the process group to be removed. * @return A processGroupEntity. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a process group", response = ProcessGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /process-groups/{uuid}", type = "") } ) @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.") + @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 removeProcessGroup( @@ -362,20 +357,20 @@ public class ProcessGroupResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable processGroup = lookup.getProcessGroup(id); - processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteProcessGroup(id), - () -> { - // delete the process group - final ProcessGroupEntity entity = serviceFacade.deleteProcessGroup(revision, id); + serviceFacade, + revision, + lookup -> { + final Authorizable processGroup = lookup.getProcessGroup(id); + processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteProcessGroup(id), + () -> { + // delete the process group + final ProcessGroupEntity entity = serviceFacade.deleteProcessGroup(revision, id); - // create the response - return clusterContext(generateOkResponse(entity)).build(); - } + // create the response + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -383,7 +378,7 @@ public class ProcessGroupResource extends ApplicationResource { * Adds the specified process group. * * @param httpServletRequest request - * @param groupId The group id + * @param groupId The group id * @param processGroupEntity A processGroupEntity * @return A processGroupEntity */ @@ -391,34 +386,33 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/process-groups") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a process group", - response = ProcessGroupEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a process group", + response = ProcessGroupEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createProcessGroup( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The process group configuration details.", - required = true - ) final ProcessGroupEntity processGroupEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The process group configuration details.", + required = true + ) final ProcessGroupEntity processGroupEntity) { if (processGroupEntity == null || processGroupEntity.getComponent() == null) { throw new IllegalArgumentException("Process group details must be specified."); @@ -434,7 +428,7 @@ public class ProcessGroupResource extends ApplicationResource { if (processGroupEntity.getComponent().getParentGroupId() != null && !groupId.equals(processGroupEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - processGroupEntity.getComponent().getParentGroupId(), groupId)); + processGroupEntity.getComponent().getParentGroupId(), groupId)); } processGroupEntity.getComponent().setParentGroupId(groupId); @@ -477,31 +471,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/process-groups") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all process groups", - response = ProcessorsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all process groups", + response = ProcessorsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getProcessGroups( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -539,41 +530,40 @@ public class ProcessGroupResource extends ApplicationResource { * Creates a new processor. * * @param httpServletRequest request - * @param groupId The group id - * @param processorEntity A processorEntity. + * @param groupId The group id + * @param processorEntity A processorEntity. * @return A processorEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/processors") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a new processor", - response = ProcessorEntity.class, - authorizations = { - @Authorization(value = "ROLE_DFM", type = "ROLE_DFM") - } + value = "Creates a new processor", + response = ProcessorEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createProcessor( @Context final HttpServletRequest httpServletRequest, @ApiParam( - value = "The process group id.", - required = true + value = "The process group id.", + required = true ) @PathParam("id") final String groupId, @ApiParam( - value = "The processor configuration details.", - required = true + value = "The processor configuration details.", + required = true ) final ProcessorEntity processorEntity) { if (processorEntity == null || processorEntity.getComponent() == null) { @@ -594,7 +584,7 @@ public class ProcessGroupResource extends ApplicationResource { if (processorEntity.getComponent().getParentGroupId() != null && !groupId.equals(processorEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - processorEntity.getComponent().getParentGroupId(), groupId)); + processorEntity.getComponent().getParentGroupId(), groupId)); } processorEntity.getComponent().setParentGroupId(groupId); @@ -638,31 +628,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/processors") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all processors", - response = ProcessorsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all processors", + response = ProcessorsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getProcessors( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -693,42 +680,41 @@ public class ProcessGroupResource extends ApplicationResource { * Creates a new input port. * * @param httpServletRequest request - * @param groupId The group id - * @param portEntity A inputPortEntity. + * @param groupId The group id + * @param portEntity A inputPortEntity. * @return A inputPortEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/input-ports") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates an input port", - response = PortEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates an input port", + response = PortEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createInputPort( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The input port configuration details.", - required = true - ) final PortEntity portEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The input port configuration details.", + required = true + ) final PortEntity portEntity) { if (portEntity == null || portEntity.getComponent() == null) { throw new IllegalArgumentException("Port details must be specified."); @@ -744,7 +730,7 @@ public class ProcessGroupResource extends ApplicationResource { if (portEntity.getComponent().getParentGroupId() != null && !groupId.equals(portEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - portEntity.getComponent().getParentGroupId(), groupId)); + portEntity.getComponent().getParentGroupId(), groupId)); } portEntity.getComponent().setParentGroupId(groupId); @@ -786,31 +772,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/input-ports") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all input ports", - response = InputPortsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all input ports", + response = InputPortsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getInputPorts( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -840,42 +823,41 @@ public class ProcessGroupResource extends ApplicationResource { * Creates a new output port. * * @param httpServletRequest request - * @param groupId The group id - * @param portEntity A outputPortEntity. + * @param groupId The group id + * @param portEntity A outputPortEntity. * @return A outputPortEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/output-ports") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates an output port", - response = PortEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates an output port", + response = PortEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createOutputPort( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The output port configuration.", - required = true - ) final PortEntity portEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The output port configuration.", + required = true + ) final PortEntity portEntity) { if (portEntity == null || portEntity.getComponent() == null) { throw new IllegalArgumentException("Port details must be specified."); @@ -891,7 +873,7 @@ public class ProcessGroupResource extends ApplicationResource { if (portEntity.getComponent().getParentGroupId() != null && !groupId.equals(portEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - portEntity.getComponent().getParentGroupId(), groupId)); + portEntity.getComponent().getParentGroupId(), groupId)); } portEntity.getComponent().setParentGroupId(groupId); @@ -933,31 +915,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/output-ports") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all output ports", - response = OutputPortsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all output ports", + response = OutputPortsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getOutputPorts( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -988,42 +967,41 @@ public class ProcessGroupResource extends ApplicationResource { * Creates a new Funnel. * * @param httpServletRequest request - * @param groupId The group id - * @param funnelEntity A funnelEntity. + * @param groupId The group id + * @param funnelEntity A funnelEntity. * @return A funnelEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/funnels") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a funnel", - response = FunnelEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a funnel", + response = FunnelEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createFunnel( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The funnel configuration details.", - required = true - ) final FunnelEntity funnelEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The funnel configuration details.", + required = true + ) final FunnelEntity funnelEntity) { if (funnelEntity == null || funnelEntity.getComponent() == null) { throw new IllegalArgumentException("Funnel details must be specified."); @@ -1039,7 +1017,7 @@ public class ProcessGroupResource extends ApplicationResource { if (funnelEntity.getComponent().getParentGroupId() != null && !groupId.equals(funnelEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - funnelEntity.getComponent().getParentGroupId(), groupId)); + funnelEntity.getComponent().getParentGroupId(), groupId)); } funnelEntity.getComponent().setParentGroupId(groupId); @@ -1081,31 +1059,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/funnels") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all funnels", - response = FunnelsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all funnels", + response = FunnelsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getFunnels( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -1136,42 +1111,41 @@ public class ProcessGroupResource extends ApplicationResource { * Creates a new Label. * * @param httpServletRequest request - * @param groupId The group id - * @param labelEntity A labelEntity. + * @param groupId The group id + * @param labelEntity A labelEntity. * @return A labelEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/labels") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a label", - response = LabelEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a label", + response = LabelEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createLabel( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The label configuration details.", - required = true - ) final LabelEntity labelEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The label configuration details.", + required = true + ) final LabelEntity labelEntity) { if (labelEntity == null || labelEntity.getComponent() == null) { throw new IllegalArgumentException("Label details must be specified."); @@ -1187,7 +1161,7 @@ public class ProcessGroupResource extends ApplicationResource { if (labelEntity.getComponent().getParentGroupId() != null && !groupId.equals(labelEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - labelEntity.getComponent().getParentGroupId(), groupId)); + labelEntity.getComponent().getParentGroupId(), groupId)); } labelEntity.getComponent().setParentGroupId(groupId); @@ -1229,31 +1203,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/labels") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all labels", - response = LabelsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all labels", + response = LabelsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getLabels( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -1283,8 +1254,8 @@ public class ProcessGroupResource extends ApplicationResource { /** * Creates a new remote process group. * - * @param httpServletRequest request - * @param groupId The group id + * @param httpServletRequest request + * @param groupId The group id * @param remoteProcessGroupEntity A remoteProcessGroupEntity. * @return A remoteProcessGroupEntity. */ @@ -1292,34 +1263,33 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/remote-process-groups") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a new process group", - response = RemoteProcessGroupEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - } + value = "Creates a new process group", + response = RemoteProcessGroupEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 createRemoteProcessGroup( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The remote process group configuration details.", - required = true - ) final RemoteProcessGroupEntity remoteProcessGroupEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The remote process group configuration details.", + required = true + ) final RemoteProcessGroupEntity remoteProcessGroupEntity) { if (remoteProcessGroupEntity == null || remoteProcessGroupEntity.getComponent() == null) { throw new IllegalArgumentException("Remote process group details must be specified."); @@ -1341,7 +1311,7 @@ public class ProcessGroupResource extends ApplicationResource { if (requestProcessGroupDTO.getParentGroupId() != null && !groupId.equals(requestProcessGroupDTO.getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - requestProcessGroupDTO.getParentGroupId(), groupId)); + requestProcessGroupDTO.getParentGroupId(), groupId)); } requestProcessGroupDTO.setParentGroupId(groupId); @@ -1408,31 +1378,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/remote-process-groups") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all remote process groups", - response = RemoteProcessGroupsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all remote process groups", + response = RemoteProcessGroupsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getRemoteProcessGroups( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -1470,42 +1437,43 @@ public class ProcessGroupResource extends ApplicationResource { * Creates a new connection. * * @param httpServletRequest request - * @param groupId The group id - * @param connectionEntity A connectionEntity. + * @param groupId The group id + * @param connectionEntity A connectionEntity. * @return A connectionEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/connections") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a connection", - response = ConnectionEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a connection", + response = ConnectionEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = ""), + @Authorization(value = "Write Source - /{component-type}/{uuid}", type = ""), + @Authorization(value = "Write Destination - /{component-type}/{uuid}", type = "") + } ) @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.") - } + 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 createConnection( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The connection configuration details.", - required = true - ) final ConnectionEntity connectionEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The connection configuration details.", + required = true + ) final ConnectionEntity connectionEntity) { if (connectionEntity == null || connectionEntity.getComponent() == null) { throw new IllegalArgumentException("Connection details must be specified."); @@ -1521,7 +1489,7 @@ public class ProcessGroupResource extends ApplicationResource { if (connectionEntity.getComponent().getParentGroupId() != null && !groupId.equals(connectionEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - connectionEntity.getComponent().getParentGroupId(), groupId)); + connectionEntity.getComponent().getParentGroupId(), groupId)); } connectionEntity.getComponent().setParentGroupId(groupId); @@ -1585,31 +1553,28 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/connections") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( - value = "Gets all connections", - response = ConnectionsEntity.class, - authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") - } + value = "Gets all connections", + response = ConnectionsEntity.class, + authorizations = { + @Authorization(value = "Read - /process-groups/{uuid}", type = "") + } ) @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.") - } + 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 getConnections( - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") String groupId) { + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String groupId) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -1639,46 +1604,46 @@ public class ProcessGroupResource extends ApplicationResource { /** * Copies the specified snippet within this ProcessGroup. The snippet instance that is instantiated cannot be referenced at a later time, therefore there is no * corresponding URI. Instead the request URI is returned. - * + *

* Alternatively, we could have performed a PUT request. However, PUT requests are supposed to be idempotent and this endpoint is certainly not. * * @param httpServletRequest request - * @param groupId The group id - * @param copySnippetEntity The copy snippet request + * @param groupId The group id + * @param copySnippetEntity The copy snippet request * @return A flowSnippetEntity. */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/snippet-instance") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Copies a snippet", - response = FlowSnippetEntity.class, - authorizations = { - @Authorization(value = "ROLE_DFM", type = "ROLE_DFM") - } + value = "Copies a snippet", + response = FlowSnippetEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = ""), + @Authorization(value = "Read - /{component-type}/{uuid} - For each component in the snippet", type = "") + } ) @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.") - } + 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 copySnippet( - @Context HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") String groupId, - @ApiParam( - value = "The copy snippet request.", - required = true - ) CopySnippetRequestEntity copySnippetEntity) { + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String groupId, + @ApiParam( + value = "The copy snippet request.", + required = true + ) CopySnippetRequestEntity copySnippetEntity) { // ensure the position has been specified if (copySnippetEntity == null || copySnippetEntity.getOriginX() == null || copySnippetEntity.getOriginY() == null) { @@ -1707,7 +1672,7 @@ public class ProcessGroupResource extends ApplicationResource { // copy the specified snippet final FlowEntity flowEntity = serviceFacade.copySnippet( - groupId, copySnippetEntity.getSnippetId(), copySnippetEntity.getOriginX(), copySnippetEntity.getOriginY(), getIdGenerationSeed().orElse(null)); + groupId, copySnippetEntity.getSnippetId(), copySnippetEntity.getOriginX(), copySnippetEntity.getOriginY(), getIdGenerationSeed().orElse(null)); // get the snippet final FlowDTO flow = flowEntity.getFlow(); @@ -1731,11 +1696,11 @@ public class ProcessGroupResource extends ApplicationResource { /** * Instantiates the specified template within this ProcessGroup. The template instance that is instantiated cannot be referenced at a later time, therefore there is no * corresponding URI. Instead the request URI is returned. - * + *

* Alternatively, we could have performed a PUT request. However, PUT requests are supposed to be idempotent and this endpoint is certainly not. * - * @param httpServletRequest request - * @param groupId The group id + * @param httpServletRequest request + * @param groupId The group id * @param instantiateTemplateRequestEntity The instantiate template request * @return A flowEntity. */ @@ -1743,34 +1708,34 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/template-instance") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Instantiates a template", - response = FlowEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Instantiates a template", + response = FlowEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = ""), + @Authorization(value = "Read - /templates/{uuid}", type = "") + } ) @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.") - } + 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 instantiateTemplate( - @Context HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") String groupId, - @ApiParam( - value = "The instantiate template request.", - required = true - ) InstantiateTemplateRequestEntity instantiateTemplateRequestEntity) { + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") String groupId, + @ApiParam( + value = "The instantiate template request.", + required = true + ) InstantiateTemplateRequestEntity instantiateTemplateRequestEntity) { // ensure the position has been specified if (instantiateTemplateRequestEntity == null || instantiateTemplateRequestEntity.getOriginX() == null || instantiateTemplateRequestEntity.getOriginY() == null) { @@ -1799,7 +1764,7 @@ public class ProcessGroupResource extends ApplicationResource { // create the template and generate the json final FlowEntity entity = serviceFacade.createTemplateInstance(groupId, instantiateTemplateRequestEntity.getOriginX(), - instantiateTemplateRequestEntity.getOriginY(), instantiateTemplateRequestEntity.getTemplateId(), getIdGenerationSeed().orElse(null)); + instantiateTemplateRequestEntity.getOriginY(), instantiateTemplateRequestEntity.getTemplateId(), getIdGenerationSeed().orElse(null)); final FlowDTO flowSnippet = entity.getFlow(); @@ -1831,7 +1796,7 @@ public class ProcessGroupResource extends ApplicationResource { /** * Creates a new template based off of the specified template. * - * @param httpServletRequest request + * @param httpServletRequest request * @param createTemplateRequestEntity request to create the template * @return A templateEntity */ @@ -1839,34 +1804,34 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/templates") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a template", - response = TemplateEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a template", + response = TemplateEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = ""), + @Authorization(value = "Read - /{component-type}/{uuid} - For each component in the snippet", type = "") + } ) @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.") - } + 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 createTemplate( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The create template request.", - required = true - ) final CreateTemplateRequestEntity createTemplateRequestEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The create template request.", + required = true + ) final CreateTemplateRequestEntity createTemplateRequestEntity) { if (createTemplateRequestEntity.getSnippetId() == null) { throw new IllegalArgumentException("The snippet identifier must be specified."); @@ -1891,7 +1856,7 @@ public class ProcessGroupResource extends ApplicationResource { // create the template and generate the json final TemplateDTO template = serviceFacade.createTemplate(createTemplateRequestEntity.getName(), createTemplateRequestEntity.getDescription(), - createTemplateRequestEntity.getSnippetId(), groupId, getIdGenerationSeed()); + createTemplateRequestEntity.getSnippetId(), groupId, getIdGenerationSeed()); templateResource.populateRemainingTemplateContent(template); // build the response entity @@ -1906,7 +1871,7 @@ public class ProcessGroupResource extends ApplicationResource { * Imports the specified template. * * @param httpServletRequest request - * @param in The template stream + * @param in The template stream * @return A templateEntity or an errorResponse XML snippet. * @throws InterruptedException if interrupted */ @@ -1914,15 +1879,29 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_XML) @Path("{id}/templates/upload") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") + @ApiOperation( + value = "Uploads a template", + response = TemplateEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) public Response uploadTemplate( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @FormDataParam("template") final InputStream in) throws InterruptedException { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @FormDataParam("template") final InputStream in) throws InterruptedException { // unmarshal the template final TemplateDTO template; @@ -1942,7 +1921,7 @@ public class ProcessGroupResource extends ApplicationResource { } catch (Exception e) { logger.warn("An error occurred while importing a template.", e); String responseXml = String.format("", - Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()); + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()); return Response.status(Response.Status.OK).entity(responseXml).type("application/xml").build(); } @@ -1981,22 +1960,36 @@ public class ProcessGroupResource extends ApplicationResource { * Imports the specified template. * * @param httpServletRequest request - * @param templateEntity A templateEntity. + * @param templateEntity A templateEntity. * @return A templateEntity. */ @POST @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) @Path("{id}/templates/import") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") + @ApiOperation( + value = "Imports a template", + response = TemplateEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) public Response importTemplate( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - final TemplateEntity templateEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + final TemplateEntity templateEntity) { // verify the template was specified if (templateEntity == null || templateEntity.getTemplate() == null || templateEntity.getTemplate().getSnippet() == null) { @@ -2039,7 +2032,7 @@ public class ProcessGroupResource extends ApplicationResource { } catch (Exception e) { logger.warn("An error occurred while importing a template.", e); String responseXml - = String.format("", Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()); + = String.format("", Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()); return Response.status(Response.Status.OK).entity(responseXml).type("application/xml").build(); } } @@ -2051,7 +2044,7 @@ public class ProcessGroupResource extends ApplicationResource { /** * Creates a new Controller Service. * - * @param httpServletRequest request + * @param httpServletRequest request * @param controllerServiceEntity A controllerServiceEntity. * @return A controllerServiceEntity. */ @@ -2059,33 +2052,32 @@ public class ProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/controller-services") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Creates a new controller service", - response = ControllerServiceEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Creates a new controller service", + response = ControllerServiceEntity.class, + authorizations = { + @Authorization(value = "Write - /process-groups/{uuid}", type = "") + } ) @ApiResponses( - value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") - } + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } ) public Response createControllerService( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The process group id.", - required = true - ) - @PathParam("id") final String groupId, - @ApiParam( - value = "The controller service configuration details.", - required = true - ) final ControllerServiceEntity controllerServiceEntity) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The process group id.", + required = true + ) + @PathParam("id") final String groupId, + @ApiParam( + value = "The controller service configuration details.", + required = true + ) final ControllerServiceEntity controllerServiceEntity) { if (controllerServiceEntity == null || controllerServiceEntity.getComponent() == null) { throw new IllegalArgumentException("Controller service details must be specified."); @@ -2105,7 +2097,7 @@ public class ProcessGroupResource extends ApplicationResource { if (controllerServiceEntity.getComponent().getParentGroupId() != null && !groupId.equals(controllerServiceEntity.getComponent().getParentGroupId())) { throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", - controllerServiceEntity.getComponent().getParentGroupId(), groupId)); + controllerServiceEntity.getComponent().getParentGroupId(), groupId)); } controllerServiceEntity.getComponent().setParentGroupId(groupId); @@ -2139,6 +2131,7 @@ public class ProcessGroupResource extends ApplicationResource { } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java index bf104f5034..fae20aaf24 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java @@ -66,8 +66,8 @@ import java.util.Set; */ @Path("/processors") @Api( - value = "/processors", - description = "Endpoint for managing a Processor." + value = "/processors", + description = "Endpoint for managing a Processor." ) public class ProcessorResource extends ApplicationResource { private NiFiServiceFacade serviceFacade; @@ -144,23 +144,20 @@ public class ProcessorResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a processor", response = ProcessorEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /processors/{uuid}", type = "") } ) @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.") + @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 getProcessor( @@ -168,7 +165,7 @@ public class ProcessorResource extends ApplicationResource { value = "The processor id.", required = true ) - @PathParam("id") final String id) throws InterruptedException { + @PathParam("id") final String id) throws InterruptedException { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -191,7 +188,7 @@ public class ProcessorResource extends ApplicationResource { /** * Returns the descriptor for the specified property. * - * @param id The id of the processor + * @param id The id of the processor * @param propertyName The property * @return a propertyDescriptorEntity * @throws InterruptedException if interrupted @@ -200,23 +197,20 @@ public class ProcessorResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}/descriptors") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the descriptor for a processor property", response = PropertyDescriptorEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /processors/{uuid}", type = "") } ) @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.") + @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 getPropertyDescriptor( @@ -234,7 +228,7 @@ public class ProcessorResource extends ApplicationResource { value = "The property name.", required = true ) - @QueryParam("propertyName") final String propertyName) throws InterruptedException { + @QueryParam("propertyName") final String propertyName) throws InterruptedException { // ensure the property name is specified if (propertyName == null) { @@ -273,29 +267,28 @@ public class ProcessorResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}/state") - // TODO - @PreAuthorize("hasAnyRole('ROLE_DFM')") @ApiOperation( - value = "Gets the state for a processor", - response = ComponentStateDTO.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Gets the state for a processor", + response = ComponentStateDTO.class, + authorizations = { + @Authorization(value = "Write - /processors/{uuid}", type = "") + } ) @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.") - } + 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 getState( - @ApiParam( - value = "The processor id.", - required = true - ) - @PathParam("id") final String id) throws InterruptedException { + @ApiParam( + value = "The processor id.", + required = true + ) + @PathParam("id") final String id) throws InterruptedException { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -322,7 +315,7 @@ public class ProcessorResource extends ApplicationResource { * Clears the state for a processor. * * @param httpServletRequest servlet request - * @param id The id of the processor + * @param id The id of the processor * @return a componentStateEntity * @throws InterruptedException if interrupted */ @@ -330,30 +323,29 @@ public class ProcessorResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/state/clear-requests") - // TODO - @PreAuthorize("hasAnyRole('ROLE_DFM')") @ApiOperation( - value = "Clears the state for a processor", - response = ComponentStateDTO.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Clears the state for a processor", + response = ComponentStateDTO.class, + authorizations = { + @Authorization(value = "Write - /processors/{uuid}", type = "") + } ) @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.") - } + 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 clearState( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The processor id.", - required = true - ) - @PathParam("id") final String id) throws InterruptedException { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The processor id.", + required = true + ) + @PathParam("id") final String id) throws InterruptedException { if (isReplicateRequest()) { return replicate(HttpMethod.POST); @@ -386,8 +378,8 @@ public class ProcessorResource extends ApplicationResource { * Updates the specified processor with the specified values. * * @param httpServletRequest request - * @param id The id of the processor to update. - * @param processorEntity A processorEntity. + * @param id The id of the processor to update. + * @param processorEntity A processorEntity. * @return A processorEntity. * @throws InterruptedException if interrupted */ @@ -395,21 +387,20 @@ public class ProcessorResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a processor", response = ProcessorEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /processors/{uuid}", type = "") } ) @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.") + @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 updateProcessor( @@ -422,7 +413,7 @@ public class ProcessorResource extends ApplicationResource { @ApiParam( value = "The processor configuration details.", required = true - ) final ProcessorEntity processorEntity) throws InterruptedException { + ) final ProcessorEntity processorEntity) throws InterruptedException { if (processorEntity == null || processorEntity.getComponent() == null) { throw new IllegalArgumentException("Processor details must be specified."); @@ -446,20 +437,20 @@ public class ProcessorResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(processorEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getProcessor(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO), - () -> { - // update the processor - final ProcessorEntity entity = serviceFacade.updateProcessor(revision, requestProcessorDTO); - populateRemainingProcessorEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getProcessor(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO), + () -> { + // update the processor + final ProcessorEntity entity = serviceFacade.updateProcessor(revision, requestProcessorDTO); + populateRemainingProcessorEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -467,9 +458,9 @@ public class ProcessorResource extends ApplicationResource { * Removes the specified processor. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the processor to remove. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the processor to remove. * @return A processorEntity. * @throws InterruptedException if interrupted */ @@ -477,21 +468,20 @@ public class ProcessorResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a processor", response = ProcessorEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /processors/{uuid}", type = "") } ) @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.") + @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 deleteProcessor( @@ -510,7 +500,7 @@ public class ProcessorResource extends ApplicationResource { value = "The processor id.", required = true ) - @PathParam("id") final String id) throws InterruptedException { + @PathParam("id") final String id) throws InterruptedException { if (isReplicateRequest()) { return replicate(HttpMethod.DELETE); @@ -518,24 +508,25 @@ public class ProcessorResource extends ApplicationResource { final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable processor = lookup.getProcessor(id); - processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteProcessor(id), - () -> { - // delete the processor - final ProcessorEntity entity = serviceFacade.deleteProcessor(revision, id); + serviceFacade, + revision, + lookup -> { + final Authorizable processor = lookup.getProcessor(id); + processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteProcessor(id), + () -> { + // delete the processor + final ProcessorEntity entity = serviceFacade.deleteProcessor(revision, id); - // generate the response - return clusterContext(generateOkResponse(entity)).build(); - } + // generate the response + return clusterContext(generateOkResponse(entity)).build(); + } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceEventResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceEventResource.java index 239b612bb0..6f424f4642 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceEventResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceEventResource.java @@ -27,9 +27,7 @@ import org.apache.nifi.controller.repository.claim.ContentDirection; import org.apache.nifi.stream.io.StreamUtils; import org.apache.nifi.web.DownloadableContent; import org.apache.nifi.web.NiFiServiceFacade; -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.lineage.LineageDTO; import org.apache.nifi.web.api.entity.ProvenanceEventEntity; import org.apache.nifi.web.api.entity.SubmitReplayRequestEntity; import org.apache.nifi.web.api.request.LongParameter; @@ -59,54 +57,37 @@ import java.net.URI; */ @Path("/provenance-events") @Api( - value = "/provenance-events", - description = "Endpoint for accessing data flow provenance." + value = "/provenance-events", + description = "Endpoint for accessing data flow provenance." ) public class ProvenanceEventResource extends ApplicationResource { private NiFiServiceFacade serviceFacade; - /** - * Populates the uri for the specified provenance. - */ - private ProvenanceDTO populateRemainingProvenanceContent(ProvenanceDTO provenance) { - provenance.setUri(generateResourceUri("provenance", provenance.getId())); - return provenance; - } - - /** - * Populates the uri for the specified lineage. - */ - private LineageDTO populateRemainingLineageContent(LineageDTO lineage) { - lineage.setUri(generateResourceUri("provenance", "lineage", lineage.getId())); - return lineage; - } - /** * Gets the content for the input of the specified event. * * @param clusterNodeId The id of the node within the cluster this content is on. Required if clustered. - * @param id The id of the provenance event associated with this content. + * @param id The id of the provenance event associated with this content. * @return The content stream */ @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.WILDCARD) @Path("{id}/content/input") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Gets the input content for a provenance event", authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read Component Data - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 getInputContent( @@ -169,27 +150,26 @@ public class ProvenanceEventResource extends ApplicationResource { * Gets the content for the output of the specified event. * * @param clusterNodeId The id of the node within the cluster this content is on. Required if clustered. - * @param id The id of the provenance event associated with this content. + * @param id The id of the provenance event associated with this content. * @return The content stream */ @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.WILDCARD) @Path("{id}/content/output") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Gets the output content for a provenance event", authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read Component Data - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 getOutputContent( @@ -251,7 +231,7 @@ public class ProvenanceEventResource extends ApplicationResource { /** * Gets the details for a provenance event. * - * @param id The id of the event + * @param id The id of the event * @param clusterNodeId The id of node in the cluster that the event/flowfile originated from. This is only required when clustered. * @return A provenanceEventEntity */ @@ -259,21 +239,20 @@ public class ProvenanceEventResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Gets a provenance event", response = ProvenanceEventEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read Component Data - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 getProvenanceEvent( @@ -283,7 +262,7 @@ public class ProvenanceEventResource extends ApplicationResource { ) @QueryParam("clusterNodeId") final String clusterNodeId, @ApiParam( - value = "The provenence event id.", + value = "The provenance event id.", required = true ) @PathParam("id") final LongParameter id) { @@ -318,7 +297,7 @@ public class ProvenanceEventResource extends ApplicationResource { /** * Creates a new replay request for the content associated with the specified provenance event id. * - * @param httpServletRequest request + * @param httpServletRequest request * @param replayRequestEntity The replay request * @return A provenanceEventEntity */ @@ -326,12 +305,12 @@ public class ProvenanceEventResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("replays") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE') and hasRole('ROLE_DFM')") @ApiOperation( value = "Replays content from a provenance event", response = ProvenanceEventEntity.class, authorizations = { - @Authorization(value = "Provenance and Data Flow Manager", type = "ROLE_PROVENANCE and ROLE_DFM") + @Authorization(value = "Read Component Data - /data/{component-type}/{uuid}", type = ""), + @Authorization(value = "Write Component Data - /data/{component-type}/{uuid}", type = "") } ) @ApiResponses( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java index e618e8ad54..06f1d6fc9a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java @@ -66,8 +66,8 @@ import java.util.Map; */ @Path("/provenance") @Api( - value = "/provenance", - description = "Endpoint for accessing data flow provenance." + value = "/provenance", + description = "Endpoint for accessing data flow provenance." ) public class ProvenanceResource extends ApplicationResource { @@ -93,7 +93,7 @@ public class ProvenanceResource extends ApplicationResource { private void authorizeProvenanceRequest() { final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Map userContext; + final Map userContext; if (!StringUtils.isBlank(user.getClientAddress())) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -102,13 +102,13 @@ public class ProvenanceResource extends ApplicationResource { } final AuthorizationRequest request = new AuthorizationRequest.Builder() - .resource(ResourceFactory.getProvenanceResource()) - .identity(user.getIdentity()) - .anonymous(user.isAnonymous()) - .accessAttempt(true) - .action(RequestAction.READ) - .userContext(userContext) - .build(); + .resource(ResourceFactory.getProvenanceResource()) + .identity(user.getIdentity()) + .anonymous(user.isAnonymous()) + .accessAttempt(true) + .action(RequestAction.READ) + .userContext(userContext) + .build(); final AuthorizationResult result = authorizer.authorize(request); if (!Result.Approved.equals(result.getResult())) { @@ -126,20 +126,19 @@ public class ProvenanceResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("search-options") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Gets the searchable attributes for provenance events", response = ProvenanceOptionsEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getSearchOptions() { @@ -165,14 +164,13 @@ public class ProvenanceResource extends ApplicationResource { * Creates provenance using the specified query criteria. * * @param httpServletRequest request - * @param provenanceEntity A provenanceEntity + * @param provenanceEntity A provenanceEntity * @return A provenanceEntity */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("") // necessary due to bug in swagger - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Submits a provenance query", notes = "Provenance queries may be long running so this endpoint submits a request. The response will include the " @@ -181,15 +179,16 @@ public class ProvenanceResource extends ApplicationResource { + "should be deleted by the client who originally submitted it.", response = ProvenanceEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = ""), + @Authorization(value = "Read - /data/{component-type}/{uuid}", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response submitProvenanceRequest( @@ -260,7 +259,7 @@ public class ProvenanceResource extends ApplicationResource { /** * Gets the provenance with the specified id. * - * @param id The id of the provenance + * @param id The id of the provenance * @param clusterNodeId The id of node in the cluster to search. This is optional and only relevant when clustered. If clustered and it is not specified the entire cluster is searched. * @return A provenanceEntity */ @@ -268,21 +267,21 @@ public class ProvenanceResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Gets a provenance query", response = ProvenanceEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = ""), + @Authorization(value = "Read - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 getProvenance( @@ -327,29 +326,28 @@ public class ProvenanceResource extends ApplicationResource { * Deletes the provenance with the specified id. * * @param httpServletRequest request - * @param id The id of the provenance - * @param clusterNodeId The id of node in the cluster to search. This is optional and only relevant when clustered. If clustered and it is not specified the entire cluster is searched. + * @param id The id of the provenance + * @param clusterNodeId The id of node in the cluster to search. This is optional and only relevant when clustered. If clustered and it is not specified the entire cluster is searched. * @return A provenanceEntity */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Deletes a provenance query", response = ProvenanceEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = "") } ) @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.") + @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 deleteProvenance( @@ -396,21 +394,20 @@ public class ProvenanceResource extends ApplicationResource { /** * Submits a lineage request based on an event or a flowfile uuid. - * + *

* When querying for the lineage of an event you must specify the eventId and the eventDirection. The eventDirection must be 'parents' or 'children' and specifies whether we are going up or down * the flowfile ancestry. The uuid cannot be specified in these cases. - * + *

* When querying for the lineage of a flowfile you must specify the uuid. The eventId and eventDirection cannot be specified in this case. * * @param httpServletRequest request - * @param lineageEntity A lineageEntity + * @param lineageEntity A lineageEntity * @return A lineageEntity */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("lineage") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Submits a lineage query", notes = "Lineage queries may be long running so this endpoint submits a request. The response will include the " @@ -419,16 +416,17 @@ public class ProvenanceResource extends ApplicationResource { + "should be deleted by the client who originally submitted it.", response = LineageEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = ""), + @Authorization(value = "Read - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 submitLineageRequest( @@ -505,28 +503,28 @@ public class ProvenanceResource extends ApplicationResource { * Gets the lineage with the specified id. * * @param clusterNodeId The id of node in the cluster that the event/flowfile originated from. This is only required when clustered. - * @param id The id of the lineage + * @param id The id of the lineage * @return A lineageEntity */ @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("lineage/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Gets a lineage query", response = LineageEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = ""), + @Authorization(value = "Read - /data/{component-type}/{uuid}", type = "") } ) @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.") + @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 getLineage( @@ -565,29 +563,28 @@ public class ProvenanceResource extends ApplicationResource { * Deletes the lineage with the specified id. * * @param httpServletRequest request - * @param clusterNodeId The id of node in the cluster that the event/flowfile originated from. This is only required when clustered. - * @param id The id of the lineage + * @param clusterNodeId The id of node in the cluster that the event/flowfile originated from. This is only required when clustered. + * @param id The id of the lineage * @return A lineageEntity */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("lineage/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_PROVENANCE')") @ApiOperation( value = "Deletes a lineage query", response = LineageEntity.class, authorizations = { - @Authorization(value = "Provenance", type = "ROLE_PROVENANCE") + @Authorization(value = "Read - /provenance", type = "") } ) @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.") + @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 deleteLineage( @@ -627,6 +624,7 @@ public class ProvenanceResource extends ApplicationResource { } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java index 15ae5991ae..e99b2e376f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java @@ -59,8 +59,8 @@ import java.util.Set; */ @Path("/remote-process-groups") @Api( - value = "/remote-process-groups", - description = "Endpoint for managing a Remote Process Group." + value = "/remote-process-groups", + description = "Endpoint for managing a Remote Process Group." ) public class RemoteProcessGroupResource extends ApplicationResource { @@ -101,23 +101,20 @@ public class RemoteProcessGroupResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a remote process group", response = RemoteProcessGroupEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /remote-process-groups/{uuid}", type = "") } ) @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.") + @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 getRemoteProcessGroup( @@ -148,30 +145,29 @@ public class RemoteProcessGroupResource extends ApplicationResource { * Removes the specified remote process group. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. - * @param id The id of the remote process group to be removed. + * @param version The revision is used to verify the client is working with the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a new one will be generated. This value (whether specified or generated) is included in the response. + * @param id The id of the remote process group to be removed. * @return A remoteProcessGroupEntity. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a remote process group", response = RemoteProcessGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /remote-process-groups/{uuid}", type = "") } ) @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.") + @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 removeRemoteProcessGroup( @@ -199,49 +195,48 @@ public class RemoteProcessGroupResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable remoteProcessGroup = lookup.getRemoteProcessGroup(id); - remoteProcessGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteRemoteProcessGroup(id), - () -> { - final RemoteProcessGroupEntity entity = serviceFacade.deleteRemoteProcessGroup(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable remoteProcessGroup = lookup.getRemoteProcessGroup(id); + remoteProcessGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteRemoteProcessGroup(id), + () -> { + final RemoteProcessGroupEntity entity = serviceFacade.deleteRemoteProcessGroup(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } /** * Updates the specified remote process group input port. * - * @param httpServletRequest request - * @param id The id of the remote process group to update. - * @param portId The id of the input port to update. + * @param httpServletRequest request + * @param id The id of the remote process group to update. + * @param portId The id of the input port to update. * @param remoteProcessGroupPortEntity The remoteProcessGroupPortEntity - * * @return A remoteProcessGroupPortEntity */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/input-ports/{port-id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a remote port", + notes = NON_GUARANTEED_ENDPOINT, response = RemoteProcessGroupPortEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /remote-process-groups/{uuid}", type = "") } ) @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.") + @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 updateRemoteProcessGroupInputPort( @@ -277,59 +272,58 @@ public class RemoteProcessGroupResource extends ApplicationResource { final Revision revision = getRevision(remoteProcessGroupPortEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable remoteProcessGroupInputPort = lookup.getRemoteProcessGroupInputPort(id, portId); - remoteProcessGroupInputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateRemoteProcessGroupInputPort(id, requestRemoteProcessGroupPort), - () -> { - // update the specified remote process group - final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupInputPort(revision, id, requestRemoteProcessGroupPort); + serviceFacade, + revision, + lookup -> { + final Authorizable remoteProcessGroupInputPort = lookup.getRemoteProcessGroupInputPort(id, portId); + remoteProcessGroupInputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateRemoteProcessGroupInputPort(id, requestRemoteProcessGroupPort), + () -> { + // update the specified remote process group + final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupInputPort(revision, id, requestRemoteProcessGroupPort); - // get the updated revision - final RevisionDTO updatedRevision = controllerResponse.getRevision(); + // get the updated revision + final RevisionDTO updatedRevision = controllerResponse.getRevision(); - // build the response entity - final RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity(); - entity.setRevision(updatedRevision); - entity.setRemoteProcessGroupPort(controllerResponse.getRemoteProcessGroupPort()); + // build the response entity + final RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity(); + entity.setRevision(updatedRevision); + entity.setRemoteProcessGroupPort(controllerResponse.getRemoteProcessGroupPort()); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } /** * Updates the specified remote process group output port. * - * @param httpServletRequest request - * @param id The id of the remote process group to update. - * @param portId The id of the output port to update. + * @param httpServletRequest request + * @param id The id of the remote process group to update. + * @param portId The id of the output port to update. * @param remoteProcessGroupPortEntity The remoteProcessGroupPortEntity - * * @return A remoteProcessGroupPortEntity */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/output-ports/{port-id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a remote port", + notes = NON_GUARANTEED_ENDPOINT, response = RemoteProcessGroupPortEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /remote-process-groups/{uuid}", type = "") } ) @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.") + @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 updateRemoteProcessGroupOutputPort( @@ -366,35 +360,35 @@ public class RemoteProcessGroupResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(remoteProcessGroupPortEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable remoteProcessGroupOutputPort = lookup.getRemoteProcessGroupOutputPort(id, portId); - remoteProcessGroupOutputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateRemoteProcessGroupOutputPort(id, requestRemoteProcessGroupPort), - () -> { - // update the specified remote process group - final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupOutputPort(revision, id, requestRemoteProcessGroupPort); + serviceFacade, + revision, + lookup -> { + final Authorizable remoteProcessGroupOutputPort = lookup.getRemoteProcessGroupOutputPort(id, portId); + remoteProcessGroupOutputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateRemoteProcessGroupOutputPort(id, requestRemoteProcessGroupPort), + () -> { + // update the specified remote process group + final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupOutputPort(revision, id, requestRemoteProcessGroupPort); - // get the updated revision - final RevisionDTO updatedRevision = controllerResponse.getRevision(); + // get the updated revision + final RevisionDTO updatedRevision = controllerResponse.getRevision(); - // build the response entity - RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity(); - entity.setRevision(updatedRevision); - entity.setRemoteProcessGroupPort(controllerResponse.getRemoteProcessGroupPort()); + // build the response entity + RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity(); + entity.setRevision(updatedRevision); + entity.setRemoteProcessGroupPort(controllerResponse.getRemoteProcessGroupPort()); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } /** * Updates the specified remote process group. * - * @param httpServletRequest request - * @param id The id of the remote process group to update. + * @param httpServletRequest request + * @param id The id of the remote process group to update. * @param remoteProcessGroupEntity A remoteProcessGroupEntity. * @return A remoteProcessGroupEntity. */ @@ -402,21 +396,20 @@ public class RemoteProcessGroupResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a remote process group", response = RemoteProcessGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /remote-process-groups/{uuid}", type = "") } ) @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.") + @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 updateRemoteProcessGroup( @@ -446,56 +439,57 @@ public class RemoteProcessGroupResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(remoteProcessGroupEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getRemoteProcessGroup(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateRemoteProcessGroup(requestRemoteProcessGroup), - () -> { - // if the target uri is set we have to verify it here - we don't support updating the target uri on - // an existing remote process group, however if the remote process group is being created with an id - // as is the case in clustered mode we need to verify the remote process group. treat this request as - // though its a new remote process group. - if (requestRemoteProcessGroup.getTargetUri() != null) { - // parse the uri - final URI uri; - try { - uri = URI.create(requestRemoteProcessGroup.getTargetUri()); - } catch (final IllegalArgumentException e) { - throw new IllegalArgumentException("The specified remote process group URL is malformed: " + requestRemoteProcessGroup.getTargetUri()); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getRemoteProcessGroup(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateRemoteProcessGroup(requestRemoteProcessGroup), + () -> { + // if the target uri is set we have to verify it here - we don't support updating the target uri on + // an existing remote process group, however if the remote process group is being created with an id + // as is the case in clustered mode we need to verify the remote process group. treat this request as + // though its a new remote process group. + if (requestRemoteProcessGroup.getTargetUri() != null) { + // parse the uri + final URI uri; + try { + uri = URI.create(requestRemoteProcessGroup.getTargetUri()); + } catch (final IllegalArgumentException e) { + throw new IllegalArgumentException("The specified remote process group URL is malformed: " + requestRemoteProcessGroup.getTargetUri()); + } + + // validate each part of the uri + if (uri.getScheme() == null || uri.getHost() == null) { + throw new IllegalArgumentException("The specified remote process group URL is malformed: " + requestRemoteProcessGroup.getTargetUri()); + } + + if (!(uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https"))) { + throw new IllegalArgumentException("The specified remote process group URL is invalid because it is not http or https: " + requestRemoteProcessGroup.getTargetUri()); + } + + // normalize the uri to the other controller + String controllerUri = uri.toString(); + if (controllerUri.endsWith("/")) { + controllerUri = StringUtils.substringBeforeLast(controllerUri, "/"); + } + + // update with the normalized uri + requestRemoteProcessGroup.setTargetUri(controllerUri); } - // validate each part of the uri - if (uri.getScheme() == null || uri.getHost() == null) { - throw new IllegalArgumentException("The specified remote process group URL is malformed: " + requestRemoteProcessGroup.getTargetUri()); - } + // update the specified remote process group + final RemoteProcessGroupEntity entity = serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup); + populateRemainingRemoteProcessGroupEntityContent(entity); - if (!(uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https"))) { - throw new IllegalArgumentException("The specified remote process group URL is invalid because it is not http or https: " + requestRemoteProcessGroup.getTargetUri()); - } - - // normalize the uri to the other controller - String controllerUri = uri.toString(); - if (controllerUri.endsWith("/")) { - controllerUri = StringUtils.substringBeforeLast(controllerUri, "/"); - } - - // update with the normalized uri - requestRemoteProcessGroup.setTargetUri(controllerUri); + return clusterContext(generateOkResponse(entity)).build(); } - - // update the specified remote process group - final RemoteProcessGroupEntity entity = serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup); - populateRemainingRemoteProcessGroupEntityContent(entity); - - return clusterContext(generateOkResponse(entity)).build(); - } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java index 1025de2bf7..67ba737ee3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java @@ -65,8 +65,8 @@ import java.util.Set; */ @Path("/reporting-tasks") @Api( - value = "/reporting-tasks", - description = "Endpoint for managing a Reporting Task." + value = "/reporting-tasks", + description = "Endpoint for managing a Reporting Task." ) public class ReportingTaskResource extends ApplicationResource { @@ -135,23 +135,20 @@ public class ReportingTaskResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a reporting task", response = ReportingTaskEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /reporting-tasks/{uuid}", type = "") } ) @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.") + @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 getReportingTask( @@ -181,7 +178,7 @@ public class ReportingTaskResource extends ApplicationResource { /** * Returns the descriptor for the specified property. * - * @param id The id of the reporting task. + * @param id The id of the reporting task. * @param propertyName The property * @return a propertyDescriptorEntity */ @@ -189,23 +186,20 @@ public class ReportingTaskResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/descriptors") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a reporting task property descriptor", response = PropertyDescriptorEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /reporting-tasks/{uuid}", type = "") } ) @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.") + @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 getPropertyDescriptor( @@ -256,29 +250,28 @@ public class ReportingTaskResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/state") - // TODO - @PreAuthorize("hasAnyRole('ROLE_DFM')") @ApiOperation( - value = "Gets the state for a reporting task", - response = ComponentStateDTO.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Gets the state for a reporting task", + response = ComponentStateDTO.class, + authorizations = { + @Authorization(value = "Write - /reporting-tasks/{uuid}", type = "") + } ) @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.") - } + 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 getState( - @ApiParam( - value = "The reporting task id.", - required = true - ) - @PathParam("id") final String id) { + @ApiParam( + value = "The reporting task id.", + required = true + ) + @PathParam("id") final String id) { if (isReplicateRequest()) { return replicate(HttpMethod.GET); @@ -305,37 +298,36 @@ public class ReportingTaskResource extends ApplicationResource { * Clears the state for a reporting task. * * @param httpServletRequest servlet request - * @param id The id of the reporting task + * @param id The id of the reporting task * @return a componentStateEntity */ @POST @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}/state/clear-requests") - // TODO - @PreAuthorize("hasAnyRole('ROLE_DFM')") @ApiOperation( - value = "Clears the state for a reporting task", - response = ComponentStateDTO.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Clears the state for a reporting task", + response = ComponentStateDTO.class, + authorizations = { + @Authorization(value = "Write - /reporting-tasks/{uuid}", type = "") + } ) @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.") - } + 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 clearState( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The reporting task id.", - required = true - ) - @PathParam("id") final String id) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The reporting task id.", + required = true + ) + @PathParam("id") final String id) { if (isReplicateRequest()) { return replicate(HttpMethod.POST); @@ -367,8 +359,8 @@ public class ReportingTaskResource extends ApplicationResource { /** * Updates the specified a Reporting Task. * - * @param httpServletRequest request - * @param id The id of the reporting task to update. + * @param httpServletRequest request + * @param id The id of the reporting task to update. * @param reportingTaskEntity A reportingTaskEntity. * @return A reportingTaskEntity. */ @@ -376,21 +368,20 @@ public class ReportingTaskResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a reporting task", response = ReportingTaskEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /reporting-tasks/{uuid}", type = "") } ) @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.") + @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 updateReportingTask( @@ -427,20 +418,20 @@ public class ReportingTaskResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = getRevision(reportingTaskEntity, id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - Authorizable authorizable = lookup.getReportingTask(id); - authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO), - () -> { - // update the reporting task - final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, requestReportingTaskDTO); - populateRemainingReportingTaskEntityContent(entity); + serviceFacade, + revision, + lookup -> { + Authorizable authorizable = lookup.getReportingTask(id); + authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO), + () -> { + // update the reporting task + final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, requestReportingTaskDTO); + populateRemainingReportingTaskEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -448,33 +439,32 @@ public class ReportingTaskResource extends ApplicationResource { * Removes the specified reporting task. * * @param httpServletRequest request - * @param version The revision is used to verify the client is working with - * the latest version of the flow. - * @param clientId Optional client id. If the client id is not specified, a - * new one will be generated. This value (whether specified or generated) is - * included in the response. - * @param id The id of the reporting task to remove. + * @param version The revision is used to verify the client is working with + * the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a + * new one will be generated. This value (whether specified or generated) is + * included in the response. + * @param id The id of the reporting task to remove. * @return A entity containing the client id and an updated revision. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a reporting task", response = ReportingTaskEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /reporting-tasks/{uuid}", type = "") } ) @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.") + @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 removeReportingTask( @@ -502,22 +492,23 @@ public class ReportingTaskResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( - serviceFacade, - revision, - lookup -> { - final Authorizable reportingTask = lookup.getReportingTask(id); - reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }, - () -> serviceFacade.verifyDeleteReportingTask(id), - () -> { - // delete the specified reporting task - final ReportingTaskEntity entity = serviceFacade.deleteReportingTask(revision, id); - return clusterContext(generateOkResponse(entity)).build(); - } + serviceFacade, + revision, + lookup -> { + final Authorizable reportingTask = lookup.getReportingTask(id); + reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyDeleteReportingTask(id), + () -> { + // delete the specified reporting task + final ReportingTaskEntity entity = serviceFacade.deleteReportingTask(revision, id); + return clusterContext(generateOkResponse(entity)).build(); + } ); } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java index 83f313f84b..67c1b22399 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java @@ -16,18 +16,11 @@ */ package org.apache.nifi.web.api; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.HttpMethod; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; +import com.wordnik.swagger.annotations.Authorization; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.authorization.AccessDeniedException; import org.apache.nifi.authorization.AuthorizationRequest; @@ -43,19 +36,24 @@ import org.apache.nifi.web.NiFiServiceFacade; import org.apache.nifi.web.api.dto.ResourceDTO; import org.apache.nifi.web.api.entity.ResourcesEntity; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; -import com.wordnik.swagger.annotations.ApiResponse; -import com.wordnik.swagger.annotations.ApiResponses; -import com.wordnik.swagger.annotations.Authorization; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HttpMethod; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * RESTful endpoint for retrieving system diagnostics. */ @Path("/resources") @Api( - value = "/resources", - description = "Provides the resources in this NiFi that can have access/authorization policies." + value = "/resources", + description = "Provides the resources in this NiFi that can have access/authorization policies." ) public class ResourceResource extends ApplicationResource { @@ -65,7 +63,7 @@ public class ResourceResource extends ApplicationResource { private void authorizeResource() { final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Map userContext; + final Map userContext; if (!StringUtils.isBlank(user.getClientAddress())) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -74,13 +72,13 @@ public class ResourceResource extends ApplicationResource { } final AuthorizationRequest request = new AuthorizationRequest.Builder() - .resource(ResourceFactory.getResourceResource()) - .identity(user.getIdentity()) - .anonymous(user.isAnonymous()) - .accessAttempt(true) - .action(RequestAction.READ) - .userContext(userContext) - .build(); + .resource(ResourceFactory.getResourceResource()) + .identity(user.getIdentity()) + .anonymous(user.isAnonymous()) + .accessAttempt(true) + .action(RequestAction.READ) + .userContext(userContext) + .build(); final AuthorizationResult result = authorizer.authorize(request); if (!Result.Approved.equals(result.getResult())) { @@ -97,20 +95,17 @@ public class ResourceResource extends ApplicationResource { @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the available resources that support access/authorization policies", response = ResourcesEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /resources", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."),} + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."),} ) public Response getResources() { @@ -120,7 +115,6 @@ public class ResourceResource extends ApplicationResource { return replicate(HttpMethod.GET); } - // TODO - if unsecure, return no resources? final List resources = serviceFacade.getResources(); // create the response @@ -132,6 +126,7 @@ public class ResourceResource extends ApplicationResource { } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java index 0411bec0c9..66b1151999 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java @@ -34,6 +34,11 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; +import com.wordnik.swagger.annotations.Authorization; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.authorization.AccessDeniedException; import org.apache.nifi.authorization.AuthorizationRequest; @@ -60,11 +65,20 @@ import org.apache.nifi.web.api.entity.PeersEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; -import com.wordnik.swagger.annotations.ApiResponse; -import com.wordnik.swagger.annotations.ApiResponses; -import com.wordnik.swagger.annotations.Authorization; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HttpMethod; +import javax.ws.rs.Path; +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.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.apache.commons.lang3.StringUtils.isEmpty; /** * RESTful endpoint for managing a SiteToSite connection. @@ -81,8 +95,6 @@ public class SiteToSiteResource extends ApplicationResource { private NiFiServiceFacade serviceFacade; private ClusterCoordinator clusterCoordinator; private Authorizer authorizer; - public static final String CHECK_SUM = "checksum"; - public static final String RESPONSE_CODE = "responseCode"; private final ResponseCreator responseCreator = new ResponseCreator(); private final VersionNegotiator transportProtocolVersionNegotiator = new TransportProtocolVersionNegotiator(1); @@ -90,7 +102,7 @@ public class SiteToSiteResource extends ApplicationResource { /** * Authorizes access to Site To Site details. - * + *

* Note: Protected for testing purposes */ protected void authorizeSiteToSite() { @@ -119,18 +131,19 @@ public class SiteToSiteResource extends ApplicationResource { @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) - // TODO - @PreAuthorize("hasRole('ROLE_NIFI')") @ApiOperation( value = "Returns the details about this NiFi necessary to communicate via site to site", response = ControllerEntity.class, - authorizations = @Authorization(value = "NiFi", type = "ROLE_NIFI") + authorizations = { + @Authorization(value = "Read - /site-to-site", type = "") + } ) @ApiResponses( value = { - @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."), - @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") } ) public Response getSiteToSiteDetails(@Context HttpServletRequest req) { @@ -174,7 +187,9 @@ public class SiteToSiteResource extends ApplicationResource { @ApiOperation( value = "Returns the available Peers and its status of this NiFi", response = PeersEntity.class, - authorizations = @Authorization(value = "NiFi", type = "ROLE_NIFI") + authorizations = { + @Authorization(value = "Read - /site-to-site", type = "") + } ) @ApiResponses( value = { @@ -246,6 +261,7 @@ public class SiteToSiteResource extends ApplicationResource { } // setters + public void setServiceFacade(final NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java index 9669017ece..e30de40d5d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java @@ -16,9 +16,20 @@ */ package org.apache.nifi.web.api; -import java.net.URI; -import java.util.Set; -import java.util.stream.Collectors; +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.user.NiFiUserUtils; +import org.apache.nifi.controller.Snippet; +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; @@ -32,30 +43,17 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - -import org.apache.nifi.authorization.Authorizer; -import org.apache.nifi.authorization.RequestAction; -import org.apache.nifi.authorization.user.NiFiUserUtils; -import org.apache.nifi.controller.Snippet; -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 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 java.net.URI; +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." + value = "/snippets", + description = "Endpoint for accessing dataflow snippets." ) public class SnippetResource extends ApplicationResource { @@ -95,38 +93,35 @@ public class SnippetResource extends ApplicationResource { * Creates a snippet based off the specified configuration. * * @param httpServletRequest request - * @param snippetEntity A snippetEntity + * @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") - } + value = "Creates a snippet", + response = SnippetEntity.class, + authorizations = { + @Authorization(value = "Read - /{component-type}/{uuid} - For each component in the Snippet", type = "") + } ) @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.") - } + 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 createSnippet( - @Context HttpServletRequest httpServletRequest, - @ApiParam( - value = "The snippet configuration details.", - required = true - ) - final SnippetEntity snippetEntity) { + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The snippet configuration details.", + required = true + ) + final SnippetEntity snippetEntity) { if (snippetEntity == null || snippetEntity.getSnippet() == null) { throw new IllegalArgumentException("Snippet details must be specified."); @@ -165,46 +160,45 @@ public class SnippetResource extends ApplicationResource { } /** - * Updates the specified snippet. The contents of the snippet (component - * ids) cannot be updated once the snippet is created. + * Move's the components in this Snippet into a new Process Group. * * @param httpServletRequest request - * @param snippetId The id of the snippet. - * @param snippetEntity A snippetEntity + * @param snippetId The id of the snippet. + * @param snippetEntity A snippetEntity * @return A snippetEntity */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Updates a snippet", - response = SnippetEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Move's the components in this Snippet into a new Process Group and drops the snippet", + response = SnippetEntity.class, + authorizations = { + @Authorization(value = "Write Process Group - /process-groups/{uuid}", type = ""), + @Authorization(value = "Write - /{component-type}/{uuid} - For each component in the Snippet", type = "") + } ) @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.") - } + 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 updateSnippet( - @Context HttpServletRequest httpServletRequest, - @ApiParam( - value = "The snippet id.", - required = true - ) - @PathParam("id") String snippetId, - @ApiParam( - value = "The snippet configuration details.", - required = true - ) final SnippetEntity snippetEntity) { + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The snippet id.", + required = true + ) + @PathParam("id") String snippetId, + @ApiParam( + value = "The snippet configuration details.", + required = true + ) final SnippetEntity snippetEntity) { if (snippetEntity == null || snippetEntity.getSnippet() == null) { throw new IllegalArgumentException("Snippet details must be specified."); @@ -214,7 +208,7 @@ public class SnippetResource extends ApplicationResource { final SnippetDTO requestSnippetDTO = snippetEntity.getSnippet(); if (!snippetId.equals(requestSnippetDTO.getId())) { throw new IllegalArgumentException(String.format("The snippet id (%s) in the request body does not equal the " - + "snippet id of the requested resource (%s).", requestSnippetDTO.getId(), snippetId)); + + "snippet id of the requested resource (%s).", requestSnippetDTO.getId(), snippetId)); } if (isReplicateRequest()) { @@ -224,25 +218,25 @@ public class SnippetResource extends ApplicationResource { // get the revision from this snippet final Set revisions = serviceFacade.getRevisionsFromSnippet(snippetId); return withWriteLock( - serviceFacade, - revisions, - lookup -> { - // ensure write access to the target process group - if (requestSnippetDTO.getParentGroupId() != null) { - lookup.getProcessGroup(requestSnippetDTO.getParentGroupId()).authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - } + serviceFacade, + revisions, + lookup -> { + // ensure write access to the target process group + if (requestSnippetDTO.getParentGroupId() != null) { + lookup.getProcessGroup(requestSnippetDTO.getParentGroupId()).authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + } - // ensure read permission to every component in the snippet - final Snippet snippet = lookup.getSnippet(snippetId); - authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); - }, - () -> serviceFacade.verifyUpdateSnippet(requestSnippetDTO, revisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())), - () -> { - // update the snippet - final SnippetEntity entity = serviceFacade.updateSnippet(revisions, snippetEntity.getSnippet()); - populateRemainingSnippetEntityContent(entity); - return clusterContext(generateOkResponse(entity)).build(); - } + // ensure write permission to every component in the snippet + final Snippet snippet = lookup.getSnippet(snippetId); + authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); + }, + () -> serviceFacade.verifyUpdateSnippet(requestSnippetDTO, revisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())), + () -> { + // update the snippet + final SnippetEntity entity = serviceFacade.updateSnippet(revisions, snippetEntity.getSnippet()); + populateRemainingSnippetEntityContent(entity); + return clusterContext(generateOkResponse(entity)).build(); + } ); } @@ -250,37 +244,36 @@ public class SnippetResource extends ApplicationResource { * Removes the specified snippet. * * @param httpServletRequest request - * @param snippetId The id of the snippet to remove. + * @param snippetId The id of the snippet to remove. * @return A entity containing the client id and an updated revision. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( - value = "Deletes the components in a snippet and drops the snippet", - response = SnippetEntity.class, - authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") - } + value = "Deletes the components in a snippet and drops the snippet", + response = SnippetEntity.class, + authorizations = { + @Authorization(value = "Write - /{component-type}/{uuid} - For each component in the Snippet", type = "") + } ) @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.") - } + 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 deleteSnippet( - @Context final HttpServletRequest httpServletRequest, - @ApiParam( - value = "The snippet id.", - required = true - ) - @PathParam("id") final String snippetId) { + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The snippet id.", + required = true + ) + @PathParam("id") final String snippetId) { if (isReplicateRequest()) { return replicate(HttpMethod.DELETE); @@ -289,23 +282,24 @@ public class SnippetResource extends ApplicationResource { // get the revision from this snippet final Set revisions = serviceFacade.getRevisionsFromSnippet(snippetId); return withWriteLock( - serviceFacade, - revisions, - lookup -> { - // ensure read permission to every component in the snippet - final Snippet snippet = lookup.getSnippet(snippetId); - authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); - }, - () -> serviceFacade.verifyDeleteSnippet(snippetId, revisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())), - () -> { - // delete the specified snippet - final SnippetEntity snippetEntity = serviceFacade.deleteSnippet(revisions, snippetId); - return clusterContext(generateOkResponse(snippetEntity)).build(); - } + serviceFacade, + revisions, + lookup -> { + // ensure read permission to every component in the snippet + final Snippet snippet = lookup.getSnippet(snippetId); + authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); + }, + () -> serviceFacade.verifyDeleteSnippet(snippetId, revisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())), + () -> { + // delete the specified snippet + final SnippetEntity snippetEntity = serviceFacade.deleteSnippet(revisions, snippetId); + return clusterContext(generateOkResponse(snippetEntity)).build(); + } ); } /* setters */ + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java index d9db9928b2..641042b3b2 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java @@ -58,8 +58,8 @@ import java.util.Set; */ @Path("/system-diagnostics") @Api( - value = "/system-diagnostics", - description = "Endpoint for accessing system diagnostics." + value = "/system-diagnostics", + description = "Endpoint for accessing system diagnostics." ) public class SystemDiagnosticsResource extends ApplicationResource { @@ -69,7 +69,7 @@ public class SystemDiagnosticsResource extends ApplicationResource { private void authorizeSystem() { final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Map userContext; + final Map userContext; if (!StringUtils.isBlank(user.getClientAddress())) { userContext = new HashMap<>(); userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); @@ -78,13 +78,13 @@ public class SystemDiagnosticsResource extends ApplicationResource { } final AuthorizationRequest request = new AuthorizationRequest.Builder() - .resource(ResourceFactory.getSystemResource()) - .identity(user.getIdentity()) - .anonymous(user.isAnonymous()) - .accessAttempt(true) - .action(RequestAction.READ) - .userContext(userContext) - .build(); + .resource(ResourceFactory.getSystemResource()) + .identity(user.getIdentity()) + .anonymous(user.isAnonymous()) + .accessAttempt(true) + .action(RequestAction.READ) + .userContext(userContext) + .build(); final AuthorizationResult result = authorizer.authorize(request); if (!Result.Approved.equals(result.getResult())) { @@ -102,32 +102,29 @@ public class SystemDiagnosticsResource extends ApplicationResource { @GET @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets the diagnostics for the system NiFi is running on", response = SystemDiagnosticsEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /system", type = "") } ) @ApiResponses( value = { - @ApiResponse(code = 401, message = "Client could not be authenticated."), - @ApiResponse(code = 403, message = "Client is not authorized to make this request."),} + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."),} ) public Response getSystemDiagnostics( @ApiParam( - value = "Whether or not to include the breakdown per node. Optional, defaults to false", - required = false + value = "Whether or not to include the breakdown per node. Optional, defaults to false", + required = false ) @QueryParam("nodewise") @DefaultValue(NODEWISE) final Boolean nodewise, @ApiParam( - value = "The id of the node where to get the status.", - required = false + value = "The id of the node where to get the status.", + required = false ) - @QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException { + @QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException { authorizeSystem(); @@ -174,6 +171,7 @@ public class SystemDiagnosticsResource extends ApplicationResource { } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java index 3c492fcc7a..abc8fe112d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java @@ -16,8 +16,21 @@ */ package org.apache.nifi.web.api; -import java.nio.charset.StandardCharsets; -import java.util.Set; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; +import com.wordnik.swagger.annotations.Authorization; +import org.apache.commons.lang3.StringUtils; +import org.apache.nifi.authorization.Authorizer; +import org.apache.nifi.authorization.RequestAction; +import org.apache.nifi.authorization.resource.Authorizable; +import org.apache.nifi.authorization.user.NiFiUserUtils; +import org.apache.nifi.persistence.TemplateSerializer; +import org.apache.nifi.web.NiFiServiceFacade; +import org.apache.nifi.web.api.dto.TemplateDTO; +import org.apache.nifi.web.api.entity.TemplateEntity; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -30,31 +43,16 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - -import org.apache.commons.lang3.StringUtils; -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.NiFiUserUtils; -import org.apache.nifi.persistence.TemplateSerializer; -import org.apache.nifi.web.NiFiServiceFacade; -import org.apache.nifi.web.api.dto.TemplateDTO; -import org.apache.nifi.web.api.entity.TemplateEntity; - -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 java.nio.charset.StandardCharsets; +import java.util.Set; /** * RESTful endpoint for managing a Template. */ @Path("/templates") @Api( - value = "/templates", - description = "Endpoint for managing a Template." + value = "/templates", + description = "Endpoint for managing a Template." ) public class TemplateResource extends ApplicationResource { @@ -76,32 +74,6 @@ public class TemplateResource extends ApplicationResource { return templateEntities; } - /** - * Populate the uri's for the specified templates. - * - * @param templateEntity templates - * @return templates - */ - public TemplateEntity populateRemainingTemplateEntityContent(TemplateEntity templateEntity) { - if (templateEntity.getTemplate() != null) { - populateRemainingTemplateContent(templateEntity.getTemplate()); - } - return templateEntity; - } - - /** - * Populates the uri for the specified templates. - * - * @param templates templates - * @return templates - */ - public Set populateRemainingTemplatesContent(Set templates) { - for (TemplateDTO template : templates) { - populateRemainingTemplateContent(template); - } - return templates; - } - /** * Populates the uri for the specified template. */ @@ -121,23 +93,20 @@ public class TemplateResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_XML) @Path("{id}/download") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Exports a template", response = TemplateDTO.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /templates/{uuid}", type = "") } ) @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.") + @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 exportTemplate( @@ -185,28 +154,27 @@ public class TemplateResource extends ApplicationResource { * Removes the specified template. * * @param httpServletRequest request - * @param id The id of the template to remove. + * @param id The id of the template to remove. * @return A templateEntity. */ @DELETE @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a template", response = TemplateEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /templates/{uuid}", type = "") } ) @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.") + @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 removeTemplate( @@ -242,6 +210,7 @@ public class TemplateResource extends ApplicationResource { } // setters + public void setServiceFacade(NiFiServiceFacade serviceFacade) { this.serviceFacade = serviceFacade; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java index b944bf7a33..049b5d21f5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java @@ -122,12 +122,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("users") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Creates a user", + notes = NON_GUARANTEED_ENDPOINT, response = UserEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /tenants", type = "") } ) @ApiResponses( @@ -205,14 +205,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("users/{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a user", + notes = NON_GUARANTEED_ENDPOINT, response = UserEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /tenants", type = "") } ) @ApiResponses( @@ -262,14 +260,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("users") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets all users", + notes = NON_GUARANTEED_ENDPOINT, response = UsersEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /tenants", type = "") } ) @ApiResponses( @@ -322,12 +318,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("users/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a user", + notes = NON_GUARANTEED_ENDPOINT, response = UserEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /tenants", type = "") } ) @ApiResponses( @@ -411,12 +407,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("users/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a user", + notes = NON_GUARANTEED_ENDPOINT, response = UserEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /tenants", type = "") } ) @ApiResponses( @@ -462,7 +458,7 @@ public class TenantsResource extends ApplicationResource { revision, lookup -> { final Authorizable tenants = lookup.getTenant(); - tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); + tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, () -> { @@ -508,12 +504,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("user-groups") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Creates a user group", + notes = NON_GUARANTEED_ENDPOINT, response = UserGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /tenants", type = "") } ) @ApiResponses( @@ -591,14 +587,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("user-groups/{id}") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets a user group", + notes = NON_GUARANTEED_ENDPOINT, response = UserGroupEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /tenants", type = "") } ) @ApiResponses( @@ -648,14 +642,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("user-groups") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Gets all user groups", + notes = NON_GUARANTEED_ENDPOINT, response = UserGroupsEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM"), - @Authorization(value = "Administrator", type = "ROLE_ADMIN") + @Authorization(value = "Read - /tenants", type = "") } ) @ApiResponses( @@ -707,12 +699,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("user-groups/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Updates a user group", + notes = NON_GUARANTEED_ENDPOINT, response = UserGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /tenants", type = "") } ) @ApiResponses( @@ -796,12 +788,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("user-groups/{id}") - // TODO - @PreAuthorize("hasRole('ROLE_DFM')") @ApiOperation( value = "Deletes a user group", + notes = NON_GUARANTEED_ENDPOINT, response = UserGroupEntity.class, authorizations = { - @Authorization(value = "Data Flow Manager", type = "ROLE_DFM") + @Authorization(value = "Write - /tenants", type = "") } ) @ApiResponses( @@ -847,7 +839,7 @@ public class TenantsResource extends ApplicationResource { revision, lookup -> { final Authorizable tenants = lookup.getTenant(); - tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); + tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, () -> { @@ -872,14 +864,12 @@ public class TenantsResource extends ApplicationResource { @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Path("search-results") - // TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')") @ApiOperation( value = "Searches the cluster for a node with the specified address", + notes = NON_GUARANTEED_ENDPOINT, response = ClusterSearchResultsEntity.class, authorizations = { - @Authorization(value = "Read Only", type = "ROLE_MONITOR"), - @Authorization(value = "DFM", type = "ROLE_DFM"), - @Authorization(value = "Admin", type = "ROLE_ADMIN") + @Authorization(value = "Read - /tenants", type = "") } ) @ApiResponses( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/InvalidRevisionExceptionMapper.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/InvalidRevisionExceptionMapper.java index d2c648c516..73304e7455 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/InvalidRevisionExceptionMapper.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/InvalidRevisionExceptionMapper.java @@ -16,14 +16,16 @@ */ package org.apache.nifi.web.api.config; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; -import javax.ws.rs.ext.Provider; import org.apache.nifi.util.StringUtils; import org.apache.nifi.web.InvalidRevisionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + /** * Maps invalid revision exceptions into client responses. */ @@ -35,13 +37,13 @@ public class InvalidRevisionExceptionMapper implements ExceptionMapper getResources() { final List resources = new ArrayList<>(); + resources.add(ResourceFactory.getFlowResource()); resources.add(ResourceFactory.getSystemResource()); resources.add(ResourceFactory.getControllerResource()); - resources.add(ResourceFactory.getFlowResource()); + resources.add(ResourceFactory.getCountersResource()); resources.add(ResourceFactory.getProvenanceResource()); + resources.add(ResourceFactory.getPoliciesResource()); + resources.add(ResourceFactory.getTenantResource()); resources.add(ResourceFactory.getProxyResource()); resources.add(ResourceFactory.getResourceResource()); + resources.add(ResourceFactory.getSiteToSiteResource()); final ProcessGroup root = flowController.getGroup(flowController.getRootGroupId()); // add each processor for (final ProcessorNode processor : root.findAllProcessors()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.Processor, processor.getIdentifier(), processor.getName())); - resources.add(ResourceFactory.getDataResource(processor.getResource())); + final Resource processorResource = processor.getResource(); + resources.add(processorResource); + resources.add(ResourceFactory.getDataResource(processorResource)); + resources.add(ResourceFactory.getPolicyResource(processorResource)); } // add each label for (final Label label : root.findAllLabels()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.Label, label.getIdentifier(), label.getValue())); + final Resource labelResource = label.getResource(); + resources.add(labelResource); + resources.add(ResourceFactory.getPolicyResource(labelResource)); } // add each process group for (final ProcessGroup processGroup : root.findAllProcessGroups()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.ProcessGroup, processGroup.getIdentifier(), processGroup.getName())); - resources.add(ResourceFactory.getDataResource(processGroup.getResource())); + final Resource processGroupResource = processGroup.getResource(); + resources.add(processGroupResource); + resources.add(ResourceFactory.getDataResource(processGroupResource)); + resources.add(ResourceFactory.getPolicyResource(processGroupResource)); } // add each remote process group for (final RemoteProcessGroup remoteProcessGroup : root.findAllRemoteProcessGroups()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.RemoteProcessGroup, remoteProcessGroup.getIdentifier(), remoteProcessGroup.getName())); - resources.add(ResourceFactory.getDataResource(remoteProcessGroup.getResource())); + final Resource remoteProcessGroupResource = remoteProcessGroup.getResource(); + resources.add(remoteProcessGroupResource); + resources.add(ResourceFactory.getDataResource(remoteProcessGroupResource)); + resources.add(ResourceFactory.getPolicyResource(remoteProcessGroupResource)); } // add each input port for (final Port inputPort : root.findAllInputPorts()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.InputPort, inputPort.getIdentifier(), inputPort.getName())); - resources.add(ResourceFactory.getDataResource(inputPort.getResource())); + final Resource inputPortResource = inputPort.getResource(); + resources.add(inputPortResource); + resources.add(ResourceFactory.getDataResource(inputPortResource)); + resources.add(ResourceFactory.getPolicyResource(inputPortResource)); + if (inputPort instanceof RootGroupPort) { + resources.add(ResourceFactory.getDataTransferResource(inputPortResource)); + } } // add each output port for (final Port outputPort : root.findAllOutputPorts()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.OutputPort, outputPort.getIdentifier(), outputPort.getName())); - resources.add(ResourceFactory.getDataResource(outputPort.getResource())); + final Resource outputPortResource = outputPort.getResource(); + resources.add(outputPortResource); + resources.add(ResourceFactory.getDataResource(outputPortResource)); + resources.add(ResourceFactory.getPolicyResource(outputPortResource)); + if (outputPort instanceof RootGroupPort) { + resources.add(ResourceFactory.getDataTransferResource(outputPortResource)); + } } // add each controller service - for (final ControllerServiceNode controllerService : flowController.getAllControllerServices()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.ControllerService, controllerService.getIdentifier(), controllerService.getName())); - } + final Consumer csConsumer = controllerService -> { + final Resource controllerServiceResource = controllerService.getResource(); + resources.add(controllerServiceResource); + resources.add(ResourceFactory.getPolicyResource(controllerServiceResource)); + }; + + flowController.getAllControllerServices().forEach(csConsumer); + root.findAllControllerServices().forEach(csConsumer); + // add each reporting task for (final ReportingTaskNode reportingTask : flowController.getAllReportingTasks()) { - resources.add(ResourceFactory.getComponentResource(ResourceType.ReportingTask, reportingTask.getIdentifier(), reportingTask.getName())); + final Resource reportingTaskResource = reportingTask.getResource(); + resources.add(reportingTaskResource); + resources.add(ResourceFactory.getPolicyResource(reportingTaskResource)); } // add each template for (final Template template : root.findAllTemplates()) { - final TemplateDTO details = template.getDetails(); - resources.add(ResourceFactory.getComponentResource(ResourceType.Template, details.getId(), details.getName())); + final Resource templateResource = template.getResource(); + resources.add(templateResource); + resources.add(ResourceFactory.getPolicyResource(templateResource)); } - // TODO - need token resource? - // resources.add(ResourceFactory.getTokenResource()); return resources; }