use of org.apache.nifi.registry.flow.StandardVersionControlInformation in project nifi by apache.
the class StandardFlowSynchronizer method addProcessGroup.
private ProcessGroup addProcessGroup(final FlowController controller, final ProcessGroup parentGroup, final Element processGroupElement, final StringEncryptor encryptor, final FlowEncodingVersion encodingVersion) throws ProcessorInstantiationException {
// get the parent group ID
final String parentId = (parentGroup == null) ? null : parentGroup.getIdentifier();
// add the process group
final ProcessGroupDTO processGroupDTO = FlowFromDOMFactory.getProcessGroup(parentId, processGroupElement, encryptor, encodingVersion);
final ProcessGroup processGroup = controller.createProcessGroup(processGroupDTO.getId());
processGroup.setComments(processGroupDTO.getComments());
processGroup.setVersionedComponentId(processGroupDTO.getVersionedComponentId());
processGroup.setPosition(toPosition(processGroupDTO.getPosition()));
processGroup.setName(processGroupDTO.getName());
processGroup.setParent(parentGroup);
if (parentGroup == null) {
controller.setRootGroup(processGroup);
} else {
parentGroup.addProcessGroup(processGroup);
}
// Set the variables for the variable registry
final Map<String, String> variables = new HashMap<>();
final List<Element> variableElements = getChildrenByTagName(processGroupElement, "variable");
for (final Element variableElement : variableElements) {
final String variableName = variableElement.getAttribute("name");
final String variableValue = variableElement.getAttribute("value");
if (variableName == null || variableValue == null) {
continue;
}
variables.put(variableName, variableValue);
}
processGroup.setVariables(variables);
final VersionControlInformationDTO versionControlInfoDto = processGroupDTO.getVersionControlInformation();
if (versionControlInfoDto != null) {
final FlowRegistry flowRegistry = controller.getFlowRegistryClient().getFlowRegistry(versionControlInfoDto.getRegistryId());
final String registryName = flowRegistry == null ? versionControlInfoDto.getRegistryId() : flowRegistry.getName();
versionControlInfoDto.setState(VersionedFlowState.SYNC_FAILURE.name());
versionControlInfoDto.setStateExplanation("Process Group has not yet been synchronized with the Flow Registry");
final StandardVersionControlInformation versionControlInformation = StandardVersionControlInformation.Builder.fromDto(versionControlInfoDto).registryName(registryName).build();
// pass empty map for the version control mapping because the VersionedComponentId has already been set on the components
processGroup.setVersionControlInformation(versionControlInformation, Collections.emptyMap());
}
// Add Controller Services
final List<Element> serviceNodeList = getChildrenByTagName(processGroupElement, "controllerService");
if (!serviceNodeList.isEmpty()) {
final Map<ControllerServiceNode, Element> controllerServices = ControllerServiceLoader.loadControllerServices(serviceNodeList, controller, processGroup, encryptor);
ControllerServiceLoader.enableControllerServices(controllerServices, controller, encryptor, autoResumeState);
}
// add processors
final List<Element> processorNodeList = getChildrenByTagName(processGroupElement, "processor");
for (final Element processorElement : processorNodeList) {
final ProcessorDTO processorDTO = FlowFromDOMFactory.getProcessor(processorElement, encryptor);
BundleCoordinate coordinate;
try {
coordinate = BundleUtils.getCompatibleBundle(processorDTO.getType(), processorDTO.getBundle());
} catch (final IllegalStateException e) {
final BundleDTO bundleDTO = processorDTO.getBundle();
if (bundleDTO == null) {
coordinate = BundleCoordinate.UNKNOWN_COORDINATE;
} else {
coordinate = new BundleCoordinate(bundleDTO.getGroup(), bundleDTO.getArtifact(), bundleDTO.getVersion());
}
}
final ProcessorNode procNode = controller.createProcessor(processorDTO.getType(), processorDTO.getId(), coordinate, false);
procNode.setVersionedComponentId(processorDTO.getVersionedComponentId());
processGroup.addProcessor(procNode);
updateProcessor(procNode, processorDTO, processGroup, controller);
}
// add input ports
final List<Element> inputPortNodeList = getChildrenByTagName(processGroupElement, "inputPort");
for (final Element inputPortElement : inputPortNodeList) {
final PortDTO portDTO = FlowFromDOMFactory.getPort(inputPortElement);
final Port port;
if (processGroup.isRootGroup()) {
port = controller.createRemoteInputPort(portDTO.getId(), portDTO.getName());
} else {
port = controller.createLocalInputPort(portDTO.getId(), portDTO.getName());
}
port.setVersionedComponentId(portDTO.getVersionedComponentId());
port.setPosition(toPosition(portDTO.getPosition()));
port.setComments(portDTO.getComments());
port.setProcessGroup(processGroup);
final Set<String> userControls = portDTO.getUserAccessControl();
if (userControls != null && !userControls.isEmpty()) {
if (!(port instanceof RootGroupPort)) {
throw new IllegalStateException("Attempting to add User Access Controls to " + port.getIdentifier() + ", but it is not a RootGroupPort");
}
((RootGroupPort) port).setUserAccessControl(userControls);
}
final Set<String> groupControls = portDTO.getGroupAccessControl();
if (groupControls != null && !groupControls.isEmpty()) {
if (!(port instanceof RootGroupPort)) {
throw new IllegalStateException("Attempting to add Group Access Controls to " + port.getIdentifier() + ", but it is not a RootGroupPort");
}
((RootGroupPort) port).setGroupAccessControl(groupControls);
}
processGroup.addInputPort(port);
if (portDTO.getConcurrentlySchedulableTaskCount() != null) {
port.setMaxConcurrentTasks(portDTO.getConcurrentlySchedulableTaskCount());
}
final ScheduledState scheduledState = ScheduledState.valueOf(portDTO.getState());
if (ScheduledState.RUNNING.equals(scheduledState)) {
controller.startConnectable(port);
} else if (ScheduledState.DISABLED.equals(scheduledState)) {
processGroup.disableInputPort(port);
}
}
// add output ports
final List<Element> outputPortNodeList = getChildrenByTagName(processGroupElement, "outputPort");
for (final Element outputPortElement : outputPortNodeList) {
final PortDTO portDTO = FlowFromDOMFactory.getPort(outputPortElement);
final Port port;
if (processGroup.isRootGroup()) {
port = controller.createRemoteOutputPort(portDTO.getId(), portDTO.getName());
} else {
port = controller.createLocalOutputPort(portDTO.getId(), portDTO.getName());
}
port.setVersionedComponentId(portDTO.getVersionedComponentId());
port.setPosition(toPosition(portDTO.getPosition()));
port.setComments(portDTO.getComments());
port.setProcessGroup(processGroup);
final Set<String> userControls = portDTO.getUserAccessControl();
if (userControls != null && !userControls.isEmpty()) {
if (!(port instanceof RootGroupPort)) {
throw new IllegalStateException("Attempting to add User Access Controls to " + port.getIdentifier() + ", but it is not a RootGroupPort");
}
((RootGroupPort) port).setUserAccessControl(userControls);
}
final Set<String> groupControls = portDTO.getGroupAccessControl();
if (groupControls != null && !groupControls.isEmpty()) {
if (!(port instanceof RootGroupPort)) {
throw new IllegalStateException("Attempting to add Group Access Controls to " + port.getIdentifier() + ", but it is not a RootGroupPort");
}
((RootGroupPort) port).setGroupAccessControl(groupControls);
}
processGroup.addOutputPort(port);
if (portDTO.getConcurrentlySchedulableTaskCount() != null) {
port.setMaxConcurrentTasks(portDTO.getConcurrentlySchedulableTaskCount());
}
final ScheduledState scheduledState = ScheduledState.valueOf(portDTO.getState());
if (ScheduledState.RUNNING.equals(scheduledState)) {
controller.startConnectable(port);
} else if (ScheduledState.DISABLED.equals(scheduledState)) {
processGroup.disableOutputPort(port);
}
}
// add funnels
final List<Element> funnelNodeList = getChildrenByTagName(processGroupElement, "funnel");
for (final Element funnelElement : funnelNodeList) {
final FunnelDTO funnelDTO = FlowFromDOMFactory.getFunnel(funnelElement);
final Funnel funnel = controller.createFunnel(funnelDTO.getId());
funnel.setVersionedComponentId(funnelDTO.getVersionedComponentId());
funnel.setPosition(toPosition(funnelDTO.getPosition()));
// Since this is called during startup, we want to add the funnel without enabling it
// and then tell the controller to enable it. This way, if the controller is not fully
// initialized, the starting of the funnel is delayed until the controller is ready.
processGroup.addFunnel(funnel, false);
controller.startConnectable(funnel);
}
// add labels
final List<Element> labelNodeList = getChildrenByTagName(processGroupElement, "label");
for (final Element labelElement : labelNodeList) {
final LabelDTO labelDTO = FlowFromDOMFactory.getLabel(labelElement);
final Label label = controller.createLabel(labelDTO.getId(), labelDTO.getLabel());
label.setVersionedComponentId(labelDTO.getVersionedComponentId());
label.setStyle(labelDTO.getStyle());
label.setPosition(toPosition(labelDTO.getPosition()));
label.setSize(new Size(labelDTO.getWidth(), labelDTO.getHeight()));
processGroup.addLabel(label);
}
// add nested process groups (recursively)
final List<Element> nestedProcessGroupNodeList = getChildrenByTagName(processGroupElement, "processGroup");
for (final Element nestedProcessGroupElement : nestedProcessGroupNodeList) {
addProcessGroup(controller, processGroup, nestedProcessGroupElement, encryptor, encodingVersion);
}
// add remote process group
final List<Element> remoteProcessGroupNodeList = getChildrenByTagName(processGroupElement, "remoteProcessGroup");
for (final Element remoteProcessGroupElement : remoteProcessGroupNodeList) {
final RemoteProcessGroupDTO remoteGroupDto = FlowFromDOMFactory.getRemoteProcessGroup(remoteProcessGroupElement, encryptor);
final RemoteProcessGroup remoteGroup = controller.createRemoteProcessGroup(remoteGroupDto.getId(), remoteGroupDto.getTargetUris());
remoteGroup.setVersionedComponentId(remoteGroupDto.getVersionedComponentId());
remoteGroup.setComments(remoteGroupDto.getComments());
remoteGroup.setPosition(toPosition(remoteGroupDto.getPosition()));
final String name = remoteGroupDto.getName();
if (name != null && !name.trim().isEmpty()) {
remoteGroup.setName(name);
}
remoteGroup.setProcessGroup(processGroup);
remoteGroup.setCommunicationsTimeout(remoteGroupDto.getCommunicationsTimeout());
if (remoteGroupDto.getYieldDuration() != null) {
remoteGroup.setYieldDuration(remoteGroupDto.getYieldDuration());
}
final String transportProtocol = remoteGroupDto.getTransportProtocol();
if (transportProtocol != null && !transportProtocol.trim().isEmpty()) {
remoteGroup.setTransportProtocol(SiteToSiteTransportProtocol.valueOf(transportProtocol.toUpperCase()));
}
if (remoteGroupDto.getProxyHost() != null) {
remoteGroup.setProxyHost(remoteGroupDto.getProxyHost());
}
if (remoteGroupDto.getProxyPort() != null) {
remoteGroup.setProxyPort(remoteGroupDto.getProxyPort());
}
if (remoteGroupDto.getProxyUser() != null) {
remoteGroup.setProxyUser(remoteGroupDto.getProxyUser());
}
if (remoteGroupDto.getProxyPassword() != null) {
remoteGroup.setProxyPassword(remoteGroupDto.getProxyPassword());
}
if (StringUtils.isBlank(remoteGroupDto.getLocalNetworkInterface())) {
remoteGroup.setNetworkInterface(null);
} else {
remoteGroup.setNetworkInterface(remoteGroupDto.getLocalNetworkInterface());
}
final Set<RemoteProcessGroupPortDescriptor> inputPorts = new HashSet<>();
for (final Element portElement : getChildrenByTagName(remoteProcessGroupElement, "inputPort")) {
inputPorts.add(FlowFromDOMFactory.getRemoteProcessGroupPort(portElement));
}
remoteGroup.setInputPorts(inputPorts, false);
final Set<RemoteProcessGroupPortDescriptor> outputPorts = new HashSet<>();
for (final Element portElement : getChildrenByTagName(remoteProcessGroupElement, "outputPort")) {
outputPorts.add(FlowFromDOMFactory.getRemoteProcessGroupPort(portElement));
}
remoteGroup.setOutputPorts(outputPorts, false);
processGroup.addRemoteProcessGroup(remoteGroup);
for (final RemoteProcessGroupPortDescriptor remoteGroupPortDTO : outputPorts) {
final RemoteGroupPort port = remoteGroup.getOutputPort(remoteGroupPortDTO.getId());
if (Boolean.TRUE.equals(remoteGroupPortDTO.isTransmitting())) {
controller.startTransmitting(port);
}
}
for (final RemoteProcessGroupPortDescriptor remoteGroupPortDTO : inputPorts) {
final RemoteGroupPort port = remoteGroup.getInputPort(remoteGroupPortDTO.getId());
if (Boolean.TRUE.equals(remoteGroupPortDTO.isTransmitting())) {
controller.startTransmitting(port);
}
}
}
// add connections
final List<Element> connectionNodeList = getChildrenByTagName(processGroupElement, "connection");
for (final Element connectionElement : connectionNodeList) {
final ConnectionDTO dto = FlowFromDOMFactory.getConnection(connectionElement);
final Connectable source;
final ConnectableDTO sourceDto = dto.getSource();
if (ConnectableType.REMOTE_OUTPUT_PORT.name().equals(sourceDto.getType())) {
final RemoteProcessGroup remoteGroup = processGroup.getRemoteProcessGroup(sourceDto.getGroupId());
source = remoteGroup.getOutputPort(sourceDto.getId());
} else {
final ProcessGroup sourceGroup = controller.getGroup(sourceDto.getGroupId());
if (sourceGroup == null) {
throw new RuntimeException("Found Invalid ProcessGroup ID for Source: " + dto.getSource().getGroupId());
}
source = sourceGroup.getConnectable(sourceDto.getId());
}
if (source == null) {
throw new RuntimeException("Found Invalid Connectable ID for Source: " + dto.getSource().getId());
}
final Connectable destination;
final ConnectableDTO destinationDto = dto.getDestination();
if (ConnectableType.REMOTE_INPUT_PORT.name().equals(destinationDto.getType())) {
final RemoteProcessGroup remoteGroup = processGroup.getRemoteProcessGroup(destinationDto.getGroupId());
destination = remoteGroup.getInputPort(destinationDto.getId());
} else {
final ProcessGroup destinationGroup = controller.getGroup(destinationDto.getGroupId());
if (destinationGroup == null) {
throw new RuntimeException("Found Invalid ProcessGroup ID for Destination: " + dto.getDestination().getGroupId());
}
destination = destinationGroup.getConnectable(destinationDto.getId());
}
if (destination == null) {
throw new RuntimeException("Found Invalid Connectable ID for Destination: " + dto.getDestination().getId());
}
final Connection connection = controller.createConnection(dto.getId(), dto.getName(), source, destination, dto.getSelectedRelationships());
connection.setVersionedComponentId(dto.getVersionedComponentId());
connection.setProcessGroup(processGroup);
final List<Position> bendPoints = new ArrayList<>();
for (final PositionDTO bend : dto.getBends()) {
bendPoints.add(new Position(bend.getX(), bend.getY()));
}
connection.setBendPoints(bendPoints);
final Long zIndex = dto.getzIndex();
if (zIndex != null) {
connection.setZIndex(zIndex);
}
if (dto.getLabelIndex() != null) {
connection.setLabelIndex(dto.getLabelIndex());
}
List<FlowFilePrioritizer> newPrioritizers = null;
final List<String> prioritizers = dto.getPrioritizers();
if (prioritizers != null) {
final List<String> newPrioritizersClasses = new ArrayList<>(prioritizers);
newPrioritizers = new ArrayList<>();
for (final String className : newPrioritizersClasses) {
try {
newPrioritizers.add(controller.createPrioritizer(className));
} catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException("Unable to set prioritizer " + className + ": " + e);
}
}
}
if (newPrioritizers != null) {
connection.getFlowFileQueue().setPriorities(newPrioritizers);
}
if (dto.getBackPressureObjectThreshold() != null) {
connection.getFlowFileQueue().setBackPressureObjectThreshold(dto.getBackPressureObjectThreshold());
}
if (dto.getBackPressureDataSizeThreshold() != null) {
connection.getFlowFileQueue().setBackPressureDataSizeThreshold(dto.getBackPressureDataSizeThreshold());
}
if (dto.getFlowFileExpiration() != null) {
connection.getFlowFileQueue().setFlowFileExpiration(dto.getFlowFileExpiration());
}
processGroup.addConnection(connection);
}
final List<Element> templateNodeList = getChildrenByTagName(processGroupElement, "template");
for (final Element templateNode : templateNodeList) {
final TemplateDTO templateDTO = TemplateUtils.parseDto(templateNode);
final Template template = new Template(templateDTO);
processGroup.addTemplate(template);
}
return processGroup;
}
use of org.apache.nifi.registry.flow.StandardVersionControlInformation in project nifi by apache.
the class StandardProcessGroup method verifyCanRevertLocalModifications.
@Override
public void verifyCanRevertLocalModifications() {
final StandardVersionControlInformation svci = versionControlInfo.get();
if (svci == null) {
throw new IllegalStateException("Cannot revert local modifications to Process Group because the Process Group is not under Version Control.");
}
verifyNoDescendantsWithLocalModifications("have its local modifications reverted");
}
use of org.apache.nifi.registry.flow.StandardVersionControlInformation in project nifi by apache.
the class StandardProcessGroup method getModifications.
private Set<FlowDifference> getModifications() {
final StandardVersionControlInformation vci = versionControlInfo.get();
// So we have to perform a diff of the flows and see if they are the same.
if (vci == null) {
return null;
}
if (vci.getFlowSnapshot() == null) {
// As a result, we will just return an empty optional
return null;
}
final NiFiRegistryFlowMapper mapper = new NiFiRegistryFlowMapper();
final VersionedProcessGroup versionedGroup = mapper.mapProcessGroup(this, controllerServiceProvider, flowController.getFlowRegistryClient(), false);
final ComparableDataFlow currentFlow = new StandardComparableDataFlow("Local Flow", versionedGroup);
final ComparableDataFlow snapshotFlow = new StandardComparableDataFlow("Versioned Flow", vci.getFlowSnapshot());
final FlowComparator flowComparator = new StandardFlowComparator(snapshotFlow, currentFlow, getAncestorGroupServiceIds(), new EvolvingDifferenceDescriptor());
final FlowComparison comparison = flowComparator.compare();
final Set<FlowDifference> differences = comparison.getDifferences().stream().filter(difference -> difference.getDifferenceType() != DifferenceType.BUNDLE_CHANGED).filter(FlowDifferenceFilters.FILTER_ADDED_REMOVED_REMOTE_PORTS).collect(Collectors.toCollection(HashSet::new));
LOG.debug("There are {} differences between this Local Flow and the Versioned Flow: {}", differences.size(), differences);
return differences;
}
use of org.apache.nifi.registry.flow.StandardVersionControlInformation in project nifi by apache.
the class StandardProcessGroup method verifyCanSaveToFlowRegistry.
@Override
public void verifyCanSaveToFlowRegistry(final String registryId, final String bucketId, final String flowId) {
verifyNoDescendantsWithLocalModifications("be saved to a Flow Registry");
final StandardVersionControlInformation vci = versionControlInfo.get();
if (vci != null) {
if (flowId != null && flowId.equals(vci.getFlowIdentifier())) {
// Flow ID is the same. We want to publish the Process Group as the next version of the Flow.
// In order to do this, we have to ensure that the Process Group is 'current'.
final VersionedFlowState state = vci.getStatus().getState();
if (state == VersionedFlowState.STALE || state == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE) {
throw new IllegalStateException("Cannot update Version Control Information for Process Group with ID " + getIdentifier() + " because the Process Group in the flow is not synchronized with the most recent version of the Flow in the Flow Registry. " + "In order to publish a new version of the Flow, the Process Group must first be in synch with the latest version in the Flow Registry.");
}
// ensure that all other parameters match as well.
if (!bucketId.equals(vci.getBucketIdentifier())) {
throw new IllegalStateException("Cannot update Version Control Information for Process Group with ID " + getIdentifier() + " because the Process Group is currently synchronized with a different Versioned Flow than the one specified in the request.");
}
if (!registryId.equals(vci.getRegistryIdentifier())) {
throw new IllegalStateException("Cannot update Version Control Information for Process Group with ID " + getIdentifier() + " because the Process Group is currently synchronized with a different Versioned Flow than the one specified in the request.");
}
} else if (flowId != null) {
// can be done.
throw new IllegalStateException("Cannot update Version Control Information for Process Group with ID " + getIdentifier() + " because the Process Group is currently synchronized with a different Versioned Flow than the one specified in the request.");
}
}
}
use of org.apache.nifi.registry.flow.StandardVersionControlInformation in project nifi by apache.
the class StandardProcessGroup method onComponentModified.
@Override
public void onComponentModified() {
// We no longer know if or how the Process Group has changed, so the next time that we
// get the local modifications, we must re-calculate it. We cannot simply assume that
// the flow was modified now, because if a Processor Property changed from 'A' to 'B',
// then back to 'A', then we have to know that it was not modified. So we set it to null
// to indicate that we must calculate the local modifications.
final StandardVersionControlInformation svci = this.versionControlInfo.get();
if (svci == null) {
// This group is not under version control directly. Notify parent.
final ProcessGroup parentGroup = parent.get();
if (parentGroup != null) {
parentGroup.onComponentModified();
}
}
versionControlFields.setFlowDifferences(null);
}
Aggregations