use of org.apache.nifi.authorization.AuthorizeAccess in project nifi by apache.
the class ProcessGroupResource method submitUpdateVariableRegistryRequest.
/**
* Updates the variable registry for the specified process group.
*
* @param httpServletRequest request
* @param groupId The id of the process group.
* @param requestVariableRegistryEntity the Variable Registry Entity
* @return A Variable Registry Entry.
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/variable-registry/update-requests")
@ApiOperation(value = "Submits a request to update a process group's variable registry", response = VariableRegistryUpdateRequestEntity.class, notes = NON_GUARANTEED_ENDPOINT, authorizations = { @Authorization(value = "Write - /process-groups/{uuid}") })
@ApiResponses(value = { @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 404, message = "The specified resource could not be found."), @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") })
public Response submitUpdateVariableRegistryRequest(@Context final HttpServletRequest httpServletRequest, @ApiParam(value = "The process group id.", required = true) @PathParam("id") final String groupId, @ApiParam(value = "The variable registry configuration details.", required = true) final VariableRegistryEntity requestVariableRegistryEntity) {
if (requestVariableRegistryEntity == null || requestVariableRegistryEntity.getVariableRegistry() == null) {
throw new IllegalArgumentException("Variable Registry details must be specified.");
}
if (requestVariableRegistryEntity.getProcessGroupRevision() == null) {
throw new IllegalArgumentException("Process Group Revision must be specified.");
}
// In order to update variables in a variable registry, we have to perform the following steps:
// 1. Determine Affected Components (this includes any Processors and Controller Services and any components that reference an affected Controller Service).
// 1a. Determine ID's of components
// 1b. Determine Revision's of associated components
// 2. Stop All Active Affected Processors
// 3. Disable All Active Affected Controller Services
// 4. Update the Variables
// 5. Re-Enable all previously Active Affected Controller Services (services only, not dependent components)
// 6. Re-Enable all previously Active Processors that Depended on the Controller Services
// Determine the affected components (and their associated revisions)
final VariableRegistryEntity computedEntity = serviceFacade.populateAffectedComponents(requestVariableRegistryEntity.getVariableRegistry());
final VariableRegistryDTO computedRegistryDto = computedEntity.getVariableRegistry();
if (computedRegistryDto == null) {
throw new ResourceNotFoundException(String.format("Unable to locate group with id '%s'.", groupId));
}
final Set<AffectedComponentEntity> allAffectedComponents = serviceFacade.getComponentsAffectedByVariableRegistryUpdate(requestVariableRegistryEntity.getVariableRegistry());
final Set<AffectedComponentDTO> activeAffectedComponents = serviceFacade.getActiveComponentsAffectedByVariableRegistryUpdate(requestVariableRegistryEntity.getVariableRegistry());
final Map<String, List<AffectedComponentDTO>> activeAffectedComponentsByType = activeAffectedComponents.stream().collect(Collectors.groupingBy(comp -> comp.getReferenceType()));
final List<AffectedComponentDTO> activeAffectedProcessors = activeAffectedComponentsByType.get(AffectedComponentDTO.COMPONENT_TYPE_PROCESSOR);
final List<AffectedComponentDTO> activeAffectedServices = activeAffectedComponentsByType.get(AffectedComponentDTO.COMPONENT_TYPE_CONTROLLER_SERVICE);
final NiFiUser user = NiFiUserUtils.getNiFiUser();
// define access authorize for execution below
final AuthorizeAccess authorizeAccess = lookup -> {
final Authorizable groupAuthorizable = lookup.getProcessGroup(groupId).getAuthorizable();
groupAuthorizable.authorize(authorizer, RequestAction.WRITE, user);
// (because this action requires stopping the component).
if (activeAffectedProcessors != null) {
for (final AffectedComponentDTO activeAffectedComponent : activeAffectedProcessors) {
final Authorizable authorizable = lookup.getProcessor(activeAffectedComponent.getId()).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.READ, user);
authorizable.authorize(authorizer, RequestAction.WRITE, user);
}
}
if (activeAffectedServices != null) {
for (final AffectedComponentDTO activeAffectedComponent : activeAffectedServices) {
final Authorizable authorizable = lookup.getControllerService(activeAffectedComponent.getId()).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.READ, user);
authorizable.authorize(authorizer, RequestAction.WRITE, user);
}
}
};
if (isReplicateRequest()) {
// authorize access
serviceFacade.authorizeAccess(authorizeAccess);
// update the variable registry
final VariableRegistryUpdateRequest updateRequest = createVariableRegistryUpdateRequest(groupId, allAffectedComponents, user);
updateRequest.getIdentifyRelevantComponentsStep().setComplete(true);
final URI originalUri = getAbsolutePath();
// Submit the task to be run in the background
final Runnable taskWrapper = () -> {
try {
// set the user authentication token
final Authentication authentication = new NiFiAuthenticationToken(new NiFiUserDetails(user));
SecurityContextHolder.getContext().setAuthentication(authentication);
updateVariableRegistryReplicated(groupId, originalUri, activeAffectedProcessors, activeAffectedServices, updateRequest, requestVariableRegistryEntity);
// ensure the request is marked complete
updateRequest.setComplete(true);
} catch (final Exception e) {
logger.error("Failed to update variable registry", e);
updateRequest.setComplete(true);
updateRequest.setFailureReason("An unexpected error has occurred: " + e);
} finally {
// clear the authentication token
SecurityContextHolder.getContext().setAuthentication(null);
}
};
variableRegistryThreadPool.submit(taskWrapper);
final VariableRegistryUpdateRequestEntity responseEntity = new VariableRegistryUpdateRequestEntity();
responseEntity.setRequest(dtoFactory.createVariableRegistryUpdateRequestDto(updateRequest));
responseEntity.setProcessGroupRevision(updateRequest.getProcessGroupRevision());
responseEntity.getRequest().setUri(generateResourceUri("process-groups", groupId, "variable-registry", "update-requests", updateRequest.getRequestId()));
final URI location = URI.create(responseEntity.getRequest().getUri());
return Response.status(Status.ACCEPTED).location(location).entity(responseEntity).build();
}
final UpdateVariableRegistryRequestWrapper requestWrapper = new UpdateVariableRegistryRequestWrapper(allAffectedComponents, activeAffectedProcessors, activeAffectedServices, requestVariableRegistryEntity);
final Revision requestRevision = getRevision(requestVariableRegistryEntity.getProcessGroupRevision(), groupId);
return withWriteLock(serviceFacade, requestWrapper, requestRevision, authorizeAccess, null, (revision, wrapper) -> updateVariableRegistryLocal(groupId, wrapper.getAllAffectedComponents(), wrapper.getActiveAffectedProcessors(), wrapper.getActiveAffectedServices(), user, revision, wrapper.getVariableRegistryEntity()));
}
Aggregations