Search in sources :

Example 1 with UpdateControllerServiceReferenceRequestEntity

use of org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity in project kylo by Teradata.

the class AbstractNiFiControllerServicesRestClient method updateServiceAndReferencingComponents.

/**
 * Updates a controller service
 * This will first disable the service, stop all referencing components, enable the service, reset the state of the components back to their prior state
 *
 * @param controllerService the service to update with the updated properties
 * @return the updates service
 */
@Override
public ControllerServiceDTO updateServiceAndReferencingComponents(ControllerServiceDTO controllerService) {
    String id = controllerService.getId();
    // Get all references to this controller service.  this will include processors, other controller services, and reporting tasks
    Optional<ControllerServiceReferencingComponentsEntity> references = getReferences(id);
    // state of the processors prior to update
    Map<String, String> previousProcessorState = null;
    // revisions for the processor references
    Map<String, RevisionDTO> processorRevisions = null;
    // revisions for the controller service references
    Map<String, RevisionDTO> controllerServiceRevisions = null;
    // a map of component id to reference entity.  this will include all referencing processors, controller services, and reporting tasks
    Map<String, ControllerServiceReferencingComponentEntity> referencingComponentEntityMap = null;
    // Stop all processor references and also disable any other controller service references
    if (references.isPresent()) {
        // build the reference state and revision maps prior to making this update
        referencingComponentEntityMap = getReferencingComponents(references.get().getControllerServiceReferencingComponents());
        previousProcessorState = referencingComponentEntityMap.values().stream().filter(e -> e.getComponent().getReferenceType().equalsIgnoreCase("PROCESSOR")).map(c -> c.getComponent()).collect(Collectors.toMap(ControllerServiceReferencingComponentDTO::getId, ControllerServiceReferencingComponentDTO::getState));
        processorRevisions = referencingComponentEntityMap.values().stream().filter(e -> e.getComponent().getReferenceType().equalsIgnoreCase("PROCESSOR")).collect(Collectors.toMap(ControllerServiceReferencingComponentEntity::getId, ControllerServiceReferencingComponentEntity::getRevision));
        controllerServiceRevisions = referencingComponentEntityMap.values().stream().filter(e -> e.getComponent().getReferenceType().equalsIgnoreCase("ControllerService")).collect(Collectors.toMap(ControllerServiceReferencingComponentEntity::getId, ControllerServiceReferencingComponentEntity::getRevision));
        // Stop the referencing processors and ensure they are in the stopped state
        if (!processorRevisions.isEmpty()) {
            String state = NifiProcessUtil.PROCESS_STATE.STOPPED.name();
            log.info("Stopping all component references to controller service {} ", controllerService.getName());
            UpdateControllerServiceReferenceRequestEntity stopComponentsRequest = new UpdateControllerServiceReferenceRequestEntity();
            stopComponentsRequest.setState(state);
            stopComponentsRequest.setId(controllerService.getId());
            stopComponentsRequest.setReferencingComponentRevisions(processorRevisions);
            updateReferences(id, stopComponentsRequest);
            boolean updatedReferences = ensureComponentsAreOfState(id, "Processor", state, 5, 500, TimeUnit.MILLISECONDS);
            if (!updatedReferences) {
                // error unable to change the state of the references. ... error
                throw new NifiClientRuntimeException("Unable to stop processor references to this controller service " + controllerService.getName() + " before making the update");
            }
        }
        // disable any controller service references
        if (!controllerServiceRevisions.isEmpty()) {
            UpdateControllerServiceReferenceRequestEntity stopComponentsRequest = new UpdateControllerServiceReferenceRequestEntity();
            stopComponentsRequest.setState("DISABLED");
            stopComponentsRequest.setId(controllerService.getId());
            stopComponentsRequest.setReferencingComponentRevisions(controllerServiceRevisions);
            updateReferences(id, stopComponentsRequest);
            boolean updatedReferences = ensureComponentsAreOfState(id, "ControllerService", "DISABLED", 5, 500, TimeUnit.MILLISECONDS);
            if (!updatedReferences) {
                // error unable to change the state of the references. ... error
                throw new NifiClientRuntimeException("Unable to disable other controller service references to this controller service " + controllerService.getName() + " before making the update");
            }
        }
    }
    // mark this controller service as disabled
    log.info("Disabling the controller service  {} ", controllerService.getName());
    // update the service and mark it disabled.  this will throw a RuntimeException if it is not successful
    ControllerServiceDTO updatedService = updateStateByIdWithRetries(controllerService.getId(), "DISABLED", 5, 500, TimeUnit.MILLISECONDS);
    // Perform the update to this controller service
    log.info("Updating the controller service  {} ", controllerService.getName());
    updatedService = update(controllerService);
    // Enable the service
    updateStateById(controllerService.getId(), NiFiControllerServicesRestClient.State.ENABLED);
    // Enable any controller service references
    if (!controllerServiceRevisions.isEmpty()) {
        log.info("Enabling other controller services referencing this controller service  {} ", controllerService.getName());
        UpdateControllerServiceReferenceRequestEntity enableReferenceServicesRequest = new UpdateControllerServiceReferenceRequestEntity();
        enableReferenceServicesRequest.setId(controllerService.getId());
        enableReferenceServicesRequest.setState(NiFiControllerServicesRestClient.State.ENABLED.name());
        enableReferenceServicesRequest.setReferencingComponentRevisions(controllerServiceRevisions);
        updateReferences(id, enableReferenceServicesRequest);
        boolean updatedReferences = ensureComponentsAreOfState(id, "ControllerService", NiFiControllerServicesRestClient.State.ENABLED.name(), 5, 500, TimeUnit.MILLISECONDS);
        if (!updatedReferences) {
            // error unable to change the state of the references. ... error
            throw new NifiClientRuntimeException("The controller service " + controllerService.getName() + " was updated, but it was unable to enable other controller service references to this controller service.  Please visit NiFi to reconcile and fix any controller service issues. " + controllerService.getName());
        }
    }
    if (references.isPresent() && previousProcessorState != null) {
        // reset the processor state
        Map<String, RevisionDTO> finalComponentRevisions = processorRevisions;
        // if all referencing processors of of the same state we can call the quick rest endpoint to update all of them
        Set<String> distinctStates = previousProcessorState.values().stream().collect(Collectors.toSet());
        if (distinctStates.size() > 0) {
            if (distinctStates.size() == 1) {
                String state = new ArrayList<>(distinctStates).get(0);
                if (!NifiProcessUtil.PROCESS_STATE.STOPPED.name().equals(state)) {
                    UpdateControllerServiceReferenceRequestEntity startComponentsRequest = new UpdateControllerServiceReferenceRequestEntity();
                    startComponentsRequest.setState(state);
                    startComponentsRequest.setReferencingComponentRevisions(finalComponentRevisions);
                    startComponentsRequest.setId(controllerService.getId());
                    updateReferences(id, startComponentsRequest);
                    log.info("Updating all component references to be {} for controller service  {} ", state, controllerService.getName());
                    boolean updatedReferences = ensureComponentsAreOfState(id, "Processor", state, 5, 500, TimeUnit.MILLISECONDS);
                    if (!updatedReferences) {
                        // error unable to change the state of the references. ... error
                        throw new NifiClientRuntimeException("The controller service {} was updated, but it was unable to update the state of the processors as " + state + ".  Please visit NiFi to reconcile and fix any controller service issues. " + controllerService.getName());
                    }
                    log.info("Successfully updated controller service {}", controllerService.getName());
                }
            } else {
                log.info("The controller service component references ({} total) had mixed states prior to updating {}.  Going through each processor/component and setting its state back to what it was prior to the update.", previousProcessorState.size(), distinctStates);
                // update references back to previous states
                List<ProcessorEntity> updatedProcessors = references.get().getControllerServiceReferencingComponents().stream().filter(c -> c.getComponent().getReferenceType().equalsIgnoreCase("PROCESSOR")).filter(c -> !c.getComponent().getState().equals(NifiProcessUtil.PROCESS_STATE.STOPPED.name())).map(referencingComponentEntity -> referencingComponentEntity.getComponent()).map(c -> {
                    ProcessorEntity entity = new ProcessorEntity();
                    entity.setRevision(finalComponentRevisions.get(c.getId()));
                    entity.setId(c.getId());
                    ProcessorDTO processorDTO = new ProcessorDTO();
                    processorDTO.setId(c.getId());
                    processorDTO.setState(c.getState());
                    entity.setComponent(processorDTO);
                    return entity;
                }).collect(Collectors.toList());
                updatedProcessors.stream().forEach(p -> getClient().processors().update(p));
                log.info("Successfully updated controller service {} and updated {} components back to their prior state ", controllerService.getName(), previousProcessorState.size());
            }
        }
    }
    return updatedService;
}
Also used : ControllerServiceReferencingComponentsEntity(org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) LoggerFactory(org.slf4j.LoggerFactory) NifiProcessUtil(com.thinkbiganalytics.nifi.rest.support.NifiProcessUtil) HashMap(java.util.HashMap) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) ClientErrorException(javax.ws.rs.ClientErrorException) ProcessorEntity(org.apache.nifi.web.api.entity.ProcessorEntity) ArrayList(java.util.ArrayList) Future(java.util.concurrent.Future) UpdateControllerServiceReferenceRequestEntity(org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity) ControllerServiceReferencingComponentEntity(org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity) Map(java.util.Map) Nonnull(javax.annotation.Nonnull) NifiConstants(com.thinkbiganalytics.nifi.rest.support.NifiConstants) ExecutorService(java.util.concurrent.ExecutorService) BulletinDTO(org.apache.nifi.web.api.dto.BulletinDTO) ControllerServiceReferencingComponentsEntity(org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity) Uninterruptibles(com.google.common.util.concurrent.Uninterruptibles) Logger(org.slf4j.Logger) ControllerServiceDTO(org.apache.nifi.web.api.dto.ControllerServiceDTO) ControllerServiceReferencingComponentDTO(org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO) Collection(java.util.Collection) Set(java.util.Set) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ProcessorDTO(org.apache.nifi.web.api.dto.ProcessorDTO) Optional(java.util.Optional) ControllerServiceDTO(org.apache.nifi.web.api.dto.ControllerServiceDTO) ControllerServiceReferencingComponentEntity(org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity) ProcessorEntity(org.apache.nifi.web.api.entity.ProcessorEntity) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) ControllerServiceReferencingComponentDTO(org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO) ProcessorDTO(org.apache.nifi.web.api.dto.ProcessorDTO) UpdateControllerServiceReferenceRequestEntity(org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity)

Example 2 with UpdateControllerServiceReferenceRequestEntity

use of org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity in project nifi by apache.

the class ControllerServiceResource method updateControllerServiceReferences.

/**
 * Updates the references of the specified controller service.
 *
 * @param httpServletRequest     request
 * @param requestUpdateReferenceRequest The update request
 * @return A controllerServiceReferencingComponentsEntity.
 */
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/references")
@ApiOperation(value = "Updates a controller services references", response = ControllerServiceReferencingComponentsEntity.class, authorizations = { @Authorization(value = "Write - /{component-type}/{uuid} - For each referencing component specified") })
@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 updateControllerServiceReferences(@Context final HttpServletRequest httpServletRequest, @ApiParam(value = "The controller service id.", required = true) @PathParam("id") final String id, @ApiParam(value = "The controller service request update request.", required = true) final UpdateControllerServiceReferenceRequestEntity requestUpdateReferenceRequest) {
    if (requestUpdateReferenceRequest.getId() == null) {
        throw new IllegalArgumentException("The controller service identifier must be specified.");
    }
    if (requestUpdateReferenceRequest.getReferencingComponentRevisions() == null) {
        throw new IllegalArgumentException("The controller service referencing components revisions must be specified.");
    }
    // parse the state to determine the desired action
    // need to consider controller service state first as it shares a state with
    // scheduled state (disabled) which is applicable for referencing services
    // but not referencing schedulable components
    ControllerServiceState requestControllerServiceState = null;
    try {
        requestControllerServiceState = ControllerServiceState.valueOf(requestUpdateReferenceRequest.getState());
    } catch (final IllegalArgumentException iae) {
    // ignore
    }
    ScheduledState requestScheduledState = null;
    try {
        requestScheduledState = ScheduledState.valueOf(requestUpdateReferenceRequest.getState());
    } catch (final IllegalArgumentException iae) {
    // ignore
    }
    // ensure an action has been specified
    if (requestScheduledState == null && requestControllerServiceState == null) {
        throw new IllegalArgumentException("Must specify the updated state. To update referencing Processors " + "and Reporting Tasks the state should be RUNNING or STOPPED. To update the referencing Controller Services the " + "state should be ENABLED or DISABLED.");
    }
    // ensure the controller service state is not ENABLING or DISABLING
    if (requestControllerServiceState != null && (ControllerServiceState.ENABLING.equals(requestControllerServiceState) || ControllerServiceState.DISABLING.equals(requestControllerServiceState))) {
        throw new IllegalArgumentException("Cannot set the referencing services to ENABLING or DISABLING");
    }
    if (isReplicateRequest()) {
        return replicate(HttpMethod.PUT, requestUpdateReferenceRequest);
    }
    // convert the referencing revisions
    final Map<String, Revision> requestReferencingRevisions = requestUpdateReferenceRequest.getReferencingComponentRevisions().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> {
        final RevisionDTO rev = e.getValue();
        return new Revision(rev.getVersion(), rev.getClientId(), e.getKey());
    }));
    final Set<Revision> requestRevisions = new HashSet<>(requestReferencingRevisions.values());
    final ScheduledState verifyScheduledState = requestScheduledState;
    final ControllerServiceState verifyControllerServiceState = requestControllerServiceState;
    return withWriteLock(serviceFacade, requestUpdateReferenceRequest, requestRevisions, lookup -> {
        requestReferencingRevisions.entrySet().stream().forEach(e -> {
            final Authorizable controllerService = lookup.getControllerServiceReferencingComponent(id, e.getKey());
            controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
        });
    }, () -> serviceFacade.verifyUpdateControllerServiceReferencingComponents(requestUpdateReferenceRequest.getId(), verifyScheduledState, verifyControllerServiceState), (revisions, updateReferenceRequest) -> {
        ScheduledState scheduledState = null;
        try {
            scheduledState = ScheduledState.valueOf(updateReferenceRequest.getState());
        } catch (final IllegalArgumentException e) {
        // ignore
        }
        ControllerServiceState controllerServiceState = null;
        try {
            controllerServiceState = ControllerServiceState.valueOf(updateReferenceRequest.getState());
        } catch (final IllegalArgumentException iae) {
        // ignore
        }
        final Map<String, Revision> 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());
        }));
        // update the controller service references
        final ControllerServiceReferencingComponentsEntity entity = serviceFacade.updateControllerServiceReferencingComponents(referencingRevisions, updateReferenceRequest.getId(), scheduledState, controllerServiceState);
        return generateOkResponse(entity).build();
    });
}
Also used : Produces(javax.ws.rs.Produces) LoggerFactory(org.slf4j.LoggerFactory) Path(javax.ws.rs.Path) ApiParam(io.swagger.annotations.ApiParam) BundleDTO(org.apache.nifi.web.api.dto.BundleDTO) ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) StringUtils(org.apache.commons.lang3.StringUtils) ClientIdParameter(org.apache.nifi.web.api.request.ClientIdParameter) ApiOperation(io.swagger.annotations.ApiOperation) MediaType(javax.ws.rs.core.MediaType) AuthorizeControllerServiceReference(org.apache.nifi.authorization.AuthorizeControllerServiceReference) PropertyDescriptorDTO(org.apache.nifi.web.api.dto.PropertyDescriptorDTO) QueryParam(javax.ws.rs.QueryParam) Consumes(javax.ws.rs.Consumes) Map(java.util.Map) UiExtension(org.apache.nifi.ui.extension.UiExtension) DefaultValue(javax.ws.rs.DefaultValue) UiExtensionType(org.apache.nifi.web.UiExtensionType) DELETE(javax.ws.rs.DELETE) ControllerServiceReferencingComponentsEntity(org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity) Context(javax.ws.rs.core.Context) Authorizable(org.apache.nifi.authorization.resource.Authorizable) ControllerServiceDTO(org.apache.nifi.web.api.dto.ControllerServiceDTO) Set(java.util.Set) LongParameter(org.apache.nifi.web.api.request.LongParameter) Collectors(java.util.stream.Collectors) List(java.util.List) Response(javax.ws.rs.core.Response) ScheduledState(org.apache.nifi.controller.ScheduledState) UiExtensionMapping(org.apache.nifi.ui.extension.UiExtensionMapping) ControllerServiceState(org.apache.nifi.controller.service.ControllerServiceState) PathParam(javax.ws.rs.PathParam) Revision(org.apache.nifi.web.Revision) GET(javax.ws.rs.GET) ControllerServiceEntity(org.apache.nifi.web.api.entity.ControllerServiceEntity) PropertyDescriptorEntity(org.apache.nifi.web.api.entity.PropertyDescriptorEntity) ApiResponses(io.swagger.annotations.ApiResponses) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) HttpMethod(javax.ws.rs.HttpMethod) HashSet(java.util.HashSet) HttpServletRequest(javax.servlet.http.HttpServletRequest) UpdateControllerServiceReferenceRequestEntity(org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity) Api(io.swagger.annotations.Api) NiFiServiceFacade(org.apache.nifi.web.NiFiServiceFacade) Logger(org.slf4j.Logger) POST(javax.ws.rs.POST) RequestAction(org.apache.nifi.authorization.RequestAction) Authorizer(org.apache.nifi.authorization.Authorizer) ApiResponse(io.swagger.annotations.ApiResponse) NiFiUserUtils(org.apache.nifi.authorization.user.NiFiUserUtils) ComponentStateDTO(org.apache.nifi.web.api.dto.ComponentStateDTO) ComponentStateEntity(org.apache.nifi.web.api.entity.ComponentStateEntity) ServletContext(javax.servlet.ServletContext) PUT(javax.ws.rs.PUT) Authorization(io.swagger.annotations.Authorization) ControllerServiceReferencingComponentsEntity(org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity) ControllerServiceState(org.apache.nifi.controller.service.ControllerServiceState) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) Revision(org.apache.nifi.web.Revision) ScheduledState(org.apache.nifi.controller.ScheduledState) ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) Authorizable(org.apache.nifi.authorization.resource.Authorizable) Map(java.util.Map) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) PUT(javax.ws.rs.PUT) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

List (java.util.List)2 Map (java.util.Map)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2 ControllerServiceDTO (org.apache.nifi.web.api.dto.ControllerServiceDTO)2 RevisionDTO (org.apache.nifi.web.api.dto.RevisionDTO)2 ControllerServiceReferencingComponentsEntity (org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity)2 UpdateControllerServiceReferenceRequestEntity (org.apache.nifi.web.api.entity.UpdateControllerServiceReferenceRequestEntity)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)1 Uninterruptibles (com.google.common.util.concurrent.Uninterruptibles)1 NifiConstants (com.thinkbiganalytics.nifi.rest.support.NifiConstants)1 NifiProcessUtil (com.thinkbiganalytics.nifi.rest.support.NifiProcessUtil)1 Api (io.swagger.annotations.Api)1 ApiOperation (io.swagger.annotations.ApiOperation)1 ApiParam (io.swagger.annotations.ApiParam)1 ApiResponse (io.swagger.annotations.ApiResponse)1 ApiResponses (io.swagger.annotations.ApiResponses)1 Authorization (io.swagger.annotations.Authorization)1