Search in sources :

Example 16 with ConfigurableComponent

use of org.apache.nifi.components.ConfigurableComponent in project nifi by apache.

the class FingerprintFactory method addReportingTaskFingerprint.

private void addReportingTaskFingerprint(final StringBuilder builder, final ReportingTaskDTO dto) {
    builder.append(dto.getId());
    builder.append(dto.getType());
    builder.append(dto.getName());
    addBundleFingerprint(builder, dto.getBundle());
    builder.append(dto.getComments());
    builder.append(dto.getSchedulingPeriod());
    builder.append(dto.getSchedulingStrategy());
    builder.append(dto.getAnnotationData());
    // get the temp instance of the ReportingTask so that we know the default property values
    final BundleCoordinate coordinate = getCoordinate(dto.getType(), dto.getBundle());
    final ConfigurableComponent configurableComponent = ExtensionManager.getTempComponent(dto.getType(), coordinate);
    if (configurableComponent == null) {
        logger.warn("Unable to get ReportingTask of type {}; its default properties will be fingerprinted instead of being ignored.", dto.getType());
    }
    addPropertiesFingerprint(builder, configurableComponent, dto.getProperties());
}
Also used : ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 17 with ConfigurableComponent

use of org.apache.nifi.components.ConfigurableComponent in project nifi by apache.

the class ScriptedLookupService method getSupportedPropertyDescriptors.

/**
 * Returns a list of property descriptors supported by this processor. The
 * list always includes properties such as script engine name, script file
 * name, script body name, script arguments, and an external module path. If
 * the scripted processor also defines supported properties, those are added
 * to the list as well.
 *
 * @return a List of PropertyDescriptor objects supported by this processor
 */
@Override
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
    synchronized (scriptingComponentHelper.isInitialized) {
        if (!scriptingComponentHelper.isInitialized.get()) {
            scriptingComponentHelper.createResources();
        }
    }
    List<PropertyDescriptor> supportedPropertyDescriptors = new ArrayList<>();
    supportedPropertyDescriptors.addAll(scriptingComponentHelper.getDescriptors());
    final ConfigurableComponent instance = lookupService.get();
    if (instance != null) {
        try {
            final List<PropertyDescriptor> instanceDescriptors = instance.getPropertyDescriptors();
            if (instanceDescriptors != null) {
                supportedPropertyDescriptors.addAll(instanceDescriptors);
            }
        } catch (final Throwable t) {
            final ComponentLog logger = getLogger();
            final String message = "Unable to get property descriptors from Processor: " + t;
            logger.error(message);
            if (logger.isDebugEnabled()) {
                logger.error(message, t);
            }
        }
    }
    return Collections.unmodifiableList(supportedPropertyDescriptors);
}
Also used : PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) ArrayList(java.util.ArrayList) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) ComponentLog(org.apache.nifi.logging.ComponentLog)

Example 18 with ConfigurableComponent

use of org.apache.nifi.components.ConfigurableComponent in project nifi by apache.

the class VersionsResource method initiateVersionControlUpdate.

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("update-requests/process-groups/{id}")
@ApiOperation(value = "Initiate the Update Request of a Process Group with the given ID", response = VersionedFlowUpdateRequestEntity.class, notes = "For a Process Group that is already under Version Control, this will initiate the action of changing " + "from a specific version of the flow in the Flow Registry to a different version of the flow. This can be a lengthy " + "process, as it will stop any Processors and disable any Controller Services necessary to perform the action and then restart them. As a result, " + "the endpoint will immediately return a VersionedFlowUpdateRequestEntity, and the process of updating the flow will occur " + "asynchronously in the background. The client may then periodically poll the status of the request by issuing a GET request to " + "/versions/update-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " + "/versions/update-requests/{requestId}. " + NON_GUARANTEED_ENDPOINT, authorizations = { @Authorization(value = "Read - /process-groups/{uuid}"), @Authorization(value = "Write - /process-groups/{uuid}"), @Authorization(value = "Read - /{component-type}/{uuid} - For all encapsulated components"), @Authorization(value = "Write - /{component-type}/{uuid} - For all encapsulated components"), @Authorization(value = "Write - if the template contains any restricted components - /restricted-components") })
@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 initiateVersionControlUpdate(@ApiParam("The process group id.") @PathParam("id") final String groupId, @ApiParam(value = "The controller service configuration details.", required = true) final VersionControlInformationEntity requestEntity) {
    // Verify the request
    final RevisionDTO revisionDto = requestEntity.getProcessGroupRevision();
    if (revisionDto == null) {
        throw new IllegalArgumentException("Process Group Revision must be specified");
    }
    final VersionControlInformationDTO requestVersionControlInfoDto = requestEntity.getVersionControlInformation();
    if (requestVersionControlInfoDto == null) {
        throw new IllegalArgumentException("Version Control Information must be supplied.");
    }
    if (requestVersionControlInfoDto.getGroupId() == null) {
        throw new IllegalArgumentException("The Process Group ID must be supplied.");
    }
    if (!requestVersionControlInfoDto.getGroupId().equals(groupId)) {
        throw new IllegalArgumentException("The Process Group ID in the request body does not match the Process Group ID of the requested resource.");
    }
    if (requestVersionControlInfoDto.getBucketId() == null) {
        throw new IllegalArgumentException("The Bucket ID must be supplied.");
    }
    if (requestVersionControlInfoDto.getFlowId() == null) {
        throw new IllegalArgumentException("The Flow ID must be supplied.");
    }
    if (requestVersionControlInfoDto.getRegistryId() == null) {
        throw new IllegalArgumentException("The Registry ID must be supplied.");
    }
    if (requestVersionControlInfoDto.getVersion() == null) {
        throw new IllegalArgumentException("The Version of the flow must be supplied.");
    }
    // We will perform the updating of the Versioned Flow in a background thread because it can be a long-running process.
    // In order to do this, we will need some parameters that are only available as Thread-Local variables to the current
    // thread, so we will gather the values for these parameters up front.
    final boolean replicateRequest = isReplicateRequest();
    final ComponentLifecycle componentLifecycle = replicateRequest ? clusterComponentLifecycle : localComponentLifecycle;
    final NiFiUser user = NiFiUserUtils.getNiFiUser();
    // Workflow for this process:
    // 0. Obtain the versioned flow snapshot to use for the update
    // a. Contact registry to download the desired version.
    // b. Get Variable Registry of this Process Group and all ancestor groups
    // c. Perform diff to find any new variables
    // d. Get Variable Registry of any child Process Group in the versioned flow
    // e. Perform diff to find any new variables
    // f. Prompt user to fill in values for all new variables
    // 1. Determine which components would be affected (and are enabled/running)
    // a. Component itself is modified in some way, other than position changing.
    // b. Source and Destination of any Connection that is modified.
    // c. Any Processor or Controller Service that references a Controller Service that is modified.
    // 2. Verify READ and WRITE permissions for user, for every component.
    // 3. Verify that all components in the snapshot exist on all nodes (i.e., the NAR exists)?
    // 4. Verify that Process Group is already under version control. If not, must start Version Control instead of updateFlow
    // 5. Verify that Process Group is not 'dirty'.
    // 6. Stop all Processors, Funnels, Ports that are affected.
    // 7. Wait for all of the components to finish stopping.
    // 8. Disable all Controller Services that are affected.
    // 9. Wait for all Controller Services to finish disabling.
    // 10. Ensure that if any connection was deleted, that it has no data in it. Ensure that no Input Port
    // was removed, unless it currently has no incoming connections. Ensure that no Output Port was removed,
    // unless it currently has no outgoing connections. Checking ports & connections could be done before
    // stopping everything, but removal of Connections cannot.
    // 11. Update variable registry to include new variables
    // (only new variables so don't have to worry about affected components? Or do we need to in case a processor
    // is already referencing the variable? In which case we need to include the affected components above in the
    // Set of affected components before stopping/disabling.).
    // 12. Update components in the Process Group; update Version Control Information.
    // 13. Re-Enable all affected Controller Services that were not removed.
    // 14. Re-Start all Processors, Funnels, Ports that are affected and not removed.
    // Step 0: Get the Versioned Flow Snapshot from the Flow Registry
    final VersionedFlowSnapshot flowSnapshot = serviceFacade.getVersionedFlowSnapshot(requestEntity.getVersionControlInformation(), true);
    // The flow in the registry may not contain the same versions of components that we have in our flow. As a result, we need to update
    // the flow snapshot to contain compatible bundles.
    BundleUtils.discoverCompatibleBundles(flowSnapshot.getFlowContents());
    // Step 1: Determine which components will be affected by updating the version
    final Set<AffectedComponentEntity> affectedComponents = serviceFacade.getComponentsAffectedByVersionChange(groupId, flowSnapshot, user);
    // build a request wrapper
    final InitiateChangeFlowVersionRequestWrapper requestWrapper = new InitiateChangeFlowVersionRequestWrapper(requestEntity, componentLifecycle, getAbsolutePath(), affectedComponents, replicateRequest, flowSnapshot);
    final Revision requestRevision = getRevision(requestEntity.getProcessGroupRevision(), groupId);
    return withWriteLock(serviceFacade, requestWrapper, requestRevision, lookup -> {
        // Step 2: Verify READ and WRITE permissions for user, for every component.
        final ProcessGroupAuthorizable groupAuthorizable = lookup.getProcessGroup(groupId);
        authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.READ, true, false, true, true);
        authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, false, true, true);
        final VersionedProcessGroup groupContents = flowSnapshot.getFlowContents();
        final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(groupContents);
        restrictedComponents.forEach(restrictedComponent -> {
            final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
            authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
        });
    }, () -> {
        // Step 3: Verify that all components in the snapshot exist on all nodes
        // Step 4: Verify that Process Group is already under version control. If not, must start Version Control instead of updating flow
        // Step 5: Verify that Process Group is not 'dirty'
        serviceFacade.verifyCanUpdate(groupId, flowSnapshot, false, true);
    }, (revision, wrapper) -> {
        final String idGenerationSeed = getIdGenerationSeed().orElse(null);
        // Create an asynchronous request that will occur in the background, because this request may
        // result in stopping components, which can take an indeterminate amount of time.
        final String requestId = UUID.randomUUID().toString();
        final AsynchronousWebRequest<VersionControlInformationEntity> request = new StandardAsynchronousWebRequest<>(requestId, groupId, user, "Stopping Affected Processors");
        // Submit the request to be performed in the background
        final Consumer<AsynchronousWebRequest<VersionControlInformationEntity>> updateTask = vcur -> {
            try {
                final VersionControlInformationEntity updatedVersionControlEntity = updateFlowVersion(groupId, wrapper.getComponentLifecycle(), wrapper.getExampleUri(), wrapper.getAffectedComponents(), user, wrapper.isReplicateRequest(), revision, wrapper.getVersionControlInformationEntity(), wrapper.getFlowSnapshot(), request, idGenerationSeed, true, true);
                vcur.markComplete(updatedVersionControlEntity);
            } catch (final ResumeFlowException rfe) {
                // Treat ResumeFlowException differently because we don't want to include a message that we couldn't update the flow
                // since in this case the flow was successfully updated - we just couldn't re-enable the components.
                logger.error(rfe.getMessage(), rfe);
                vcur.setFailureReason(rfe.getMessage());
            } catch (final Exception e) {
                logger.error("Failed to update flow to new version", e);
                vcur.setFailureReason("Failed to update flow to new version due to " + e);
            }
        };
        requestManager.submitRequest("update-requests", requestId, request, updateTask);
        // Generate the response.
        final VersionedFlowUpdateRequestDTO updateRequestDto = new VersionedFlowUpdateRequestDTO();
        updateRequestDto.setComplete(request.isComplete());
        updateRequestDto.setFailureReason(request.getFailureReason());
        updateRequestDto.setLastUpdated(request.getLastUpdated());
        updateRequestDto.setProcessGroupId(groupId);
        updateRequestDto.setRequestId(requestId);
        updateRequestDto.setUri(generateResourceUri("versions", "update-requests", requestId));
        updateRequestDto.setPercentCompleted(request.getPercentComplete());
        updateRequestDto.setState(request.getState());
        final VersionedFlowUpdateRequestEntity updateRequestEntity = new VersionedFlowUpdateRequestEntity();
        final RevisionDTO groupRevision = serviceFacade.getProcessGroup(groupId).getRevision();
        updateRequestEntity.setProcessGroupRevision(groupRevision);
        updateRequestEntity.setRequest(updateRequestDto);
        return generateOkResponse(updateRequestEntity).build();
    });
}
Also used : ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) Produces(javax.ws.rs.Produces) Date(java.util.Date) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) Path(javax.ws.rs.Path) ApiParam(io.swagger.annotations.ApiParam) ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) StringUtils(org.apache.commons.lang3.StringUtils) ClientIdParameter(org.apache.nifi.web.api.request.ClientIdParameter) VersionedFlowSnapshotMetadata(org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata) ApiOperation(io.swagger.annotations.ApiOperation) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) Consumes(javax.ws.rs.Consumes) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) Map(java.util.Map) ResourceNotFoundException(org.apache.nifi.web.ResourceNotFoundException) DefaultValue(javax.ws.rs.DefaultValue) AsyncRequestManager(org.apache.nifi.web.api.concurrent.AsyncRequestManager) URI(java.net.URI) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) VersionedFlowUpdateRequestDTO(org.apache.nifi.web.api.dto.VersionedFlowUpdateRequestDTO) DELETE(javax.ws.rs.DELETE) LifecycleManagementException(org.apache.nifi.web.util.LifecycleManagementException) Authorizable(org.apache.nifi.authorization.resource.Authorizable) VersionedFlowDTO(org.apache.nifi.web.api.dto.VersionedFlowDTO) Set(java.util.Set) UUID(java.util.UUID) BundleUtils(org.apache.nifi.util.BundleUtils) LongParameter(org.apache.nifi.web.api.request.LongParameter) Collectors(java.util.stream.Collectors) FlowController(org.apache.nifi.controller.FlowController) CreateActiveRequestEntity(org.apache.nifi.web.api.entity.CreateActiveRequestEntity) Response(javax.ws.rs.core.Response) ScheduledState(org.apache.nifi.controller.ScheduledState) ProcessGroupEntity(org.apache.nifi.web.api.entity.ProcessGroupEntity) VersionedFlowSnapshotEntity(org.apache.nifi.web.api.entity.VersionedFlowSnapshotEntity) ControllerServiceState(org.apache.nifi.controller.service.ControllerServiceState) DtoFactory(org.apache.nifi.web.api.dto.DtoFactory) Entity(org.apache.nifi.web.api.entity.Entity) PathParam(javax.ws.rs.PathParam) Bucket(org.apache.nifi.registry.bucket.Bucket) Revision(org.apache.nifi.web.Revision) GET(javax.ws.rs.GET) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) HashMap(java.util.HashMap) ApiResponses(io.swagger.annotations.ApiResponses) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) AffectedComponentDTO(org.apache.nifi.web.api.dto.AffectedComponentDTO) ComponentLifecycle(org.apache.nifi.web.util.ComponentLifecycle) HttpMethod(javax.ws.rs.HttpMethod) HashSet(java.util.HashSet) FlowRegistryUtils(org.apache.nifi.registry.flow.FlowRegistryUtils) NiFiUser(org.apache.nifi.authorization.user.NiFiUser) VersionControlInformationDTO(org.apache.nifi.web.api.dto.VersionControlInformationDTO) Api(io.swagger.annotations.Api) VersionControlComponentMappingEntity(org.apache.nifi.web.api.entity.VersionControlComponentMappingEntity) CancellableTimedPause(org.apache.nifi.web.util.CancellableTimedPause) Status(javax.ws.rs.core.Response.Status) LinkedHashSet(java.util.LinkedHashSet) ResumeFlowException(org.apache.nifi.web.ResumeFlowException) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState) AffectedComponentUtils(org.apache.nifi.web.util.AffectedComponentUtils) NiFiServiceFacade(org.apache.nifi.web.NiFiServiceFacade) Logger(org.slf4j.Logger) POST(javax.ws.rs.POST) RequestAction(org.apache.nifi.authorization.RequestAction) IOException(java.io.IOException) VersionedFlowSnapshot(org.apache.nifi.registry.flow.VersionedFlowSnapshot) StandardAsynchronousWebRequest(org.apache.nifi.web.api.concurrent.StandardAsynchronousWebRequest) VersionedFlow(org.apache.nifi.registry.flow.VersionedFlow) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) StartVersionControlRequestEntity(org.apache.nifi.web.api.entity.StartVersionControlRequestEntity) Authorizer(org.apache.nifi.authorization.Authorizer) VersionControlInformationEntity(org.apache.nifi.web.api.entity.VersionControlInformationEntity) ProcessGroupAuthorizable(org.apache.nifi.authorization.ProcessGroupAuthorizable) ApiResponse(io.swagger.annotations.ApiResponse) NiFiUserUtils(org.apache.nifi.authorization.user.NiFiUserUtils) PUT(javax.ws.rs.PUT) AffectedComponentEntity(org.apache.nifi.web.api.entity.AffectedComponentEntity) VersionedFlowUpdateRequestEntity(org.apache.nifi.web.api.entity.VersionedFlowUpdateRequestEntity) Authorization(io.swagger.annotations.Authorization) RequestManager(org.apache.nifi.web.api.concurrent.RequestManager) Collections(java.util.Collections) AsynchronousWebRequest(org.apache.nifi.web.api.concurrent.AsynchronousWebRequest) NiFiUser(org.apache.nifi.authorization.user.NiFiUser) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) VersionControlInformationDTO(org.apache.nifi.web.api.dto.VersionControlInformationDTO) ProcessGroupAuthorizable(org.apache.nifi.authorization.ProcessGroupAuthorizable) VersionControlInformationEntity(org.apache.nifi.web.api.entity.VersionControlInformationEntity) VersionedFlowSnapshot(org.apache.nifi.registry.flow.VersionedFlowSnapshot) StandardAsynchronousWebRequest(org.apache.nifi.web.api.concurrent.StandardAsynchronousWebRequest) VersionedFlowUpdateRequestDTO(org.apache.nifi.web.api.dto.VersionedFlowUpdateRequestDTO) AffectedComponentEntity(org.apache.nifi.web.api.entity.AffectedComponentEntity) ResumeFlowException(org.apache.nifi.web.ResumeFlowException) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) URISyntaxException(java.net.URISyntaxException) ResourceNotFoundException(org.apache.nifi.web.ResourceNotFoundException) LifecycleManagementException(org.apache.nifi.web.util.LifecycleManagementException) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) ResumeFlowException(org.apache.nifi.web.ResumeFlowException) IOException(java.io.IOException) VersionedFlowUpdateRequestEntity(org.apache.nifi.web.api.entity.VersionedFlowUpdateRequestEntity) Revision(org.apache.nifi.web.Revision) ComponentLifecycle(org.apache.nifi.web.util.ComponentLifecycle) StandardAsynchronousWebRequest(org.apache.nifi.web.api.concurrent.StandardAsynchronousWebRequest) AsynchronousWebRequest(org.apache.nifi.web.api.concurrent.AsynchronousWebRequest) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 19 with ConfigurableComponent

use of org.apache.nifi.components.ConfigurableComponent in project nifi by apache.

the class VersionsResource method initiateRevertFlowVersion.

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("revert-requests/process-groups/{id}")
@ApiOperation(value = "Initiate the Revert Request of a Process Group with the given ID", response = VersionedFlowUpdateRequestEntity.class, notes = "For a Process Group that is already under Version Control, this will initiate the action of reverting " + "any local changes that have been made to the Process Group since it was last synchronized with the Flow Registry. This will result in the " + "flow matching the Versioned Flow that exists in the Flow Registry. This can be a lengthy " + "process, as it will stop any Processors and disable any Controller Services necessary to perform the action and then restart them. As a result, " + "the endpoint will immediately return a VersionedFlowUpdateRequestEntity, and the process of updating the flow will occur " + "asynchronously in the background. The client may then periodically poll the status of the request by issuing a GET request to " + "/versions/revert-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " + "/versions/revert-requests/{requestId}. " + NON_GUARANTEED_ENDPOINT, authorizations = { @Authorization(value = "Read - /process-groups/{uuid}"), @Authorization(value = "Write - /process-groups/{uuid}"), @Authorization(value = "Read - /{component-type}/{uuid} - For all encapsulated components"), @Authorization(value = "Write - /{component-type}/{uuid} - For all encapsulated components"), @Authorization(value = "Write - if the template contains any restricted components - /restricted-components") })
@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 initiateRevertFlowVersion(@ApiParam("The process group id.") @PathParam("id") final String groupId, @ApiParam(value = "The controller service configuration details.", required = true) final VersionControlInformationEntity requestEntity) throws IOException {
    // Verify the request
    final RevisionDTO revisionDto = requestEntity.getProcessGroupRevision();
    if (revisionDto == null) {
        throw new IllegalArgumentException("Process Group Revision must be specified");
    }
    final VersionControlInformationDTO requestVersionControlInfoDto = requestEntity.getVersionControlInformation();
    if (requestVersionControlInfoDto == null) {
        throw new IllegalArgumentException("Version Control Information must be supplied.");
    }
    if (requestVersionControlInfoDto.getGroupId() == null) {
        throw new IllegalArgumentException("The Process Group ID must be supplied.");
    }
    if (!requestVersionControlInfoDto.getGroupId().equals(groupId)) {
        throw new IllegalArgumentException("The Process Group ID in the request body does not match the Process Group ID of the requested resource.");
    }
    if (requestVersionControlInfoDto.getBucketId() == null) {
        throw new IllegalArgumentException("The Bucket ID must be supplied.");
    }
    if (requestVersionControlInfoDto.getFlowId() == null) {
        throw new IllegalArgumentException("The Flow ID must be supplied.");
    }
    if (requestVersionControlInfoDto.getRegistryId() == null) {
        throw new IllegalArgumentException("The Registry ID must be supplied.");
    }
    if (requestVersionControlInfoDto.getVersion() == null) {
        throw new IllegalArgumentException("The Version of the flow must be supplied.");
    }
    // We will perform the updating of the Versioned Flow in a background thread because it can be a long-running process.
    // In order to do this, we will need some parameters that are only available as Thread-Local variables to the current
    // thread, so we will gather the values for these parameters up front.
    final boolean replicateRequest = isReplicateRequest();
    final ComponentLifecycle componentLifecycle = replicateRequest ? clusterComponentLifecycle : localComponentLifecycle;
    final NiFiUser user = NiFiUserUtils.getNiFiUser();
    // Step 0: Get the Versioned Flow Snapshot from the Flow Registry
    final VersionedFlowSnapshot flowSnapshot = serviceFacade.getVersionedFlowSnapshot(requestEntity.getVersionControlInformation(), true);
    // The flow in the registry may not contain the same versions of components that we have in our flow. As a result, we need to update
    // the flow snapshot to contain compatible bundles.
    BundleUtils.discoverCompatibleBundles(flowSnapshot.getFlowContents());
    // Step 1: Determine which components will be affected by updating the version
    final Set<AffectedComponentEntity> affectedComponents = serviceFacade.getComponentsAffectedByVersionChange(groupId, flowSnapshot, user);
    // build a request wrapper
    final InitiateChangeFlowVersionRequestWrapper requestWrapper = new InitiateChangeFlowVersionRequestWrapper(requestEntity, componentLifecycle, getAbsolutePath(), affectedComponents, replicateRequest, flowSnapshot);
    final Revision requestRevision = getRevision(requestEntity.getProcessGroupRevision(), groupId);
    return withWriteLock(serviceFacade, requestWrapper, requestRevision, lookup -> {
        // Step 2: Verify READ and WRITE permissions for user, for every component.
        final ProcessGroupAuthorizable groupAuthorizable = lookup.getProcessGroup(groupId);
        authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.READ, true, false, true, true);
        authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, false, true, true);
        final VersionedProcessGroup groupContents = flowSnapshot.getFlowContents();
        final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(groupContents);
        restrictedComponents.forEach(restrictedComponent -> {
            final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
            authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
        });
    }, () -> {
        // Step 3: Verify that all components in the snapshot exist on all nodes
        // Step 4: Verify that Process Group is already under version control. If not, must start Version Control instead of updating flow
        serviceFacade.verifyCanRevertLocalModifications(groupId, flowSnapshot);
    }, (revision, wrapper) -> {
        final VersionControlInformationEntity versionControlInformationEntity = wrapper.getVersionControlInformationEntity();
        final VersionControlInformationDTO versionControlInformationDTO = versionControlInformationEntity.getVersionControlInformation();
        // Ensure that the information passed in is correct
        final VersionControlInformationEntity currentVersionEntity = serviceFacade.getVersionControlInformation(groupId);
        if (currentVersionEntity == null) {
            throw new IllegalStateException("Process Group cannot be reverted to the previous version of the flow because Process Group is not under Version Control.");
        }
        final VersionControlInformationDTO currentVersion = currentVersionEntity.getVersionControlInformation();
        if (!currentVersion.getBucketId().equals(versionControlInformationDTO.getBucketId())) {
            throw new IllegalArgumentException("The Version Control Information provided does not match the flow that the Process Group is currently synchronized with.");
        }
        if (!currentVersion.getFlowId().equals(versionControlInformationDTO.getFlowId())) {
            throw new IllegalArgumentException("The Version Control Information provided does not match the flow that the Process Group is currently synchronized with.");
        }
        if (!currentVersion.getRegistryId().equals(versionControlInformationDTO.getRegistryId())) {
            throw new IllegalArgumentException("The Version Control Information provided does not match the flow that the Process Group is currently synchronized with.");
        }
        if (!currentVersion.getVersion().equals(versionControlInformationDTO.getVersion())) {
            throw new IllegalArgumentException("The Version Control Information provided does not match the flow that the Process Group is currently synchronized with.");
        }
        final String idGenerationSeed = getIdGenerationSeed().orElse(null);
        // Create an asynchronous request that will occur in the background, because this request may
        // result in stopping components, which can take an indeterminate amount of time.
        final String requestId = UUID.randomUUID().toString();
        final AsynchronousWebRequest<VersionControlInformationEntity> request = new StandardAsynchronousWebRequest<>(requestId, groupId, user, "Stopping Affected Processors");
        // Submit the request to be performed in the background
        final Consumer<AsynchronousWebRequest<VersionControlInformationEntity>> updateTask = vcur -> {
            try {
                final VersionControlInformationEntity updatedVersionControlEntity = updateFlowVersion(groupId, wrapper.getComponentLifecycle(), wrapper.getExampleUri(), wrapper.getAffectedComponents(), user, wrapper.isReplicateRequest(), revision, versionControlInformationEntity, wrapper.getFlowSnapshot(), request, idGenerationSeed, false, true);
                vcur.markComplete(updatedVersionControlEntity);
            } catch (final ResumeFlowException rfe) {
                // Treat ResumeFlowException differently because we don't want to include a message that we couldn't update the flow
                // since in this case the flow was successfully updated - we just couldn't re-enable the components.
                logger.error(rfe.getMessage(), rfe);
                vcur.setFailureReason(rfe.getMessage());
            } catch (final Exception e) {
                logger.error("Failed to update flow to new version", e);
                vcur.setFailureReason("Failed to update flow to new version due to " + e.getMessage());
            }
        };
        requestManager.submitRequest("revert-requests", requestId, request, updateTask);
        // Generate the response.
        final VersionedFlowUpdateRequestDTO updateRequestDto = new VersionedFlowUpdateRequestDTO();
        updateRequestDto.setComplete(request.isComplete());
        updateRequestDto.setFailureReason(request.getFailureReason());
        updateRequestDto.setLastUpdated(request.getLastUpdated());
        updateRequestDto.setProcessGroupId(groupId);
        updateRequestDto.setRequestId(requestId);
        updateRequestDto.setState(request.getState());
        updateRequestDto.setPercentCompleted(request.getPercentComplete());
        updateRequestDto.setUri(generateResourceUri("versions", "revert-requests", requestId));
        final VersionedFlowUpdateRequestEntity updateRequestEntity = new VersionedFlowUpdateRequestEntity();
        final RevisionDTO groupRevision = serviceFacade.getProcessGroup(groupId).getRevision();
        updateRequestEntity.setProcessGroupRevision(groupRevision);
        updateRequestEntity.setRequest(updateRequestDto);
        return generateOkResponse(updateRequestEntity).build();
    });
}
Also used : ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) Produces(javax.ws.rs.Produces) Date(java.util.Date) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) Path(javax.ws.rs.Path) ApiParam(io.swagger.annotations.ApiParam) ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) StringUtils(org.apache.commons.lang3.StringUtils) ClientIdParameter(org.apache.nifi.web.api.request.ClientIdParameter) VersionedFlowSnapshotMetadata(org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata) ApiOperation(io.swagger.annotations.ApiOperation) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) Consumes(javax.ws.rs.Consumes) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) Map(java.util.Map) ResourceNotFoundException(org.apache.nifi.web.ResourceNotFoundException) DefaultValue(javax.ws.rs.DefaultValue) AsyncRequestManager(org.apache.nifi.web.api.concurrent.AsyncRequestManager) URI(java.net.URI) NodeResponse(org.apache.nifi.cluster.manager.NodeResponse) VersionedFlowUpdateRequestDTO(org.apache.nifi.web.api.dto.VersionedFlowUpdateRequestDTO) DELETE(javax.ws.rs.DELETE) LifecycleManagementException(org.apache.nifi.web.util.LifecycleManagementException) Authorizable(org.apache.nifi.authorization.resource.Authorizable) VersionedFlowDTO(org.apache.nifi.web.api.dto.VersionedFlowDTO) Set(java.util.Set) UUID(java.util.UUID) BundleUtils(org.apache.nifi.util.BundleUtils) LongParameter(org.apache.nifi.web.api.request.LongParameter) Collectors(java.util.stream.Collectors) FlowController(org.apache.nifi.controller.FlowController) CreateActiveRequestEntity(org.apache.nifi.web.api.entity.CreateActiveRequestEntity) Response(javax.ws.rs.core.Response) ScheduledState(org.apache.nifi.controller.ScheduledState) ProcessGroupEntity(org.apache.nifi.web.api.entity.ProcessGroupEntity) VersionedFlowSnapshotEntity(org.apache.nifi.web.api.entity.VersionedFlowSnapshotEntity) ControllerServiceState(org.apache.nifi.controller.service.ControllerServiceState) DtoFactory(org.apache.nifi.web.api.dto.DtoFactory) Entity(org.apache.nifi.web.api.entity.Entity) PathParam(javax.ws.rs.PathParam) Bucket(org.apache.nifi.registry.bucket.Bucket) Revision(org.apache.nifi.web.Revision) GET(javax.ws.rs.GET) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) HashMap(java.util.HashMap) ApiResponses(io.swagger.annotations.ApiResponses) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) AffectedComponentDTO(org.apache.nifi.web.api.dto.AffectedComponentDTO) ComponentLifecycle(org.apache.nifi.web.util.ComponentLifecycle) HttpMethod(javax.ws.rs.HttpMethod) HashSet(java.util.HashSet) FlowRegistryUtils(org.apache.nifi.registry.flow.FlowRegistryUtils) NiFiUser(org.apache.nifi.authorization.user.NiFiUser) VersionControlInformationDTO(org.apache.nifi.web.api.dto.VersionControlInformationDTO) Api(io.swagger.annotations.Api) VersionControlComponentMappingEntity(org.apache.nifi.web.api.entity.VersionControlComponentMappingEntity) CancellableTimedPause(org.apache.nifi.web.util.CancellableTimedPause) Status(javax.ws.rs.core.Response.Status) LinkedHashSet(java.util.LinkedHashSet) ResumeFlowException(org.apache.nifi.web.ResumeFlowException) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState) AffectedComponentUtils(org.apache.nifi.web.util.AffectedComponentUtils) NiFiServiceFacade(org.apache.nifi.web.NiFiServiceFacade) Logger(org.slf4j.Logger) POST(javax.ws.rs.POST) RequestAction(org.apache.nifi.authorization.RequestAction) IOException(java.io.IOException) VersionedFlowSnapshot(org.apache.nifi.registry.flow.VersionedFlowSnapshot) StandardAsynchronousWebRequest(org.apache.nifi.web.api.concurrent.StandardAsynchronousWebRequest) VersionedFlow(org.apache.nifi.registry.flow.VersionedFlow) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) StartVersionControlRequestEntity(org.apache.nifi.web.api.entity.StartVersionControlRequestEntity) Authorizer(org.apache.nifi.authorization.Authorizer) VersionControlInformationEntity(org.apache.nifi.web.api.entity.VersionControlInformationEntity) ProcessGroupAuthorizable(org.apache.nifi.authorization.ProcessGroupAuthorizable) ApiResponse(io.swagger.annotations.ApiResponse) NiFiUserUtils(org.apache.nifi.authorization.user.NiFiUserUtils) PUT(javax.ws.rs.PUT) AffectedComponentEntity(org.apache.nifi.web.api.entity.AffectedComponentEntity) VersionedFlowUpdateRequestEntity(org.apache.nifi.web.api.entity.VersionedFlowUpdateRequestEntity) Authorization(io.swagger.annotations.Authorization) RequestManager(org.apache.nifi.web.api.concurrent.RequestManager) Collections(java.util.Collections) AsynchronousWebRequest(org.apache.nifi.web.api.concurrent.AsynchronousWebRequest) NiFiUser(org.apache.nifi.authorization.user.NiFiUser) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) VersionControlInformationDTO(org.apache.nifi.web.api.dto.VersionControlInformationDTO) ProcessGroupAuthorizable(org.apache.nifi.authorization.ProcessGroupAuthorizable) VersionControlInformationEntity(org.apache.nifi.web.api.entity.VersionControlInformationEntity) VersionedFlowSnapshot(org.apache.nifi.registry.flow.VersionedFlowSnapshot) StandardAsynchronousWebRequest(org.apache.nifi.web.api.concurrent.StandardAsynchronousWebRequest) VersionedFlowUpdateRequestDTO(org.apache.nifi.web.api.dto.VersionedFlowUpdateRequestDTO) AffectedComponentEntity(org.apache.nifi.web.api.entity.AffectedComponentEntity) ResumeFlowException(org.apache.nifi.web.ResumeFlowException) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) URISyntaxException(java.net.URISyntaxException) ResourceNotFoundException(org.apache.nifi.web.ResourceNotFoundException) LifecycleManagementException(org.apache.nifi.web.util.LifecycleManagementException) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) ResumeFlowException(org.apache.nifi.web.ResumeFlowException) IOException(java.io.IOException) VersionedFlowUpdateRequestEntity(org.apache.nifi.web.api.entity.VersionedFlowUpdateRequestEntity) Revision(org.apache.nifi.web.Revision) ComponentLifecycle(org.apache.nifi.web.util.ComponentLifecycle) StandardAsynchronousWebRequest(org.apache.nifi.web.api.concurrent.StandardAsynchronousWebRequest) AsynchronousWebRequest(org.apache.nifi.web.api.concurrent.AsynchronousWebRequest) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 20 with ConfigurableComponent

use of org.apache.nifi.components.ConfigurableComponent in project nifi by apache.

the class StandardReportingTaskDAO method updateBundle.

private void updateBundle(ReportingTaskNode reportingTask, ReportingTaskDTO reportingTaskDTO) {
    final BundleDTO bundleDTO = reportingTaskDTO.getBundle();
    if (bundleDTO != null) {
        final BundleCoordinate incomingCoordinate = BundleUtils.getBundle(reportingTask.getCanonicalClassName(), bundleDTO);
        final BundleCoordinate existingCoordinate = reportingTask.getBundleCoordinate();
        if (!existingCoordinate.getCoordinate().equals(incomingCoordinate.getCoordinate())) {
            try {
                // we need to use the property descriptors from the temp component here in case we are changing from a ghost component to a real component
                final ConfigurableComponent tempComponent = ExtensionManager.getTempComponent(reportingTask.getCanonicalClassName(), incomingCoordinate);
                final Set<URL> additionalUrls = reportingTask.getAdditionalClasspathResources(tempComponent.getPropertyDescriptors());
                reloadComponent.reload(reportingTask, reportingTask.getCanonicalClassName(), incomingCoordinate, additionalUrls);
            } catch (ReportingTaskInstantiationException e) {
                throw new NiFiCoreException(String.format("Unable to update reporting task %s from %s to %s due to: %s", reportingTaskDTO.getId(), reportingTask.getBundleCoordinate().getCoordinate(), incomingCoordinate.getCoordinate(), e.getMessage()), e);
            }
        }
    }
}
Also used : NiFiCoreException(org.apache.nifi.web.NiFiCoreException) ReportingTaskInstantiationException(org.apache.nifi.controller.reporting.ReportingTaskInstantiationException) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) BundleDTO(org.apache.nifi.web.api.dto.BundleDTO) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) URL(java.net.URL)

Aggregations

ConfigurableComponent (org.apache.nifi.components.ConfigurableComponent)20 BundleCoordinate (org.apache.nifi.bundle.BundleCoordinate)9 LinkedHashSet (java.util.LinkedHashSet)6 URL (java.net.URL)5 HashSet (java.util.HashSet)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 Set (java.util.Set)4 ApiOperation (io.swagger.annotations.ApiOperation)3 ApiResponses (io.swagger.annotations.ApiResponses)3 IOException (java.io.IOException)3 Consumes (javax.ws.rs.Consumes)3 POST (javax.ws.rs.POST)3 Path (javax.ws.rs.Path)3 Produces (javax.ws.rs.Produces)3 AccessDeniedException (org.apache.nifi.authorization.AccessDeniedException)3 NiFiCoreException (org.apache.nifi.web.NiFiCoreException)3 BundleDTO (org.apache.nifi.web.api.dto.BundleDTO)3 Api (io.swagger.annotations.Api)2 ApiParam (io.swagger.annotations.ApiParam)2