Search in sources :

Example 1 with VersionedFlowState

use of org.apache.nifi.registry.flow.VersionedFlowState in project nifi by apache.

the class DtoFactory method createVersionControlInformationDto.

public VersionControlInformationDTO createVersionControlInformationDto(final ProcessGroup group) {
    if (group == null) {
        return null;
    }
    final VersionControlInformation versionControlInfo = group.getVersionControlInformation();
    if (versionControlInfo == null) {
        return null;
    }
    final VersionControlInformationDTO dto = new VersionControlInformationDTO();
    dto.setGroupId(group.getIdentifier());
    dto.setRegistryId(versionControlInfo.getRegistryIdentifier());
    dto.setRegistryName(versionControlInfo.getRegistryName());
    dto.setBucketId(versionControlInfo.getBucketIdentifier());
    dto.setBucketName(versionControlInfo.getBucketName());
    dto.setFlowId(versionControlInfo.getFlowIdentifier());
    dto.setFlowName(versionControlInfo.getFlowName());
    dto.setFlowDescription(versionControlInfo.getFlowDescription());
    dto.setVersion(versionControlInfo.getVersion());
    final VersionedFlowStatus status = versionControlInfo.getStatus();
    final VersionedFlowState state = status.getState();
    dto.setState(state == null ? null : state.name());
    dto.setStateExplanation(status.getStateExplanation());
    return dto;
}
Also used : VersionedFlowStatus(org.apache.nifi.registry.flow.VersionedFlowStatus) VersionControlInformation(org.apache.nifi.registry.flow.VersionControlInformation) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState)

Example 2 with VersionedFlowState

use of org.apache.nifi.registry.flow.VersionedFlowState in project nifi by apache.

the class ProcessGroupResource method createProcessGroup.

/**
 * Adds the specified process group.
 *
 * @param httpServletRequest request
 * @param groupId The group id
 * @param requestProcessGroupEntity A processGroupEntity
 * @return A processGroupEntity
 * @throws IOException if the request indicates that the Process Group should be imported from a Flow Registry and NiFi is unable to communicate with the Flow Registry
 */
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/process-groups")
@ApiOperation(value = "Creates a process group", response = ProcessGroupEntity.class, 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 createProcessGroup(@Context final HttpServletRequest httpServletRequest, @ApiParam(value = "The process group id.", required = true) @PathParam("id") final String groupId, @ApiParam(value = "The process group configuration details.", required = true) final ProcessGroupEntity requestProcessGroupEntity) throws IOException {
    if (requestProcessGroupEntity == null || requestProcessGroupEntity.getComponent() == null) {
        throw new IllegalArgumentException("Process group details must be specified.");
    }
    if (requestProcessGroupEntity.getRevision() == null || (requestProcessGroupEntity.getRevision().getVersion() == null || requestProcessGroupEntity.getRevision().getVersion() != 0)) {
        throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Process group.");
    }
    if (requestProcessGroupEntity.getComponent().getId() != null) {
        throw new IllegalArgumentException("Process group ID cannot be specified.");
    }
    final PositionDTO proposedPosition = requestProcessGroupEntity.getComponent().getPosition();
    if (proposedPosition != null) {
        if (proposedPosition.getX() == null || proposedPosition.getY() == null) {
            throw new IllegalArgumentException("The x and y coordinate of the proposed position must be specified.");
        }
    }
    // if the group name isn't specified, ensure the group is being imported from version control
    if (StringUtils.isBlank(requestProcessGroupEntity.getComponent().getName()) && requestProcessGroupEntity.getComponent().getVersionControlInformation() == null) {
        throw new IllegalArgumentException("The group name is required when the group is not imported from version control.");
    }
    if (requestProcessGroupEntity.getComponent().getParentGroupId() != null && !groupId.equals(requestProcessGroupEntity.getComponent().getParentGroupId())) {
        throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", requestProcessGroupEntity.getComponent().getParentGroupId(), groupId));
    }
    requestProcessGroupEntity.getComponent().setParentGroupId(groupId);
    // Step 1: Ensure that user has write permissions to the Process Group. If not, then immediately fail.
    // Step 2: Retrieve flow from Flow Registry
    // Step 3: Resolve Bundle info
    // Step 4: Update contents of the ProcessGroupDTO passed in to include the components that need to be added.
    // Step 5: If any of the components is a Restricted Component, then we must authorize the user
    // for write access to the RestrictedComponents resource
    // Step 6: Replicate the request or call serviceFacade.updateProcessGroup
    final VersionControlInformationDTO versionControlInfo = requestProcessGroupEntity.getComponent().getVersionControlInformation();
    if (versionControlInfo != null && requestProcessGroupEntity.getVersionedFlowSnapshot() == null) {
        // Step 1: Ensure that user has write permissions to the Process Group. If not, then immediately fail.
        // Step 2: Retrieve flow from Flow Registry
        final VersionedFlowSnapshot flowSnapshot = serviceFacade.getVersionedFlowSnapshot(versionControlInfo, true);
        final Bucket bucket = flowSnapshot.getBucket();
        final VersionedFlow flow = flowSnapshot.getFlow();
        versionControlInfo.setBucketName(bucket.getName());
        versionControlInfo.setFlowName(flow.getName());
        versionControlInfo.setFlowDescription(flow.getDescription());
        versionControlInfo.setRegistryName(serviceFacade.getFlowRegistryName(versionControlInfo.getRegistryId()));
        final VersionedFlowState flowState = flowSnapshot.isLatest() ? VersionedFlowState.UP_TO_DATE : VersionedFlowState.STALE;
        versionControlInfo.setState(flowState.name());
        // Step 3: Resolve Bundle info
        BundleUtils.discoverCompatibleBundles(flowSnapshot.getFlowContents());
        // Step 4: Update contents of the ProcessGroupDTO passed in to include the components that need to be added.
        requestProcessGroupEntity.setVersionedFlowSnapshot(flowSnapshot);
    }
    if (versionControlInfo != null) {
        final VersionedFlowSnapshot flowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
        serviceFacade.verifyImportProcessGroup(versionControlInfo, flowSnapshot.getFlowContents(), groupId);
    }
    // Step 6: Replicate the request or call serviceFacade.updateProcessGroup
    if (isReplicateRequest()) {
        return replicate(HttpMethod.POST, requestProcessGroupEntity);
    }
    return withWriteLock(serviceFacade, requestProcessGroupEntity, lookup -> {
        final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
        processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
        // Step 5: If any of the components is a Restricted Component, then we must authorize the user
        // for write access to the RestrictedComponents resource
        final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
        if (versionedFlowSnapshot != null) {
            final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(versionedFlowSnapshot.getFlowContents());
            restrictedComponents.forEach(restrictedComponent -> {
                final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
                authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
            });
        }
    }, () -> {
        final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
        if (versionedFlowSnapshot != null) {
            serviceFacade.verifyComponentTypes(versionedFlowSnapshot.getFlowContents());
        }
    }, processGroupEntity -> {
        final ProcessGroupDTO processGroup = processGroupEntity.getComponent();
        // set the processor id as appropriate
        processGroup.setId(generateUuid());
        // ensure the group name comes from the versioned flow
        final VersionedFlowSnapshot flowSnapshot = processGroupEntity.getVersionedFlowSnapshot();
        if (flowSnapshot != null && StringUtils.isNotBlank(flowSnapshot.getFlowContents().getName()) && StringUtils.isBlank(processGroup.getName())) {
            processGroup.setName(flowSnapshot.getFlowContents().getName());
        }
        // create the process group contents
        final Revision revision = getRevision(processGroupEntity, processGroup.getId());
        ProcessGroupEntity entity = serviceFacade.createProcessGroup(revision, groupId, processGroup);
        if (flowSnapshot != null) {
            final RevisionDTO revisionDto = entity.getRevision();
            final String newGroupId = entity.getComponent().getId();
            final Revision newGroupRevision = new Revision(revisionDto.getVersion(), revisionDto.getClientId(), newGroupId);
            // We don't want the Process Group's position to be updated because we want to keep the position where the user
            // placed the Process Group. However, we do want to use the name of the Process Group that is in the Flow Contents.
            // To accomplish this, we call updateProcessGroupContents() passing 'true' for the updateSettings flag but null out the position.
            flowSnapshot.getFlowContents().setPosition(null);
            entity = serviceFacade.updateProcessGroupContents(NiFiUserUtils.getNiFiUser(), newGroupRevision, newGroupId, versionControlInfo, flowSnapshot, getIdGenerationSeed().orElse(null), false, true, true);
        }
        populateRemainingProcessGroupEntityContent(entity);
        // generate a 201 created response
        String uri = entity.getUri();
        return generateCreatedResponse(URI.create(uri), entity).build();
    });
}
Also used : ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) ProcessGroupEntity(org.apache.nifi.web.api.entity.ProcessGroupEntity) RemoteProcessGroupEntity(org.apache.nifi.web.api.entity.RemoteProcessGroupEntity) VersionedFlow(org.apache.nifi.registry.flow.VersionedFlow) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) PositionDTO(org.apache.nifi.web.api.dto.PositionDTO) RevisionDTO(org.apache.nifi.web.api.dto.RevisionDTO) VersionControlInformationDTO(org.apache.nifi.web.api.dto.VersionControlInformationDTO) Revision(org.apache.nifi.web.Revision) Bucket(org.apache.nifi.registry.bucket.Bucket) VersionedFlowSnapshot(org.apache.nifi.registry.flow.VersionedFlowSnapshot) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState) ComponentAuthorizable(org.apache.nifi.authorization.ComponentAuthorizable) Authorizable(org.apache.nifi.authorization.resource.Authorizable) SnippetAuthorizable(org.apache.nifi.authorization.SnippetAuthorizable) TemplateContentsAuthorizable(org.apache.nifi.authorization.TemplateContentsAuthorizable) ProcessGroupAuthorizable(org.apache.nifi.authorization.ProcessGroupAuthorizable) ProcessGroupDTO(org.apache.nifi.web.api.dto.ProcessGroupDTO) RemoteProcessGroupDTO(org.apache.nifi.web.api.dto.RemoteProcessGroupDTO) 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 3 with VersionedFlowState

use of org.apache.nifi.registry.flow.VersionedFlowState in project nifi by apache.

the class StandardProcessGroup method setVersionControlInformation.

@Override
public void setVersionControlInformation(final VersionControlInformation versionControlInformation, final Map<String, String> versionedComponentIds) {
    final StandardVersionControlInformation svci = new StandardVersionControlInformation(versionControlInformation.getRegistryIdentifier(), versionControlInformation.getRegistryName(), versionControlInformation.getBucketIdentifier(), versionControlInformation.getFlowIdentifier(), versionControlInformation.getVersion(), stripContentsFromRemoteDescendantGroups(versionControlInformation.getFlowSnapshot(), true), versionControlInformation.getStatus()) {

        @Override
        public String getRegistryName() {
            final String registryId = versionControlInformation.getRegistryIdentifier();
            final FlowRegistry registry = flowController.getFlowRegistryClient().getFlowRegistry(registryId);
            return registry == null ? registryId : registry.getName();
        }

        private boolean isModified() {
            Set<FlowDifference> differences = versionControlFields.getFlowDifferences();
            if (differences == null) {
                differences = getModifications();
                if (differences == null) {
                    return false;
                }
                versionControlFields.setFlowDifferences(differences);
            }
            return !differences.isEmpty();
        }

        @Override
        public VersionedFlowStatus getStatus() {
            // If current state is a sync failure, then
            final String syncFailureExplanation = versionControlFields.getSyncFailureExplanation();
            if (syncFailureExplanation != null) {
                return new StandardVersionedFlowStatus(VersionedFlowState.SYNC_FAILURE, syncFailureExplanation);
            }
            final boolean modified = isModified();
            if (!modified) {
                final VersionControlInformation vci = StandardProcessGroup.this.versionControlInfo.get();
                if (vci.getFlowSnapshot() == null) {
                    return new StandardVersionedFlowStatus(VersionedFlowState.SYNC_FAILURE, "Process Group has not yet been synchronized with Flow Registry");
                }
            }
            final boolean stale = versionControlFields.isStale();
            final VersionedFlowState flowState;
            if (modified && stale) {
                flowState = VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
            } else if (modified) {
                flowState = VersionedFlowState.LOCALLY_MODIFIED;
            } else if (stale) {
                flowState = VersionedFlowState.STALE;
            } else {
                flowState = VersionedFlowState.UP_TO_DATE;
            }
            return new StandardVersionedFlowStatus(flowState, flowState.getDescription());
        }
    };
    svci.setBucketName(versionControlInformation.getBucketName());
    svci.setFlowName(versionControlInformation.getFlowName());
    svci.setFlowDescription(versionControlInformation.getFlowDescription());
    final VersionedFlowState flowState = versionControlInformation.getStatus().getState();
    versionControlFields.setStale(flowState == VersionedFlowState.STALE || flowState == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE);
    versionControlFields.setLocallyModified(flowState == VersionedFlowState.LOCALLY_MODIFIED || flowState == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE);
    versionControlFields.setSyncFailureExplanation(null);
    writeLock.lock();
    try {
        updateVersionedComponentIds(this, versionedComponentIds);
        this.versionControlInfo.set(svci);
        versionControlFields.setFlowDifferences(null);
        final ProcessGroup parent = getParent();
        if (parent != null) {
            parent.onComponentModified();
        }
        scheduler.submitFrameworkTask(() -> synchronizeWithFlowRegistry(flowController.getFlowRegistryClient()));
    } finally {
        writeLock.unlock();
    }
}
Also used : FlowDifference(org.apache.nifi.registry.flow.diff.FlowDifference) StandardVersionControlInformation(org.apache.nifi.registry.flow.StandardVersionControlInformation) StandardVersionControlInformation(org.apache.nifi.registry.flow.StandardVersionControlInformation) VersionControlInformation(org.apache.nifi.registry.flow.VersionControlInformation) FlowRegistry(org.apache.nifi.registry.flow.FlowRegistry) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) VersionedRemoteProcessGroup(org.apache.nifi.registry.flow.VersionedRemoteProcessGroup)

Example 4 with VersionedFlowState

use of org.apache.nifi.registry.flow.VersionedFlowState in project nifi by apache.

the class StandardProcessGroup method verifyNoDescendantsWithLocalModifications.

private void verifyNoDescendantsWithLocalModifications(final String action) {
    for (final ProcessGroup descendant : findAllProcessGroups()) {
        final VersionControlInformation descendantVci = descendant.getVersionControlInformation();
        if (descendantVci != null) {
            final VersionedFlowState flowState = descendantVci.getStatus().getState();
            final boolean modified = flowState == VersionedFlowState.LOCALLY_MODIFIED || flowState == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
            if (modified) {
                throw new IllegalStateException("Process Group cannot " + action + " because it contains a child or descendant Process Group that is under Version Control and " + "has local modifications. Each descendant Process Group that is under Version Control must first be reverted or have its changes pushed to the Flow Registry before " + "this action can be performed on the parent Process Group.");
            }
            if (flowState == VersionedFlowState.SYNC_FAILURE) {
                throw new IllegalStateException("Process Group cannot " + action + " because it contains a child or descendant Process Group that is under Version Control and " + "is not synchronized with the Flow Registry. Each descendant Process Group must first be synchronized with the Flow Registry before this action can be " + "performed on the parent Process Group. NiFi will continue to attempt to communicate with the Flow Registry periodically in the background.");
            }
        }
    }
}
Also used : StandardVersionControlInformation(org.apache.nifi.registry.flow.StandardVersionControlInformation) VersionControlInformation(org.apache.nifi.registry.flow.VersionControlInformation) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) VersionedRemoteProcessGroup(org.apache.nifi.registry.flow.VersionedRemoteProcessGroup) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState)

Example 5 with VersionedFlowState

use of org.apache.nifi.registry.flow.VersionedFlowState in project nifi by apache.

the class StandardProcessGroup method verifyCanUpdate.

@Override
public void verifyCanUpdate(final VersionedFlowSnapshot updatedFlow, final boolean verifyConnectionRemoval, final boolean verifyNotDirty) {
    readLock.lock();
    try {
        final VersionControlInformation versionControlInfo = getVersionControlInformation();
        if (versionControlInfo != null) {
            if (!versionControlInfo.getFlowIdentifier().equals(updatedFlow.getSnapshotMetadata().getFlowIdentifier())) {
                throw new IllegalStateException(this + " is under version control but the given flow does not match the flow that this Process Group is synchronized with");
            }
            if (verifyNotDirty) {
                final VersionedFlowState flowState = versionControlInfo.getStatus().getState();
                final boolean modified = flowState == VersionedFlowState.LOCALLY_MODIFIED || flowState == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
                final Set<FlowDifference> modifications = getModifications();
                if (modified) {
                    final String changes = modifications.stream().map(FlowDifference::toString).collect(Collectors.joining("\n"));
                    LOG.error("Cannot change the Version of the flow for {} because the Process Group has been modified ({} modifications) " + "since it was last synchronized with the Flow Registry. The following differences were found:\n{}", this, modifications.size(), changes);
                    throw new IllegalStateException("Cannot change the Version of the flow for " + this + " because the Process Group has been modified (" + modifications.size() + " modifications) since it was last synchronized with the Flow Registry. The Process Group must be" + " reverted to its original form before changing the version.");
                }
            }
            verifyNoDescendantsWithLocalModifications("be updated");
        }
        final VersionedProcessGroup flowContents = updatedFlow.getFlowContents();
        if (verifyConnectionRemoval) {
            // Determine which Connections have been removed.
            final Map<String, Connection> removedConnectionByVersionedId = new HashMap<>();
            // Populate the 'removedConnectionByVersionId' map with all Connections. We key off of the connection's VersionedComponentID
            // if it is populated. Otherwise, we key off of its actual ID. We do this because it allows us to then remove from this Map
            // any connection that does exist in the proposed flow. This results in us having a Map whose values are those Connections
            // that were removed. We can then check for any connections that have data in them. If any Connection is to be removed but
            // has data, then we should throw an IllegalStateException.
            findAllConnections().stream().forEach(conn -> removedConnectionByVersionedId.put(conn.getVersionedComponentId().orElse(conn.getIdentifier()), conn));
            final Set<String> proposedFlowConnectionIds = new HashSet<>();
            findAllConnectionIds(flowContents, proposedFlowConnectionIds);
            for (final String proposedConnectionId : proposedFlowConnectionIds) {
                removedConnectionByVersionedId.remove(proposedConnectionId);
            }
            // If any connection that was removed has data in it, throw an IllegalStateException
            for (final Connection connection : removedConnectionByVersionedId.values()) {
                final FlowFileQueue flowFileQueue = connection.getFlowFileQueue();
                if (!flowFileQueue.isEmpty()) {
                    throw new IllegalStateException(this + " cannot be updated to the proposed version of the flow because the " + "proposed version does not contain " + connection + " and the connection currently has data in the queue.");
                }
            }
        }
        // Determine which input ports were removed from this process group
        final Map<String, Port> removedInputPortsByVersionId = new HashMap<>();
        getInputPorts().stream().filter(port -> port.getVersionedComponentId().isPresent()).forEach(port -> removedInputPortsByVersionId.put(port.getVersionedComponentId().get(), port));
        flowContents.getInputPorts().stream().map(VersionedPort::getIdentifier).forEach(id -> removedInputPortsByVersionId.remove(id));
        // Ensure that there are no incoming connections for any Input Port that was removed.
        for (final Port inputPort : removedInputPortsByVersionId.values()) {
            final List<Connection> incomingConnections = inputPort.getIncomingConnections();
            if (!incomingConnections.isEmpty()) {
                throw new IllegalStateException(this + " cannot be updated to the proposed version of the flow because the proposed version does not contain the Input Port " + inputPort + " and the Input Port currently has an incoming connections");
            }
        }
        // Determine which output ports were removed from this process group
        final Map<String, Port> removedOutputPortsByVersionId = new HashMap<>();
        getOutputPorts().stream().filter(port -> port.getVersionedComponentId().isPresent()).forEach(port -> removedOutputPortsByVersionId.put(port.getVersionedComponentId().get(), port));
        flowContents.getOutputPorts().stream().map(VersionedPort::getIdentifier).forEach(id -> removedOutputPortsByVersionId.remove(id));
        // Ensure that there are no outgoing connections for any Output Port that was removed.
        for (final Port outputPort : removedOutputPortsByVersionId.values()) {
            final Set<Connection> outgoingConnections = outputPort.getConnections();
            if (!outgoingConnections.isEmpty()) {
                throw new IllegalStateException(this + " cannot be updated to the proposed version of the flow because the proposed version does not contain the Output Port " + outputPort + " and the Output Port currently has an outgoing connections");
            }
        }
        // Find any Process Groups that may have been deleted. If we find any Process Group that was deleted, and that Process Group
        // has Templates, then we fail because the Templates have to be removed first.
        final Map<String, VersionedProcessGroup> proposedProcessGroups = new HashMap<>();
        findAllProcessGroups(updatedFlow.getFlowContents(), proposedProcessGroups);
        for (final ProcessGroup childGroup : findAllProcessGroups()) {
            if (childGroup.getTemplates().isEmpty()) {
                continue;
            }
            final Optional<String> versionedIdOption = childGroup.getVersionedComponentId();
            if (!versionedIdOption.isPresent()) {
                continue;
            }
            final String versionedId = versionedIdOption.get();
            if (!proposedProcessGroups.containsKey(versionedId)) {
                // Process Group was removed.
                throw new IllegalStateException(this + " cannot be updated to the proposed version of the flow because the child " + childGroup + " that exists locally has one or more Templates, and the proposed flow does not contain these templates. " + "A Process Group cannot be deleted while it contains Templates. Please remove the Templates before attempting to change the version of the flow.");
            }
        }
        // Ensure that all Processors are instantiate-able.
        final Map<String, VersionedProcessor> proposedProcessors = new HashMap<>();
        findAllProcessors(updatedFlow.getFlowContents(), proposedProcessors);
        findAllProcessors().stream().filter(proc -> proc.getVersionedComponentId().isPresent()).forEach(proc -> proposedProcessors.remove(proc.getVersionedComponentId().get()));
        for (final VersionedProcessor processorToAdd : proposedProcessors.values()) {
            final BundleCoordinate coordinate = toCoordinate(processorToAdd.getBundle());
            try {
                flowController.createProcessor(processorToAdd.getType(), UUID.randomUUID().toString(), coordinate, false);
            } catch (Exception e) {
                throw new IllegalArgumentException("Unable to create Processor of type " + processorToAdd.getType(), e);
            }
        }
        // Ensure that all Controller Services are instantiate-able.
        final Map<String, VersionedControllerService> proposedServices = new HashMap<>();
        findAllControllerServices(updatedFlow.getFlowContents(), proposedServices);
        findAllControllerServices().stream().filter(service -> service.getVersionedComponentId().isPresent()).forEach(service -> proposedServices.remove(service.getVersionedComponentId().get()));
        for (final VersionedControllerService serviceToAdd : proposedServices.values()) {
            final BundleCoordinate coordinate = toCoordinate(serviceToAdd.getBundle());
            try {
                flowController.createControllerService(serviceToAdd.getType(), UUID.randomUUID().toString(), coordinate, Collections.emptySet(), false);
            } catch (Exception e) {
                throw new IllegalArgumentException("Unable to create Controller Service of type " + serviceToAdd.getType(), e);
            }
        }
        // Ensure that all Prioritizers are instantiate-able.
        final Map<String, VersionedConnection> proposedConnections = new HashMap<>();
        findAllConnections(updatedFlow.getFlowContents(), proposedConnections);
        findAllConnections().stream().filter(conn -> conn.getVersionedComponentId().isPresent()).forEach(conn -> proposedConnections.remove(conn.getVersionedComponentId().get()));
        for (final VersionedConnection connectionToAdd : proposedConnections.values()) {
            if (connectionToAdd.getPrioritizers() != null) {
                for (final String prioritizerType : connectionToAdd.getPrioritizers()) {
                    try {
                        flowController.createPrioritizer(prioritizerType);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Unable to create Prioritizer of type " + prioritizerType, e);
                    }
                }
            }
        }
    } finally {
        readLock.unlock();
    }
}
Also used : OnRemoved(org.apache.nifi.annotation.lifecycle.OnRemoved) ConfigurationContext(org.apache.nifi.controller.ConfigurationContext) Size(org.apache.nifi.connectable.Size) FlowComparison(org.apache.nifi.registry.flow.diff.FlowComparison) StringUtils(org.apache.commons.lang3.StringUtils) ReflectionUtils(org.apache.nifi.util.ReflectionUtils) PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) SecureRandom(java.security.SecureRandom) NiFiRegistryException(org.apache.nifi.registry.client.NiFiRegistryException) ComponentType(org.apache.nifi.registry.flow.ComponentType) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) SnippetUtils(org.apache.nifi.util.SnippetUtils) Map(java.util.Map) HashCodeBuilder(org.apache.commons.lang3.builder.HashCodeBuilder) RootGroupPort(org.apache.nifi.remote.RootGroupPort) Connectable(org.apache.nifi.connectable.Connectable) Connection(org.apache.nifi.connectable.Connection) Bundle(org.apache.nifi.registry.flow.Bundle) FlowFilePrioritizer(org.apache.nifi.flowfile.FlowFilePrioritizer) FlowDifferenceFilters(org.apache.nifi.util.FlowDifferenceFilters) VersionedFlowStatus(org.apache.nifi.registry.flow.VersionedFlowStatus) Set(java.util.Set) VersionedFlowCoordinates(org.apache.nifi.registry.flow.VersionedFlowCoordinates) VersionedRemoteGroupPort(org.apache.nifi.registry.flow.VersionedRemoteGroupPort) FlowController(org.apache.nifi.controller.FlowController) StandardCharsets(java.nio.charset.StandardCharsets) StateManagerProvider(org.apache.nifi.components.state.StateManagerProvider) Position(org.apache.nifi.connectable.Position) ScheduledState(org.apache.nifi.controller.ScheduledState) ControllerService(org.apache.nifi.controller.ControllerService) ExtensionManager(org.apache.nifi.nar.ExtensionManager) StandardVersionControlInformation(org.apache.nifi.registry.flow.StandardVersionControlInformation) Resource(org.apache.nifi.authorization.Resource) FlowComparator(org.apache.nifi.registry.flow.diff.FlowComparator) StaticDifferenceDescriptor(org.apache.nifi.registry.flow.diff.StaticDifferenceDescriptor) StandardComparableDataFlow(org.apache.nifi.registry.flow.diff.StandardComparableDataFlow) SiteToSiteTransportProtocol(org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) ArrayList(java.util.ArrayList) Relationship(org.apache.nifi.processor.Relationship) ControllerServiceReference(org.apache.nifi.controller.service.ControllerServiceReference) ControllerServiceProvider(org.apache.nifi.controller.service.ControllerServiceProvider) VersionedLabel(org.apache.nifi.registry.flow.VersionedLabel) LinkedHashSet(java.util.LinkedHashSet) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState) EvolvingDifferenceDescriptor(org.apache.nifi.registry.flow.diff.EvolvingDifferenceDescriptor) ConfiguredComponent(org.apache.nifi.controller.ConfiguredComponent) Positionable(org.apache.nifi.connectable.Positionable) ExecutionNode(org.apache.nifi.scheduling.ExecutionNode) IOException(java.io.IOException) VersionedFlowSnapshot(org.apache.nifi.registry.flow.VersionedFlowSnapshot) NiFiRegistryFlowMapper(org.apache.nifi.registry.flow.mapping.NiFiRegistryFlowMapper) Lock(java.util.concurrent.locks.Lock) NiFiProperties(org.apache.nifi.util.NiFiProperties) VariableImpact(org.apache.nifi.attribute.expression.language.VariableImpact) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) ProcessorInstantiationException(org.apache.nifi.controller.exception.ProcessorInstantiationException) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) URL(java.net.URL) ConnectableType(org.apache.nifi.connectable.ConnectableType) ConnectableComponent(org.apache.nifi.registry.flow.ConnectableComponent) VariableDescriptor(org.apache.nifi.registry.VariableDescriptor) LoggerFactory(org.slf4j.LoggerFactory) Port(org.apache.nifi.connectable.Port) StandardFlowComparator(org.apache.nifi.registry.flow.diff.StandardFlowComparator) Query(org.apache.nifi.attribute.expression.language.Query) ResourceType(org.apache.nifi.authorization.resource.ResourceType) TemplateDTO(org.apache.nifi.web.api.dto.TemplateDTO) SchedulingStrategy(org.apache.nifi.scheduling.SchedulingStrategy) VersionedPort(org.apache.nifi.registry.flow.VersionedPort) VersionedRemoteProcessGroup(org.apache.nifi.registry.flow.VersionedRemoteProcessGroup) StandardProcessScheduler(org.apache.nifi.controller.scheduling.StandardProcessScheduler) VersionedComponent(org.apache.nifi.registry.flow.VersionedComponent) DifferenceType(org.apache.nifi.registry.flow.diff.DifferenceType) VersionedConnection(org.apache.nifi.registry.flow.VersionedConnection) Template(org.apache.nifi.controller.Template) Label(org.apache.nifi.controller.label.Label) FlowRegistryClient(org.apache.nifi.registry.flow.FlowRegistryClient) OnShutdown(org.apache.nifi.annotation.lifecycle.OnShutdown) MutableVariableRegistry(org.apache.nifi.registry.variable.MutableVariableRegistry) Authorizable(org.apache.nifi.authorization.resource.Authorizable) UUID(java.util.UUID) ComponentLifeCycleException(org.apache.nifi.controller.exception.ComponentLifeCycleException) Snippet(org.apache.nifi.controller.Snippet) Collectors(java.util.stream.Collectors) ResourceFactory(org.apache.nifi.authorization.resource.ResourceFactory) Objects(java.util.Objects) List(java.util.List) BatchSize(org.apache.nifi.registry.flow.BatchSize) VersionedFunnel(org.apache.nifi.registry.flow.VersionedFunnel) ToStringBuilder(org.apache.commons.lang3.builder.ToStringBuilder) VersionControlInformation(org.apache.nifi.registry.flow.VersionControlInformation) Optional(java.util.Optional) LocalPort(org.apache.nifi.connectable.LocalPort) StandardProcessContext(org.apache.nifi.processor.StandardProcessContext) ProcessorNode(org.apache.nifi.controller.ProcessorNode) Revision(org.apache.nifi.web.Revision) Funnel(org.apache.nifi.connectable.Funnel) ControllerServiceNode(org.apache.nifi.controller.service.ControllerServiceNode) ToStringStyle(org.apache.commons.lang3.builder.ToStringStyle) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) FlowRegistry(org.apache.nifi.registry.flow.FlowRegistry) HashSet(java.util.HashSet) StringEncryptor(org.apache.nifi.encrypt.StringEncryptor) ComparableDataFlow(org.apache.nifi.registry.flow.diff.ComparableDataFlow) Objects.requireNonNull(java.util.Objects.requireNonNull) StandardConfigurationContext(org.apache.nifi.controller.service.StandardConfigurationContext) NarCloseable(org.apache.nifi.nar.NarCloseable) LogLevel(org.apache.nifi.logging.LogLevel) VersionedProcessor(org.apache.nifi.registry.flow.VersionedProcessor) Logger(org.slf4j.Logger) StateManager(org.apache.nifi.components.state.StateManager) RemoteGroupPort(org.apache.nifi.remote.RemoteGroupPort) StandardRemoteProcessGroupPortDescriptor(org.apache.nifi.remote.StandardRemoteProcessGroupPortDescriptor) VersionedFlow(org.apache.nifi.registry.flow.VersionedFlow) VersionedControllerService(org.apache.nifi.registry.flow.VersionedControllerService) TimeUnit(java.util.concurrent.TimeUnit) ComponentVariableRegistry(org.apache.nifi.registry.ComponentVariableRegistry) FlowDifference(org.apache.nifi.registry.flow.diff.FlowDifference) VersionedPropertyDescriptor(org.apache.nifi.registry.flow.VersionedPropertyDescriptor) Collections(java.util.Collections) LogRepositoryFactory(org.apache.nifi.logging.LogRepositoryFactory) HashMap(java.util.HashMap) RootGroupPort(org.apache.nifi.remote.RootGroupPort) VersionedRemoteGroupPort(org.apache.nifi.registry.flow.VersionedRemoteGroupPort) Port(org.apache.nifi.connectable.Port) VersionedPort(org.apache.nifi.registry.flow.VersionedPort) LocalPort(org.apache.nifi.connectable.LocalPort) RemoteGroupPort(org.apache.nifi.remote.RemoteGroupPort) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) FlowFileQueue(org.apache.nifi.controller.queue.FlowFileQueue) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) VersionedFlowState(org.apache.nifi.registry.flow.VersionedFlowState) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) Connection(org.apache.nifi.connectable.Connection) VersionedConnection(org.apache.nifi.registry.flow.VersionedConnection) VersionedControllerService(org.apache.nifi.registry.flow.VersionedControllerService) NiFiRegistryException(org.apache.nifi.registry.client.NiFiRegistryException) IOException(java.io.IOException) ProcessorInstantiationException(org.apache.nifi.controller.exception.ProcessorInstantiationException) ComponentLifeCycleException(org.apache.nifi.controller.exception.ComponentLifeCycleException) FlowDifference(org.apache.nifi.registry.flow.diff.FlowDifference) StandardVersionControlInformation(org.apache.nifi.registry.flow.StandardVersionControlInformation) VersionControlInformation(org.apache.nifi.registry.flow.VersionControlInformation) VersionedProcessGroup(org.apache.nifi.registry.flow.VersionedProcessGroup) VersionedRemoteProcessGroup(org.apache.nifi.registry.flow.VersionedRemoteProcessGroup) VersionedConnection(org.apache.nifi.registry.flow.VersionedConnection) VersionedProcessor(org.apache.nifi.registry.flow.VersionedProcessor)

Aggregations

VersionedFlowState (org.apache.nifi.registry.flow.VersionedFlowState)9 StandardVersionControlInformation (org.apache.nifi.registry.flow.StandardVersionControlInformation)5 VersionControlInformation (org.apache.nifi.registry.flow.VersionControlInformation)5 Authorizable (org.apache.nifi.authorization.resource.Authorizable)4 VersionedFlow (org.apache.nifi.registry.flow.VersionedFlow)4 VersionedFlowSnapshot (org.apache.nifi.registry.flow.VersionedFlowSnapshot)4 VersionedProcessGroup (org.apache.nifi.registry.flow.VersionedProcessGroup)4 VersionedRemoteProcessGroup (org.apache.nifi.registry.flow.VersionedRemoteProcessGroup)4 Revision (org.apache.nifi.web.Revision)4 FlowRegistry (org.apache.nifi.registry.flow.FlowRegistry)3 VersionedFlowStatus (org.apache.nifi.registry.flow.VersionedFlowStatus)3 FlowDifference (org.apache.nifi.registry.flow.diff.FlowDifference)3 IOException (java.io.IOException)2 URL (java.net.URL)2 StandardCharsets (java.nio.charset.StandardCharsets)2 SecureRandom (java.security.SecureRandom)2 ArrayList (java.util.ArrayList)2 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2