Repository: nifi Updated Branches: refs/heads/master e9da90812 -> c2bfc4ef2
http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/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 06f1d6f..4e7a171 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 @@ -33,12 +33,12 @@ 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.NiFiUserUtils; -import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator; import org.apache.nifi.web.NiFiServiceFacade; import org.apache.nifi.web.api.dto.provenance.ProvenanceDTO; import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO; import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO; import org.apache.nifi.web.api.dto.provenance.lineage.LineageRequestDTO; +import org.apache.nifi.web.api.entity.ComponentEntity; import org.apache.nifi.web.api.entity.LineageEntity; import org.apache.nifi.web.api.entity.ProvenanceEntity; import org.apache.nifi.web.api.entity.ProvenanceOptionsEntity; @@ -164,7 +164,7 @@ public class ProvenanceResource extends ApplicationResource { * Creates provenance using the specified query criteria. * * @param httpServletRequest request - * @param provenanceEntity A provenanceEntity + * @param requestProvenanceEntity A provenanceEntity * @return A provenanceEntity */ @POST @@ -196,20 +196,20 @@ public class ProvenanceResource extends ApplicationResource { @ApiParam( value = "The provenance query details.", required = true - ) ProvenanceEntity provenanceEntity) { - - authorizeProvenanceRequest(); + ) ProvenanceEntity requestProvenanceEntity) { // check the request - if (provenanceEntity == null) { - provenanceEntity = new ProvenanceEntity(); + if (requestProvenanceEntity == null) { + requestProvenanceEntity = new ProvenanceEntity(); } // get the provenance - ProvenanceDTO provenanceDto = provenanceEntity.getProvenance(); - if (provenanceDto == null) { - provenanceDto = new ProvenanceDTO(); - provenanceEntity.setProvenance(provenanceDto); + final ProvenanceDTO requestProvenanceDto; + if (requestProvenanceEntity.getProvenance() != null) { + requestProvenanceDto = requestProvenanceEntity.getProvenance(); + } else { + requestProvenanceDto = new ProvenanceDTO(); + requestProvenanceEntity.setProvenance(requestProvenanceDto); } // replicate if cluster manager @@ -219,41 +219,45 @@ public class ProvenanceResource extends ApplicationResource { headersToOverride.put("content-type", MediaType.APPLICATION_JSON); // determine where this request should be sent - if (provenanceDto.getRequest() == null || provenanceDto.getRequest().getClusterNodeId() == null) { + if (requestProvenanceDto.getRequest() == null || requestProvenanceDto.getRequest().getClusterNodeId() == null) { // replicate to all nodes - return replicate(HttpMethod.POST, provenanceEntity, headersToOverride); + return replicate(HttpMethod.POST, requestProvenanceEntity, headersToOverride); } else { - return replicate(HttpMethod.POST, provenanceEntity, provenanceDto.getRequest().getClusterNodeId(), headersToOverride); + return replicate(HttpMethod.POST, requestProvenanceEntity, requestProvenanceDto.getRequest().getClusterNodeId(), headersToOverride); } } - // handle expects request (usually from the cluster manager) - final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER); - if (expects != null) { - return generateContinueResponse().build(); - } + return withWriteLock( + serviceFacade, + requestProvenanceEntity, + lookup -> authorizeProvenanceRequest(), + null, + (provenanceEntity) -> { + final ProvenanceDTO provenanceDTO = provenanceEntity.getProvenance(); - // ensure the id is the same across the cluster - final String provenanceId = generateUuid(); + // ensure the id is the same across the cluster + final String provenanceId = generateUuid(); - // set the provenance id accordingly - provenanceDto.setId(provenanceId); + // set the provenance id accordingly + provenanceDTO.setId(provenanceId); - // submit the provenance request - final ProvenanceDTO dto = serviceFacade.submitProvenance(provenanceDto); - populateRemainingProvenanceContent(dto); + // submit the provenance request + final ProvenanceDTO dto = serviceFacade.submitProvenance(provenanceDTO); + populateRemainingProvenanceContent(dto); - // set the cluster id if necessary - if (provenanceDto.getRequest() != null && provenanceDto.getRequest().getClusterNodeId() != null) { - dto.getRequest().setClusterNodeId(provenanceDto.getRequest().getClusterNodeId()); - } + // set the cluster id if necessary + if (provenanceDTO.getRequest() != null && provenanceDTO.getRequest().getClusterNodeId() != null) { + dto.getRequest().setClusterNodeId(provenanceDTO.getRequest().getClusterNodeId()); + } - // create the response entity - final ProvenanceEntity entity = new ProvenanceEntity(); - entity.setProvenance(dto); + // create the response entity + final ProvenanceEntity entity = new ProvenanceEntity(); + entity.setProvenance(dto); - // generate the response - return clusterContext(generateCreatedResponse(URI.create(dto.getUri()), entity)).build(); + // generate the response + return clusterContext(generateCreatedResponse(URI.create(dto.getUri()), entity)).build(); + } + ); } /** @@ -363,8 +367,6 @@ public class ProvenanceResource extends ApplicationResource { ) @PathParam("id") final String id) { - authorizeProvenanceRequest(); - // replicate if cluster manager if (isReplicateRequest()) { // determine where this request should be sent @@ -376,20 +378,22 @@ public class ProvenanceResource extends ApplicationResource { } } - // handle expects request (usually from the cluster manager) - final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER); - if (expects != null) { - return generateContinueResponse().build(); - } + final ComponentEntity requestEntity = new ComponentEntity(); + requestEntity.setId(id); - // delete the provenance - serviceFacade.deleteProvenance(id); - - // create the response entity - final ProvenanceEntity entity = new ProvenanceEntity(); + return withWriteLock( + serviceFacade, + requestEntity, + lookup -> authorizeProvenanceRequest(), + null, + (entity) -> { + // delete the provenance + serviceFacade.deleteProvenance(entity.getId()); - // generate the response - return clusterContext(generateOkResponse(entity)).build(); + // generate the response + return clusterContext(generateOkResponse(new ProvenanceEntity())).build(); + } + ); } /** @@ -401,7 +405,7 @@ public class ProvenanceResource extends ApplicationResource { * 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 requestLineageEntity A lineageEntity * @return A lineageEntity */ @POST @@ -434,17 +438,15 @@ public class ProvenanceResource extends ApplicationResource { @ApiParam( value = "The lineage query details.", required = true - ) final LineageEntity lineageEntity) { + ) final LineageEntity requestLineageEntity) { - authorizeProvenanceRequest(); - - if (lineageEntity == null || lineageEntity.getLineage() == null || lineageEntity.getLineage().getRequest() == null) { + if (requestLineageEntity == null || requestLineageEntity.getLineage() == null || requestLineageEntity.getLineage().getRequest() == null) { throw new IllegalArgumentException("Lineage request must be specified."); } // ensure the request is well formed - final LineageDTO lineageDto = lineageEntity.getLineage(); - final LineageRequestDTO requestDto = lineageDto.getRequest(); + final LineageDTO requestLineageDto = requestLineageEntity.getLineage(); + final LineageRequestDTO requestDto = requestLineageDto.getRequest(); // ensure the type has been specified if (requestDto.getLineageRequestType() == null) { @@ -477,26 +479,30 @@ public class ProvenanceResource extends ApplicationResource { // change content type to JSON for serializing entity final Map<String, String> headersToOverride = new HashMap<>(); headersToOverride.put("content-type", MediaType.APPLICATION_JSON); - return replicate(HttpMethod.POST, lineageEntity, requestDto.getClusterNodeId(), headersToOverride); - } - - // handle expects request (usually from the cluster manager) - final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER); - if (expects != null) { - return generateContinueResponse().build(); + return replicate(HttpMethod.POST, requestLineageEntity, requestDto.getClusterNodeId(), headersToOverride); } - // get the provenance event - final LineageDTO dto = serviceFacade.submitLineage(lineageDto); - dto.getRequest().setClusterNodeId(requestDto.getClusterNodeId()); - populateRemainingLineageContent(dto); - - // create a response entity - final LineageEntity entity = new LineageEntity(); - entity.setLineage(dto); - - // generate the response - return clusterContext(generateOkResponse(entity)).build(); + return withWriteLock( + serviceFacade, + requestLineageEntity, + lookup -> authorizeProvenanceRequest(), + null, + (lineageEntity) -> { + final LineageDTO lineageDTO = lineageEntity.getLineage(); + + // get the provenance event + final LineageDTO dto = serviceFacade.submitLineage(lineageDTO); + dto.getRequest().setClusterNodeId(lineageDTO.getRequest().getClusterNodeId()); + populateRemainingLineageContent(dto); + + // create a response entity + final LineageEntity entity = new LineageEntity(); + entity.setLineage(dto); + + // generate the response + return clusterContext(generateOkResponse(entity)).build(); + } + ); } /** @@ -600,27 +606,27 @@ public class ProvenanceResource extends ApplicationResource { ) @PathParam("id") final String id) { - authorizeProvenanceRequest(); - // replicate if cluster manager if (isReplicateRequest()) { return replicate(HttpMethod.DELETE, clusterNodeId); } - // handle expects request (usually from the cluster manager) - final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER); - if (expects != null) { - return generateContinueResponse().build(); - } - - // delete the lineage - serviceFacade.deleteLineage(id); + final ComponentEntity requestEntity = new ComponentEntity(); + requestEntity.setId(id); - // create the response entity - final LineageEntity entity = new LineageEntity(); + return withWriteLock( + serviceFacade, + requestEntity, + lookup -> authorizeProvenanceRequest(), + null, + (entity) -> { + // delete the lineage + serviceFacade.deleteLineage(entity.getId()); - // generate the response - return clusterContext(generateOkResponse(entity)).build(); + // generate the response + return clusterContext(generateOkResponse(new LineageEntity())).build(); + } + ); } // setters http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/RemoteProcessGroupResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/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 e99b2e3..0f91aca 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 @@ -192,18 +192,22 @@ public class RemoteProcessGroupResource extends ApplicationResource { return replicate(HttpMethod.DELETE); } + final RemoteProcessGroupEntity requestRemoteProcessGroupEntity = new RemoteProcessGroupEntity(); + requestRemoteProcessGroupEntity.setId(id); + // handle expects request (usually from the cluster manager) - final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); + final Revision requestRevision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( serviceFacade, - revision, + requestRemoteProcessGroupEntity, + requestRevision, lookup -> { final Authorizable remoteProcessGroup = lookup.getRemoteProcessGroup(id); remoteProcessGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, () -> serviceFacade.verifyDeleteRemoteProcessGroup(id), - () -> { - final RemoteProcessGroupEntity entity = serviceFacade.deleteRemoteProcessGroup(revision, id); + (revision, remoteProcessGroupEntity) -> { + final RemoteProcessGroupEntity entity = serviceFacade.deleteRemoteProcessGroup(revision, remoteProcessGroupEntity.getId()); return clusterContext(generateOkResponse(entity)).build(); } ); @@ -215,7 +219,7 @@ public class RemoteProcessGroupResource extends ApplicationResource { * @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 + * @param requestRemoteProcessGroupPortEntity The remoteProcessGroupPortEntity * @return A remoteProcessGroupPortEntity */ @PUT @@ -241,20 +245,31 @@ public class RemoteProcessGroupResource extends ApplicationResource { ) public Response updateRemoteProcessGroupInputPort( @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The remote process group id.", + required = true + ) @PathParam("id") final String id, + @ApiParam( + value = "The remote process group port id.", + required = true + ) @PathParam("port-id") final String portId, - final RemoteProcessGroupPortEntity remoteProcessGroupPortEntity) { + @ApiParam( + value = "The remote process group port.", + required = true + ) final RemoteProcessGroupPortEntity requestRemoteProcessGroupPortEntity) { - if (remoteProcessGroupPortEntity == null || remoteProcessGroupPortEntity.getRemoteProcessGroupPort() == null) { + if (requestRemoteProcessGroupPortEntity == null || requestRemoteProcessGroupPortEntity.getRemoteProcessGroupPort() == null) { throw new IllegalArgumentException("Remote process group port details must be specified."); } - if (remoteProcessGroupPortEntity.getRevision() == null) { + if (requestRemoteProcessGroupPortEntity.getRevision() == null) { throw new IllegalArgumentException("Revision must be specified."); } // ensure the ids are the same - final RemoteProcessGroupPortDTO requestRemoteProcessGroupPort = remoteProcessGroupPortEntity.getRemoteProcessGroupPort(); + final RemoteProcessGroupPortDTO requestRemoteProcessGroupPort = requestRemoteProcessGroupPortEntity.getRemoteProcessGroupPort(); if (!portId.equals(requestRemoteProcessGroupPort.getId())) { throw new IllegalArgumentException(String.format("The remote process group port id (%s) in the request body does not equal the " + "remote process group port id of the requested resource (%s).", requestRemoteProcessGroupPort.getId(), portId)); @@ -267,21 +282,24 @@ public class RemoteProcessGroupResource extends ApplicationResource { } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, remoteProcessGroupPortEntity); + return replicate(HttpMethod.PUT, requestRemoteProcessGroupPortEntity); } - final Revision revision = getRevision(remoteProcessGroupPortEntity, id); + final Revision requestRevision = getRevision(requestRemoteProcessGroupPortEntity, id); return withWriteLock( serviceFacade, - revision, + requestRemoteProcessGroupPortEntity, + requestRevision, lookup -> { final Authorizable remoteProcessGroupInputPort = lookup.getRemoteProcessGroupInputPort(id, portId); remoteProcessGroupInputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, () -> serviceFacade.verifyUpdateRemoteProcessGroupInputPort(id, requestRemoteProcessGroupPort), - () -> { + (revision, remoteProcessGroupPortEntity) -> { + final RemoteProcessGroupPortDTO remoteProcessGroupPort = remoteProcessGroupPortEntity.getRemoteProcessGroupPort(); + // update the specified remote process group - final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupInputPort(revision, id, requestRemoteProcessGroupPort); + final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupInputPort(revision, remoteProcessGroupPort.getId(), remoteProcessGroupPort); // get the updated revision final RevisionDTO updatedRevision = controllerResponse.getRevision(); @@ -302,7 +320,7 @@ public class RemoteProcessGroupResource extends ApplicationResource { * @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 + * @param requestRemoteProcessGroupPortEntity The remoteProcessGroupPortEntity * @return A remoteProcessGroupPortEntity */ @PUT @@ -328,20 +346,31 @@ public class RemoteProcessGroupResource extends ApplicationResource { ) public Response updateRemoteProcessGroupOutputPort( @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The remote process group id.", + required = true + ) @PathParam("id") String id, + @ApiParam( + value = "The remote process group port id.", + required = true + ) @PathParam("port-id") String portId, - RemoteProcessGroupPortEntity remoteProcessGroupPortEntity) { + @ApiParam( + value = "The remote process group port.", + required = true + ) RemoteProcessGroupPortEntity requestRemoteProcessGroupPortEntity) { - if (remoteProcessGroupPortEntity == null || remoteProcessGroupPortEntity.getRemoteProcessGroupPort() == null) { + if (requestRemoteProcessGroupPortEntity == null || requestRemoteProcessGroupPortEntity.getRemoteProcessGroupPort() == null) { throw new IllegalArgumentException("Remote process group port details must be specified."); } - if (remoteProcessGroupPortEntity.getRevision() == null) { + if (requestRemoteProcessGroupPortEntity.getRevision() == null) { throw new IllegalArgumentException("Revision must be specified."); } // ensure the ids are the same - final RemoteProcessGroupPortDTO requestRemoteProcessGroupPort = remoteProcessGroupPortEntity.getRemoteProcessGroupPort(); + final RemoteProcessGroupPortDTO requestRemoteProcessGroupPort = requestRemoteProcessGroupPortEntity.getRemoteProcessGroupPort(); if (!portId.equals(requestRemoteProcessGroupPort.getId())) { throw new IllegalArgumentException(String.format("The remote process group port id (%s) in the request body does not equal the " + "remote process group port id of the requested resource (%s).", requestRemoteProcessGroupPort.getId(), portId)); @@ -354,22 +383,25 @@ public class RemoteProcessGroupResource extends ApplicationResource { } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, remoteProcessGroupPortEntity); + return replicate(HttpMethod.PUT, requestRemoteProcessGroupPortEntity); } // handle expects request (usually from the cluster manager) - final Revision revision = getRevision(remoteProcessGroupPortEntity, id); + final Revision requestRevision = getRevision(requestRemoteProcessGroupPortEntity, id); return withWriteLock( serviceFacade, - revision, + requestRemoteProcessGroupPortEntity, + requestRevision, lookup -> { final Authorizable remoteProcessGroupOutputPort = lookup.getRemoteProcessGroupOutputPort(id, portId); remoteProcessGroupOutputPort.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, () -> serviceFacade.verifyUpdateRemoteProcessGroupOutputPort(id, requestRemoteProcessGroupPort), - () -> { + (revision, remoteProcessGroupPortEntity) -> { + final RemoteProcessGroupPortDTO remoteProcessGroupPort = remoteProcessGroupPortEntity.getRemoteProcessGroupPort(); + // update the specified remote process group - final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupOutputPort(revision, id, requestRemoteProcessGroupPort); + final RemoteProcessGroupPortEntity controllerResponse = serviceFacade.updateRemoteProcessGroupOutputPort(revision, remoteProcessGroupPort.getId(), remoteProcessGroupPort); // get the updated revision final RevisionDTO updatedRevision = controllerResponse.getRevision(); @@ -389,7 +421,7 @@ public class RemoteProcessGroupResource extends ApplicationResource { * * @param httpServletRequest request * @param id The id of the remote process group to update. - * @param remoteProcessGroupEntity A remoteProcessGroupEntity. + * @param requestRemoteProcessGroupEntity A remoteProcessGroupEntity. * @return A remoteProcessGroupEntity. */ @PUT @@ -414,59 +446,69 @@ public class RemoteProcessGroupResource extends ApplicationResource { ) public Response updateRemoteProcessGroup( @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The remote process group id.", + required = true + ) @PathParam("id") String id, - RemoteProcessGroupEntity remoteProcessGroupEntity) { + @ApiParam( + value = "The remote process group.", + required = true + ) final RemoteProcessGroupEntity requestRemoteProcessGroupEntity) { - if (remoteProcessGroupEntity == null || remoteProcessGroupEntity.getComponent() == null) { + if (requestRemoteProcessGroupEntity == null || requestRemoteProcessGroupEntity.getComponent() == null) { throw new IllegalArgumentException("Remote process group details must be specified."); } - if (remoteProcessGroupEntity.getRevision() == null) { + if (requestRemoteProcessGroupEntity.getRevision() == null) { throw new IllegalArgumentException("Revision must be specified."); } // ensure the ids are the same - final RemoteProcessGroupDTO requestRemoteProcessGroup = remoteProcessGroupEntity.getComponent(); + final RemoteProcessGroupDTO requestRemoteProcessGroup = requestRemoteProcessGroupEntity.getComponent(); if (!id.equals(requestRemoteProcessGroup.getId())) { throw new IllegalArgumentException(String.format("The remote process group id (%s) in the request body does not equal the " + "remote process group id of the requested resource (%s).", requestRemoteProcessGroup.getId(), id)); } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, remoteProcessGroupEntity); + return replicate(HttpMethod.PUT, requestRemoteProcessGroupEntity); } // handle expects request (usually from the cluster manager) - final Revision revision = getRevision(remoteProcessGroupEntity, id); + final Revision requestRevision = getRevision(requestRemoteProcessGroupEntity, id); return withWriteLock( serviceFacade, - revision, + requestRemoteProcessGroupEntity, + requestRevision, lookup -> { Authorizable authorizable = lookup.getRemoteProcessGroup(id); authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, () -> serviceFacade.verifyUpdateRemoteProcessGroup(requestRemoteProcessGroup), - () -> { + (revision, remoteProcessGroupEntity) -> { + final RemoteProcessGroupDTO remoteProcessGroup = remoteProcessGroupEntity.getComponent(); + // 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) { + if (remoteProcessGroup.getTargetUri() != null) { // parse the uri final URI uri; try { - uri = URI.create(requestRemoteProcessGroup.getTargetUri()); + uri = URI.create(remoteProcessGroup.getTargetUri()); } catch (final IllegalArgumentException e) { - throw new IllegalArgumentException("The specified remote process group URL is malformed: " + requestRemoteProcessGroup.getTargetUri()); + throw new IllegalArgumentException("The specified remote process group URL is malformed: " + remoteProcessGroup.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()); + throw new IllegalArgumentException("The specified remote process group URL is malformed: " + remoteProcessGroup.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()); + throw new IllegalArgumentException("The specified remote process group URL is invalid because it is not http or https: " + remoteProcessGroup.getTargetUri()); } // normalize the uri to the other controller @@ -476,11 +518,11 @@ public class RemoteProcessGroupResource extends ApplicationResource { } // update with the normalized uri - requestRemoteProcessGroup.setTargetUri(controllerUri); + remoteProcessGroup.setTargetUri(controllerUri); } // update the specified remote process group - final RemoteProcessGroupEntity entity = serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup); + final RemoteProcessGroupEntity entity = serviceFacade.updateRemoteProcessGroup(revision, remoteProcessGroup); populateRemainingRemoteProcessGroupEntityContent(entity); return clusterContext(generateOkResponse(entity)).build(); http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/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 0c2ad68..4d23804 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 @@ -333,27 +333,28 @@ public class ReportingTaskResource extends ApplicationResource { return replicate(HttpMethod.POST); } - final boolean isValidationPhase = isValidationPhase(httpServletRequest); - if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) { - // authorize access - serviceFacade.authorizeAccess(lookup -> { - final Authorizable processor = lookup.getReportingTask(id).getAuthorizable(); - processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }); - } - if (isValidationPhase) { - serviceFacade.verifyCanClearReportingTaskState(id); - return generateContinueResponse().build(); - } + final ReportingTaskEntity requestReportTaskEntity = new ReportingTaskEntity(); + requestReportTaskEntity.setId(id); - // get the component state - serviceFacade.clearReportingTaskState(id); + return withWriteLock( + serviceFacade, + requestReportTaskEntity, + lookup -> { + final Authorizable processor = lookup.getReportingTask(id).getAuthorizable(); + processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + () -> serviceFacade.verifyCanClearReportingTaskState(id), + (reportingTaskEntity) -> { + // get the component state + serviceFacade.clearReportingTaskState(reportingTaskEntity.getId()); - // generate the response entity - final ComponentStateEntity entity = new ComponentStateEntity(); + // generate the response entity + final ComponentStateEntity entity = new ComponentStateEntity(); - // generate the response - return clusterContext(generateOkResponse(entity)).build(); + // generate the response + return clusterContext(generateOkResponse(entity)).build(); + } + ); } /** @@ -361,7 +362,7 @@ public class ReportingTaskResource extends ApplicationResource { * * @param httpServletRequest request * @param id The id of the reporting task to update. - * @param reportingTaskEntity A reportingTaskEntity. + * @param requestReportingTaskEntity A reportingTaskEntity. * @return A reportingTaskEntity. */ @PUT @@ -395,32 +396,33 @@ public class ReportingTaskResource extends ApplicationResource { @ApiParam( value = "The reporting task configuration details.", required = true - ) final ReportingTaskEntity reportingTaskEntity) { + ) final ReportingTaskEntity requestReportingTaskEntity) { - if (reportingTaskEntity == null || reportingTaskEntity.getComponent() == null) { + if (requestReportingTaskEntity == null || requestReportingTaskEntity.getComponent() == null) { throw new IllegalArgumentException("Reporting task details must be specified."); } - if (reportingTaskEntity.getRevision() == null) { + if (requestReportingTaskEntity.getRevision() == null) { throw new IllegalArgumentException("Revision must be specified."); } // ensure the ids are the same - final ReportingTaskDTO requestReportingTaskDTO = reportingTaskEntity.getComponent(); + final ReportingTaskDTO requestReportingTaskDTO = requestReportingTaskEntity.getComponent(); if (!id.equals(requestReportingTaskDTO.getId())) { throw new IllegalArgumentException(String.format("The reporting task id (%s) in the request body does not equal the " + "reporting task id of the requested resource (%s).", requestReportingTaskDTO.getId(), id)); } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, reportingTaskEntity); + return replicate(HttpMethod.PUT, requestReportingTaskEntity); } // handle expects request (usually from the cluster manager) - final Revision revision = getRevision(reportingTaskEntity, id); + final Revision requestRevision = getRevision(requestReportingTaskEntity, id); return withWriteLock( serviceFacade, - revision, + requestReportingTaskEntity, + requestRevision, lookup -> { // authorize reporting task final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id); @@ -430,9 +432,11 @@ public class ReportingTaskResource extends ApplicationResource { AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTaskDTO.getProperties(), authorizable, authorizer, lookup); }, () -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO), - () -> { + (revision, reportingTaskEntity) -> { + final ReportingTaskDTO reportingTaskDTO = reportingTaskEntity.getComponent(); + // update the reporting task - final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, requestReportingTaskDTO); + final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, reportingTaskDTO); populateRemainingReportingTaskEntityContent(entity); return clusterContext(generateOkResponse(entity)).build(); @@ -494,19 +498,23 @@ public class ReportingTaskResource extends ApplicationResource { return replicate(HttpMethod.DELETE); } + final ReportingTaskEntity requestReportingTaskEntity = new ReportingTaskEntity(); + requestReportingTaskEntity.setId(id); + // handle expects request (usually from the cluster manager) - final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); + final Revision requestRevision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( serviceFacade, - revision, + requestReportingTaskEntity, + requestRevision, lookup -> { final Authorizable reportingTask = lookup.getReportingTask(id).getAuthorizable(); reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, () -> serviceFacade.verifyDeleteReportingTask(id), - () -> { + (revision, reportingTaskEntity) -> { // delete the specified reporting task - final ReportingTaskEntity entity = serviceFacade.deleteReportingTask(revision, id); + final ReportingTaskEntity entity = serviceFacade.deleteReportingTask(revision, reportingTaskEntity.getId()); return clusterContext(generateOkResponse(entity)).build(); } ); http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SnippetResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/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 5c34be1..050017b 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 @@ -30,6 +30,7 @@ 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.ComponentEntity; import org.apache.nifi.web.api.entity.SnippetEntity; import javax.servlet.http.HttpServletRequest; @@ -94,7 +95,7 @@ public class SnippetResource extends ApplicationResource { * Creates a snippet based off the specified configuration. * * @param httpServletRequest request - * @param snippetEntity A snippetEntity + * @param requestSnippetEntity A snippetEntity * @return A snippetEntity */ @POST @@ -122,53 +123,51 @@ public class SnippetResource extends ApplicationResource { value = "The snippet configuration details.", required = true ) - final SnippetEntity snippetEntity) { + final SnippetEntity requestSnippetEntity) { - if (snippetEntity == null || snippetEntity.getSnippet() == null) { + if (requestSnippetEntity == null || requestSnippetEntity.getSnippet() == null) { throw new IllegalArgumentException("Snippet details must be specified."); } - if (snippetEntity.getSnippet().getId() != null) { + if (requestSnippetEntity.getSnippet().getId() != null) { throw new IllegalArgumentException("Snippet ID cannot be specified."); } if (isReplicateRequest()) { - return replicate(HttpMethod.POST, snippetEntity); + return replicate(HttpMethod.POST, requestSnippetEntity); } - // handle expects request (usually from the cluster manager) - final boolean validationPhase = isValidationPhase(httpServletRequest); - if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { - // authorize access - serviceFacade.authorizeAccess(lookup -> { - final SnippetDTO snippet = snippetEntity.getSnippet(); + return withWriteLock( + serviceFacade, + requestSnippetEntity, + lookup -> { + final SnippetDTO snippet = requestSnippetEntity.getSnippet(); - // the snippet being created may be used later for batch component modifications, - // copy/paste, or template creation. during those subsequent actions, the snippet - // will again be authorized accordingly (read or write). at this point we do not - // know what the snippet will be used for so we need to attempt to authorize as - // read OR write + // the snippet being created may be used later for batch component modifications, + // copy/paste, or template creation. during those subsequent actions, the snippet + // will again be authorized accordingly (read or write). at this point we do not + // know what the snippet will be used for so we need to attempt to authorize as + // read OR write - try { - authorizeSnippet(snippet, authorizer, lookup, RequestAction.READ); - } catch (final AccessDeniedException e) { - authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); - } - }); - } - if (validationPhase) { - return generateContinueResponse().build(); - } - - // set the processor id as appropriate - snippetEntity.getSnippet().setId(generateUuid()); + try { + authorizeSnippet(snippet, authorizer, lookup, RequestAction.READ); + } catch (final AccessDeniedException e) { + authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); + } + }, + null, + (snippetEntity) -> { + // set the processor id as appropriate + snippetEntity.getSnippet().setId(generateUuid()); - // create the snippet - final SnippetEntity entity = serviceFacade.createSnippet(snippetEntity.getSnippet()); - populateRemainingSnippetEntityContent(entity); + // create the snippet + final SnippetEntity entity = serviceFacade.createSnippet(snippetEntity.getSnippet()); + populateRemainingSnippetEntityContent(entity); - // build the response - return clusterContext(generateCreatedResponse(URI.create(entity.getSnippet().getUri()), entity)).build(); + // build the response + return clusterContext(generateCreatedResponse(URI.create(entity.getSnippet().getUri()), entity)).build(); + } + ); } /** @@ -176,7 +175,7 @@ public class SnippetResource extends ApplicationResource { * * @param httpServletRequest request * @param snippetId The id of the snippet. - * @param snippetEntity A snippetEntity + * @param requestSnippetEntity A snippetEntity * @return A snippetEntity */ @PUT @@ -210,40 +209,41 @@ public class SnippetResource extends ApplicationResource { @ApiParam( value = "The snippet configuration details.", required = true - ) final SnippetEntity snippetEntity) { + ) final SnippetEntity requestSnippetEntity) { - if (snippetEntity == null || snippetEntity.getSnippet() == null) { + if (requestSnippetEntity == null || requestSnippetEntity.getSnippet() == null) { throw new IllegalArgumentException("Snippet details must be specified."); } // ensure the ids are the same - final SnippetDTO requestSnippetDTO = snippetEntity.getSnippet(); + final SnippetDTO requestSnippetDTO = requestSnippetEntity.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)); } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, snippetEntity); + return replicate(HttpMethod.PUT, requestSnippetEntity); } // get the revision from this snippet - final Set<Revision> revisions = serviceFacade.getRevisionsFromSnippet(snippetId); + final Set<Revision> requestRevisions = serviceFacade.getRevisionsFromSnippet(snippetId); return withWriteLock( - serviceFacade, - revisions, - lookup -> { - // ensure write access to the target process group - if (requestSnippetDTO.getParentGroupId() != null) { - lookup.getProcessGroup(requestSnippetDTO.getParentGroupId()).getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - } + serviceFacade, + requestSnippetEntity, + requestRevisions, + lookup -> { + // ensure write access to the target process group + if (requestSnippetDTO.getParentGroupId() != null) { + lookup.getProcessGroup(requestSnippetDTO.getParentGroupId()).getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + } - // ensure write permission to every component in the snippet - final Snippet snippet = lookup.getSnippet(snippetId); - authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE); + // 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())), - () -> { + () -> serviceFacade.verifyUpdateSnippet(requestSnippetDTO, requestRevisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())), + (revisions, snippetEntity) -> { // update the snippet final SnippetEntity entity = serviceFacade.updateSnippet(revisions, snippetEntity.getSnippet()); populateRemainingSnippetEntityContent(entity); @@ -291,20 +291,24 @@ public class SnippetResource extends ApplicationResource { return replicate(HttpMethod.DELETE); } + final ComponentEntity requestEntity = new ComponentEntity(); + requestEntity.setId(snippetId); + // get the revision from this snippet - final Set<Revision> revisions = serviceFacade.getRevisionsFromSnippet(snippetId); + final Set<Revision> requestRevisions = serviceFacade.getRevisionsFromSnippet(snippetId); return withWriteLock( serviceFacade, - revisions, + requestEntity, + requestRevisions, 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())), - () -> { + () -> serviceFacade.verifyDeleteSnippet(snippetId, requestRevisions.stream().map(rev -> rev.getComponentId()).collect(Collectors.toSet())), + (revisions, entity) -> { // delete the specified snippet - final SnippetEntity snippetEntity = serviceFacade.deleteSnippet(revisions, snippetId); + final SnippetEntity snippetEntity = serviceFacade.deleteSnippet(revisions, entity.getId()); return clusterContext(generateOkResponse(snippetEntity)).build(); } ); http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TemplateResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/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 abc8fe1..f210792 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 @@ -189,24 +189,27 @@ public class TemplateResource extends ApplicationResource { return replicate(HttpMethod.DELETE); } - // handle expects request (usually from the cluster manager) - final boolean validationPhase = isValidationPhase(httpServletRequest); - if (validationPhase) { - // authorize access - serviceFacade.authorizeAccess(lookup -> { - final Authorizable template = lookup.getTemplate(id); - template.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }); - return generateContinueResponse().build(); - } - - // delete the specified template - serviceFacade.deleteTemplate(id); - - // build the response entity - final TemplateEntity entity = new TemplateEntity(); - - return clusterContext(generateOkResponse(entity)).build(); + final TemplateEntity requestTemplateEntity = new TemplateEntity(); + requestTemplateEntity.setId(id); + + return withWriteLock( + serviceFacade, + requestTemplateEntity, + lookup -> { + final Authorizable template = lookup.getTemplate(id); + template.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + (templateEntity) -> { + // delete the specified template + serviceFacade.deleteTemplate(templateEntity.getId()); + + // build the response entity + final TemplateEntity entity = new TemplateEntity(); + + return clusterContext(generateOkResponse(entity)).build(); + } + ); } // setters http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/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 049b5d2..fae7345 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 @@ -115,7 +115,7 @@ public class TenantsResource extends ApplicationResource { * Creates a new user. * * @param httpServletRequest request - * @param userEntity An userEntity. + * @param requestUserEntity An userEntity. * @return An userEntity. */ @POST @@ -144,55 +144,53 @@ public class TenantsResource extends ApplicationResource { @ApiParam( value = "The user configuration details.", required = true - ) final UserEntity userEntity) { + ) final UserEntity requestUserEntity) { // ensure we're running with a configurable authorizer if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); } - if (userEntity == null || userEntity.getComponent() == null) { + if (requestUserEntity == null || requestUserEntity.getComponent() == null) { throw new IllegalArgumentException("User details must be specified."); } - if (userEntity.getRevision() == null || (userEntity.getRevision().getVersion() == null || userEntity.getRevision().getVersion() != 0)) { + if (requestUserEntity.getRevision() == null || (requestUserEntity.getRevision().getVersion() == null || requestUserEntity.getRevision().getVersion() != 0)) { throw new IllegalArgumentException("A revision of 0 must be specified when creating a new User."); } - if (userEntity.getComponent().getId() != null) { + if (requestUserEntity.getComponent().getId() != null) { throw new IllegalArgumentException("User ID cannot be specified."); } if (isReplicateRequest()) { - return replicate(HttpMethod.POST, userEntity); + return replicate(HttpMethod.POST, requestUserEntity); } - // handle expects request (usually from the cluster manager) - final boolean validationPhase = isValidationPhase(httpServletRequest); - if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { - // authorize access - serviceFacade.authorizeAccess(lookup -> { - final Authorizable tenants = lookup.getTenant(); - tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }); - } - if (validationPhase) { - return generateContinueResponse().build(); - } - - // set the user id as appropriate - userEntity.getComponent().setId(generateUuid()); - // get revision from the config - final RevisionDTO revisionDTO = userEntity.getRevision(); - Revision revision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), userEntity.getComponent().getId()); + final RevisionDTO revisionDTO = requestUserEntity.getRevision(); + Revision requestRevision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), requestUserEntity.getComponent().getId()); + return withWriteLock( + serviceFacade, + requestUserEntity, + requestRevision, + lookup -> { + final Authorizable tenants = lookup.getTenant(); + tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + (revision, userEntity) -> { + // set the user id as appropriate + userEntity.getComponent().setId(generateUuid()); - // create the user and generate the json - final UserEntity entity = serviceFacade.createUser(revision, userEntity.getComponent()); - populateRemainingUserEntityContent(entity); + // create the user and generate the json + final UserEntity entity = serviceFacade.createUser(revision, userEntity.getComponent()); + populateRemainingUserEntityContent(entity); - // build the response - return clusterContext(generateCreatedResponse(URI.create(entity.getUri()), entity)).build(); + // build the response + return clusterContext(generateCreatedResponse(URI.create(entity.getUri()), entity)).build(); + } + ); } /** @@ -311,7 +309,7 @@ public class TenantsResource extends ApplicationResource { * * @param httpServletRequest request * @param id The id of the user to update. - * @param userEntity An userEntity. + * @param requestUserEntity An userEntity. * @return An userEntity. */ @PUT @@ -345,45 +343,46 @@ public class TenantsResource extends ApplicationResource { @ApiParam( value = "The user configuration details.", required = true - ) final UserEntity userEntity) { + ) final UserEntity requestUserEntity) { // ensure we're running with a configurable authorizer if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); } - if (userEntity == null || userEntity.getComponent() == null) { + if (requestUserEntity == null || requestUserEntity.getComponent() == null) { throw new IllegalArgumentException("User details must be specified."); } - if (userEntity.getRevision() == null) { + if (requestUserEntity.getRevision() == null) { throw new IllegalArgumentException("Revision must be specified."); } // ensure the ids are the same - final UserDTO userDTO = userEntity.getComponent(); - if (!id.equals(userDTO.getId())) { + final UserDTO requestUserDTO = requestUserEntity.getComponent(); + if (!id.equals(requestUserDTO.getId())) { throw new IllegalArgumentException(String.format("The user id (%s) in the request body does not equal the " - + "user id of the requested resource (%s).", userDTO.getId(), id)); + + "user id of the requested resource (%s).", requestUserDTO.getId(), id)); } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, userEntity); + return replicate(HttpMethod.PUT, requestUserEntity); } // Extract the revision - final Revision revision = getRevision(userEntity, id); + final Revision requestRevision = getRevision(requestUserEntity, id); return withWriteLock( serviceFacade, - revision, + requestUserEntity, + requestRevision, lookup -> { final Authorizable tenants = lookup.getTenant(); tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, - () -> { + (revision, userEntity) -> { // update the user - final UserEntity entity = serviceFacade.updateUser(revision, userDTO); + final UserEntity entity = serviceFacade.updateUser(revision, userEntity.getComponent()); populateRemainingUserEntityContent(entity); return clusterContext(generateOkResponse(entity)).build(); @@ -451,19 +450,23 @@ public class TenantsResource extends ApplicationResource { return replicate(HttpMethod.DELETE); } + final UserEntity requestUserEntity = new UserEntity(); + requestUserEntity.setId(id); + // handle expects request (usually from the cluster manager) - final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); + final Revision requestRevision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( serviceFacade, - revision, + requestUserEntity, + requestRevision, lookup -> { final Authorizable tenants = lookup.getTenant(); tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, - () -> { + (revision, userEntity) -> { // delete the specified user - final UserEntity entity = serviceFacade.deleteUser(revision, id); + final UserEntity entity = serviceFacade.deleteUser(revision, userEntity.getId()); return clusterContext(generateOkResponse(entity)).build(); } ); @@ -497,7 +500,7 @@ public class TenantsResource extends ApplicationResource { * Creates a new user group. * * @param httpServletRequest request - * @param userGroupEntity An userGroupEntity. + * @param requestUserGroupEntity An userGroupEntity. * @return An userGroupEntity. */ @POST @@ -526,55 +529,53 @@ public class TenantsResource extends ApplicationResource { @ApiParam( value = "The user group configuration details.", required = true - ) final UserGroupEntity userGroupEntity) { + ) final UserGroupEntity requestUserGroupEntity) { // ensure we're running with a configurable authorizer if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); } - if (userGroupEntity == null || userGroupEntity.getComponent() == null) { + if (requestUserGroupEntity == null || requestUserGroupEntity.getComponent() == null) { throw new IllegalArgumentException("User group details must be specified."); } - if (userGroupEntity.getRevision() == null || (userGroupEntity.getRevision().getVersion() == null || userGroupEntity.getRevision().getVersion() != 0)) { + if (requestUserGroupEntity.getRevision() == null || (requestUserGroupEntity.getRevision().getVersion() == null || requestUserGroupEntity.getRevision().getVersion() != 0)) { throw new IllegalArgumentException("A revision of 0 must be specified when creating a new User Group."); } - if (userGroupEntity.getComponent().getId() != null) { + if (requestUserGroupEntity.getComponent().getId() != null) { throw new IllegalArgumentException("User group ID cannot be specified."); } if (isReplicateRequest()) { - return replicate(HttpMethod.POST, userGroupEntity); + return replicate(HttpMethod.POST, requestUserGroupEntity); } - // handle expects request (usually from the cluster manager) - final boolean validationPhase = isValidationPhase(httpServletRequest); - if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { - // authorize access - serviceFacade.authorizeAccess(lookup -> { - final Authorizable tenants = lookup.getTenant(); - tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); - }); - } - if (validationPhase) { - return generateContinueResponse().build(); - } - - // set the user group id as appropriate - userGroupEntity.getComponent().setId(generateUuid()); - // get revision from the config - final RevisionDTO revisionDTO = userGroupEntity.getRevision(); - Revision revision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), userGroupEntity.getComponent().getId()); + final RevisionDTO revisionDTO = requestUserGroupEntity.getRevision(); + Revision requestRevision = new Revision(revisionDTO.getVersion(), revisionDTO.getClientId(), requestUserGroupEntity.getComponent().getId()); + return withWriteLock( + serviceFacade, + requestUserGroupEntity, + requestRevision, + lookup -> { + final Authorizable tenants = lookup.getTenant(); + tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); + }, + null, + (revision, userGroupEntity) -> { + // set the user group id as appropriate + userGroupEntity.getComponent().setId(generateUuid()); - // create the user group and generate the json - final UserGroupEntity entity = serviceFacade.createUserGroup(revision, userGroupEntity.getComponent()); - populateRemainingUserGroupEntityContent(entity); + // create the user group and generate the json + final UserGroupEntity entity = serviceFacade.createUserGroup(revision, userGroupEntity.getComponent()); + populateRemainingUserGroupEntityContent(entity); - // build the response - return clusterContext(generateCreatedResponse(URI.create(entity.getUri()), entity)).build(); + // build the response + return clusterContext(generateCreatedResponse(URI.create(entity.getUri()), entity)).build(); + } + ); } /** @@ -692,7 +693,7 @@ public class TenantsResource extends ApplicationResource { * * @param httpServletRequest request * @param id The id of the user group to update. - * @param userGroupEntity An userGroupEntity. + * @param requestUserGroupEntity An userGroupEntity. * @return An userGroupEntity. */ @PUT @@ -726,45 +727,46 @@ public class TenantsResource extends ApplicationResource { @ApiParam( value = "The user group configuration details.", required = true - ) final UserGroupEntity userGroupEntity) { + ) final UserGroupEntity requestUserGroupEntity) { // ensure we're running with a configurable authorizer if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); } - if (userGroupEntity == null || userGroupEntity.getComponent() == null) { + if (requestUserGroupEntity == null || requestUserGroupEntity.getComponent() == null) { throw new IllegalArgumentException("User group details must be specified."); } - if (userGroupEntity.getRevision() == null) { + if (requestUserGroupEntity.getRevision() == null) { throw new IllegalArgumentException("Revision must be specified."); } // ensure the ids are the same - final UserGroupDTO userGroupDTO = userGroupEntity.getComponent(); - if (!id.equals(userGroupDTO.getId())) { + final UserGroupDTO requestUserGroupDTO = requestUserGroupEntity.getComponent(); + if (!id.equals(requestUserGroupDTO.getId())) { throw new IllegalArgumentException(String.format("The user group id (%s) in the request body does not equal the " - + "user group id of the requested resource (%s).", userGroupDTO.getId(), id)); + + "user group id of the requested resource (%s).", requestUserGroupDTO.getId(), id)); } if (isReplicateRequest()) { - return replicate(HttpMethod.PUT, userGroupEntity); + return replicate(HttpMethod.PUT, requestUserGroupEntity); } // Extract the revision - final Revision revision = getRevision(userGroupEntity, id); + final Revision requestRevision = getRevision(requestUserGroupEntity, id); return withWriteLock( serviceFacade, - revision, + requestUserGroupEntity, + requestRevision, lookup -> { final Authorizable tenants = lookup.getTenant(); tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, - () -> { + (revision, userGroupEntity) -> { // update the user group - final UserGroupEntity entity = serviceFacade.updateUserGroup(revision, userGroupDTO); + final UserGroupEntity entity = serviceFacade.updateUserGroup(revision, userGroupEntity.getComponent()); populateRemainingUserGroupEntityContent(entity); return clusterContext(generateOkResponse(entity)).build(); @@ -832,19 +834,23 @@ public class TenantsResource extends ApplicationResource { return replicate(HttpMethod.DELETE); } + final UserGroupEntity requestUserGroupEntity = new UserGroupEntity(); + requestUserGroupEntity.setId(id); + // handle expects request (usually from the cluster manager) - final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); + final Revision requestRevision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); return withWriteLock( serviceFacade, - revision, + requestUserGroupEntity, + requestRevision, lookup -> { final Authorizable tenants = lookup.getTenant(); tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); }, null, - () -> { + (revision, userGroupEntity) -> { // delete the specified user group - final UserGroupEntity entity = serviceFacade.deleteUserGroup(revision, id); + final UserGroupEntity entity = serviceFacade.deleteUserGroup(revision, userGroupEntity.getId()); return clusterContext(generateOkResponse(entity)).build(); } ); http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpService.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpService.java index cd5a90c..bcd26a4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpService.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/otp/OtpService.java @@ -20,6 +20,7 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import org.apache.commons.codec.binary.Base64; import org.apache.nifi.web.security.token.OtpAuthenticationToken; +import org.apache.nifi.web.security.util.CacheKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,7 +28,6 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.concurrent.ConcurrentMap; @@ -129,7 +129,7 @@ public class OtpService { cache.putIfAbsent(cacheKey, authenticationToken.getName()); // return the token - return cacheKey.getToken(); + return cacheKey.getKey(); } /** @@ -178,42 +178,4 @@ public class OtpService { throw new IllegalStateException("Unable to generate single use token."); } } - - /** - * Key for the cache. Necessary to override the default String.equals() to utilize MessageDigest.isEquals() to prevent timing attacks. - */ - private static class CacheKey { - final String token; - - public CacheKey(String token) { - this.token = token; - } - - public String getToken() { - return token; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final CacheKey otherCacheKey = (CacheKey) o; - return MessageDigest.isEqual(token.getBytes(StandardCharsets.UTF_8), otherCacheKey.token.getBytes(StandardCharsets.UTF_8)); - } - - @Override - public int hashCode() { - return token.hashCode(); - } - - @Override - public String toString() { - return "CacheKey{token ending in '..." + token.substring(token.length() - 6) + "'}"; - } - } } http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/util/CacheKey.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/util/CacheKey.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/util/CacheKey.java new file mode 100644 index 0000000..6247993 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/util/CacheKey.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.web.security.util; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +/** + * An authentication token that represents an Authenticated and Authorized user of the NiFi Apis. The authorities are based off the specified UserDetails. + */ +/** + * Key for the cache. Necessary to override the default String.equals() to utilize MessageDigest.isEquals() to prevent timing attacks. + */ +public class CacheKey { + final String key; + + public CacheKey(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final CacheKey otherCacheKey = (CacheKey) o; + return MessageDigest.isEqual(key.getBytes(StandardCharsets.UTF_8), otherCacheKey.key.getBytes(StandardCharsets.UTF_8)); + } + + @Override + public int hashCode() { + return key.hashCode(); + } + + @Override + public String toString() { + return "CacheKey{token ending in '..." + key.substring(key.length() - 6) + "'}"; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/c2bfc4ef/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css index 24a370b..c742c2f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css @@ -190,7 +190,7 @@ md-toolbar.md-small .md-toolbar-tools { font-style: normal; font-weight: normal; font-size: 12px; - max-width: 130px; + max-width: 250px; text-overflow: ellipsis; line-height: normal; overflow: hidden;
