mirror of https://github.com/apache/nifi.git
NIFI-4436: Removed isCurrent, isModified from VersionControlInformation and associated DTO. Bug fixes & code refactoring
Signed-off-by: Matt Gilman <matt.c.gilman@gmail.com>
This commit is contained in:
parent
db2cc9fec1
commit
fe8b30bf26
|
@ -32,8 +32,6 @@ public class VersionControlInformationDTO {
|
||||||
private String flowName;
|
private String flowName;
|
||||||
private String flowDescription;
|
private String flowDescription;
|
||||||
private Integer version;
|
private Integer version;
|
||||||
private Boolean modified;
|
|
||||||
private Boolean current;
|
|
||||||
private String state;
|
private String state;
|
||||||
private String stateExplanation;
|
private String stateExplanation;
|
||||||
|
|
||||||
|
@ -118,26 +116,6 @@ public class VersionControlInformationDTO {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiModelProperty(readOnly=true,
|
|
||||||
value = "Whether or not the flow has been modified since it was last synced to the Flow Registry. The value will be null if this information is not yet known.")
|
|
||||||
public Boolean getModified() {
|
|
||||||
return modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModified(Boolean modified) {
|
|
||||||
this.modified = modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiModelProperty(readOnly=true,
|
|
||||||
value = "Whether or not this is the most recent version of the flow in the Flow Registry. The value will be null if this information is not yet known.")
|
|
||||||
public Boolean getCurrent() {
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrent(Boolean current) {
|
|
||||||
this.current = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiModelProperty(readOnly = true,
|
@ApiModelProperty(readOnly = true,
|
||||||
value = "The current state of the Process Group, as it relates to the Versioned Flow",
|
value = "The current state of the Process Group, as it relates to the Versioned Flow",
|
||||||
allowableValues = "LOCALLY_MODIFIED_DESCENDANT, LOCALLY_MODIFIED, STALE, LOCALLY_MODIFIED_AND_STALE, UP_TO_DATE")
|
allowableValues = "LOCALLY_MODIFIED_DESCENDANT, LOCALLY_MODIFIED, STALE, LOCALLY_MODIFIED_AND_STALE, UP_TO_DATE")
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class ProcessGroupEntityMerger implements ComponentEntityMerger<ProcessGr
|
||||||
if (targetVersionControl == null) {
|
if (targetVersionControl == null) {
|
||||||
targetGroupDto.setVersionControlInformation(toMergeGroupDto.getVersionControlInformation());
|
targetGroupDto.setVersionControlInformation(toMergeGroupDto.getVersionControlInformation());
|
||||||
} else if (toMergeVersionControl != null) {
|
} else if (toMergeVersionControl != null) {
|
||||||
targetVersionControl.setCurrent(Boolean.TRUE.equals(targetVersionControl.getCurrent()) && Boolean.TRUE.equals(toMergeVersionControl.getCurrent()));
|
VersionControlInformationEntityMerger.updateFlowState(targetVersionControl, toMergeVersionControl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.nifi.cluster.manager;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.nifi.cluster.protocol.NodeIdentifier;
|
import org.apache.nifi.cluster.protocol.NodeIdentifier;
|
||||||
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
|
import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
|
||||||
import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
|
import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
|
||||||
|
|
||||||
|
@ -37,12 +38,54 @@ public class VersionControlInformationEntityMerger {
|
||||||
.forEach(entity -> {
|
.forEach(entity -> {
|
||||||
final VersionControlInformationDTO dto = entity.getVersionControlInformation();
|
final VersionControlInformationDTO dto = entity.getVersionControlInformation();
|
||||||
|
|
||||||
// We consider the flow to be current only if ALL nodes indicate that it is current
|
updateFlowState(clientDto, dto);
|
||||||
clientDto.setCurrent(Boolean.TRUE.equals(clientDto.getCurrent()) && Boolean.TRUE.equals(dto.getCurrent()));
|
|
||||||
|
|
||||||
// We consider the flow to be modified if ANY node indicates that it is modified
|
|
||||||
clientDto.setModified(Boolean.TRUE.equals(clientDto.getModified()) || Boolean.TRUE.equals(dto.getModified()));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isCurrent(final VersionedFlowState state) {
|
||||||
|
return state == VersionedFlowState.UP_TO_DATE || state == VersionedFlowState.LOCALLY_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isModified(final VersionedFlowState state) {
|
||||||
|
return state == VersionedFlowState.LOCALLY_MODIFIED || state == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateFlowState(final VersionControlInformationDTO clientDto, final VersionControlInformationDTO dto) {
|
||||||
|
final VersionedFlowState clientState = VersionedFlowState.valueOf(clientDto.getState());
|
||||||
|
if (clientState == VersionedFlowState.SYNC_FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final VersionedFlowState dtoState = VersionedFlowState.valueOf(dto.getState());
|
||||||
|
if (dtoState == VersionedFlowState.SYNC_FAILURE) {
|
||||||
|
clientDto.setState(dto.getState());
|
||||||
|
clientDto.setStateExplanation(dto.getStateExplanation());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean clientCurrent = isCurrent(clientState);
|
||||||
|
final boolean clientModified = isModified(clientState);
|
||||||
|
|
||||||
|
final boolean dtoCurrent = isCurrent(dtoState);
|
||||||
|
final boolean dtoModified = isModified(dtoState);
|
||||||
|
|
||||||
|
final boolean current = clientCurrent && dtoCurrent;
|
||||||
|
final boolean stale = !current;
|
||||||
|
final boolean modified = clientModified && dtoModified;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
clientDto.setState(flowState.name());
|
||||||
|
clientDto.setStateExplanation(flowState.getDescription());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,17 +65,6 @@ public interface VersionControlInformation {
|
||||||
*/
|
*/
|
||||||
int getVersion();
|
int getVersion();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if the flow has been modified since the last time that it was updated from the Flow Registry or saved
|
|
||||||
* to the Flow Registry; <code>false</code> if the flow is in sync with the Flow Registry.
|
|
||||||
*/
|
|
||||||
boolean isModified();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if this version of the flow is the most recent version of the flow available in the Flow Registry, <code>false</code> otherwise.
|
|
||||||
*/
|
|
||||||
boolean isCurrent();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the current status of the Process Group as it relates to the associated Versioned Flow.
|
* @return the current status of the Process Group as it relates to the associated Versioned Flow.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,31 +22,42 @@ public enum VersionedFlowState {
|
||||||
/**
|
/**
|
||||||
* We are unable to communicate with the Flow Registry in order to determine the appropriate state
|
* We are unable to communicate with the Flow Registry in order to determine the appropriate state
|
||||||
*/
|
*/
|
||||||
SYNC_FAILURE,
|
SYNC_FAILURE("Failed to communicate with Flow Registry"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Process Group (or a child/descendant Process Group that is not itself under Version Control)
|
* This Process Group (or a child/descendant Process Group that is not itself under Version Control)
|
||||||
* is on the latest version of the Versioned Flow, but is different than the Versioned Flow that is
|
* is on the latest version of the Versioned Flow, but is different than the Versioned Flow that is
|
||||||
* stored in the Flow Registry.
|
* stored in the Flow Registry.
|
||||||
*/
|
*/
|
||||||
LOCALLY_MODIFIED,
|
LOCALLY_MODIFIED("Local changes have been made"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Process Group has not been modified since it was last synchronized with the Flow Registry, but
|
* This Process Group has not been modified since it was last synchronized with the Flow Registry, but
|
||||||
* the Flow Registry has a newer version of the flow than what is contained in this Process Group.
|
* the Flow Registry has a newer version of the flow than what is contained in this Process Group.
|
||||||
*/
|
*/
|
||||||
STALE,
|
STALE("A newer version of this flow is available"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Process Group (or a child/descendant Process Group that is not itself under Version Control)
|
* This Process Group (or a child/descendant Process Group that is not itself under Version Control)
|
||||||
* has been modified since it was last synchronized with the Flow Registry, and the Flow Registry has
|
* has been modified since it was last synchronized with the Flow Registry, and the Flow Registry has
|
||||||
* a newer version of the flow than what is contained in this Process Group.
|
* a newer version of the flow than what is contained in this Process Group.
|
||||||
*/
|
*/
|
||||||
LOCALLY_MODIFIED_AND_STALE,
|
LOCALLY_MODIFIED_AND_STALE("Local changes have been made and a newer version of this flow is available"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Process Group and all child/descendant Process Groups are on the latest version of the flow in
|
* This Process Group and all child/descendant Process Groups are on the latest version of the flow in
|
||||||
* the Flow Registry and have no local modifications.
|
* the Flow Registry and have no local modifications.
|
||||||
*/
|
*/
|
||||||
UP_TO_DATE;
|
UP_TO_DATE("Flow version is current");
|
||||||
|
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
private VersionedFlowState(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ import org.apache.nifi.processor.SimpleProcessLogger;
|
||||||
import org.apache.nifi.registry.flow.FlowRegistry;
|
import org.apache.nifi.registry.flow.FlowRegistry;
|
||||||
import org.apache.nifi.registry.flow.FlowRegistryClient;
|
import org.apache.nifi.registry.flow.FlowRegistryClient;
|
||||||
import org.apache.nifi.registry.flow.StandardVersionControlInformation;
|
import org.apache.nifi.registry.flow.StandardVersionControlInformation;
|
||||||
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
import org.apache.nifi.remote.RemoteGroupPort;
|
import org.apache.nifi.remote.RemoteGroupPort;
|
||||||
import org.apache.nifi.remote.RootGroupPort;
|
import org.apache.nifi.remote.RootGroupPort;
|
||||||
import org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol;
|
import org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol;
|
||||||
|
@ -1116,10 +1117,10 @@ public class StandardFlowSynchronizer implements FlowSynchronizer {
|
||||||
final FlowRegistry flowRegistry = controller.getFlowRegistryClient().getFlowRegistry(versionControlInfoDto.getRegistryId());
|
final FlowRegistry flowRegistry = controller.getFlowRegistryClient().getFlowRegistry(versionControlInfoDto.getRegistryId());
|
||||||
final String registryName = flowRegistry == null ? versionControlInfoDto.getRegistryId() : flowRegistry.getName();
|
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)
|
final StandardVersionControlInformation versionControlInformation = StandardVersionControlInformation.Builder.fromDto(versionControlInfoDto)
|
||||||
.registryName(registryName)
|
.registryName(registryName)
|
||||||
.modified(false)
|
|
||||||
.current(true)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// pass empty map for the version control mapping because the VersionedComponentId has already been set on the components
|
// pass empty map for the version control mapping because the VersionedComponentId has already been set on the components
|
||||||
|
|
|
@ -169,8 +169,7 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
private final Map<String, Template> templates = new HashMap<>();
|
private final Map<String, Template> templates = new HashMap<>();
|
||||||
private final StringEncryptor encryptor;
|
private final StringEncryptor encryptor;
|
||||||
private final MutableVariableRegistry variableRegistry;
|
private final MutableVariableRegistry variableRegistry;
|
||||||
private final AtomicReference<StandardVersionedFlowStatus> flowStatus = new AtomicReference<>(
|
private final VersionControlFields versionControlFields = new VersionControlFields();
|
||||||
new StandardVersionedFlowStatus(null, "Not yet synchronized with Flow Registry", null));
|
|
||||||
|
|
||||||
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||||
private final Lock readLock = rwLock.readLock();
|
private final Lock readLock = rwLock.readLock();
|
||||||
|
@ -339,14 +338,22 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
// update the vci counts for this child group
|
// update the vci counts for this child group
|
||||||
final VersionControlInformation vci = childGroup.getVersionControlInformation();
|
final VersionControlInformation vci = childGroup.getVersionControlInformation();
|
||||||
if (vci != null) {
|
if (vci != null) {
|
||||||
if (vci.isModified() && !vci.isCurrent()) {
|
switch (vci.getStatus().getState()) {
|
||||||
locallyModifiedAndStale += 1;
|
case LOCALLY_MODIFIED:
|
||||||
} else if (!vci.isCurrent()) {
|
locallyModified++;
|
||||||
stale += 1;
|
break;
|
||||||
} else if (vci.isModified()) {
|
case LOCALLY_MODIFIED_AND_STALE:
|
||||||
locallyModified += 1;
|
locallyModifiedAndStale++;
|
||||||
} else {
|
break;
|
||||||
upToDate += 1;
|
case STALE:
|
||||||
|
stale++;
|
||||||
|
break;
|
||||||
|
case SYNC_FAILURE:
|
||||||
|
syncFailure++;
|
||||||
|
break;
|
||||||
|
case UP_TO_DATE:
|
||||||
|
upToDate++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2938,17 +2945,9 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearFlowDifferences();
|
versionControlFields.setFlowDifferences(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearFlowDifferences() {
|
|
||||||
boolean updated = false;
|
|
||||||
while (!updated) {
|
|
||||||
final StandardVersionedFlowStatus status = flowStatus.get();
|
|
||||||
final StandardVersionedFlowStatus updatedStatus = new StandardVersionedFlowStatus(status.getState(), status.getStateExplanation(), null);
|
|
||||||
updated = flowStatus.compareAndSet(status, updatedStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVersionControlInformation(final VersionControlInformation versionControlInformation, final Map<String, String> versionedComponentIds) {
|
public void setVersionControlInformation(final VersionControlInformation versionControlInformation, final Map<String, String> versionedComponentIds) {
|
||||||
|
@ -2959,8 +2958,6 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
versionControlInformation.getFlowIdentifier(),
|
versionControlInformation.getFlowIdentifier(),
|
||||||
versionControlInformation.getVersion(),
|
versionControlInformation.getVersion(),
|
||||||
stripContentsFromRemoteDescendantGroups(versionControlInformation.getFlowSnapshot(), true),
|
stripContentsFromRemoteDescendantGroups(versionControlInformation.getFlowSnapshot(), true),
|
||||||
versionControlInformation.isModified(),
|
|
||||||
versionControlInformation.isCurrent(),
|
|
||||||
versionControlInformation.getStatus()) {
|
versionControlInformation.getStatus()) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2970,60 +2967,50 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
return registry == null ? registryId : registry.getName();
|
return registry == null ? registryId : registry.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean isModified() {
|
||||||
public boolean isModified() {
|
Set<FlowDifference> differences = versionControlFields.getFlowDifferences();
|
||||||
boolean updated = false;
|
if (differences == null) {
|
||||||
while (true) {
|
differences = getModifications();
|
||||||
final StandardVersionedFlowStatus status = flowStatus.get();
|
|
||||||
Set<FlowDifference> differences = status.getCurrentDifferences();
|
|
||||||
if (differences == null) {
|
if (differences == null) {
|
||||||
differences = getModifications();
|
return false;
|
||||||
if (differences == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final StandardVersionedFlowStatus updatedStatus = new StandardVersionedFlowStatus(status.getState(), status.getStateExplanation(), differences);
|
|
||||||
updated = flowStatus.compareAndSet(status, updatedStatus);
|
|
||||||
|
|
||||||
if (updated) {
|
|
||||||
return !differences.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !differences.isEmpty();
|
versionControlFields.setFlowDifferences(differences);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return !differences.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionedFlowStatus getStatus() {
|
public VersionedFlowStatus getStatus() {
|
||||||
// If current state is a sync failure, then
|
// If current state is a sync failure, then
|
||||||
final StandardVersionedFlowStatus status = flowStatus.get();
|
final String syncFailureExplanation = versionControlFields.getSyncFailureExplanation();
|
||||||
final VersionedFlowState state = status.getState();
|
if (syncFailureExplanation != null) {
|
||||||
if (state == VersionedFlowState.SYNC_FAILURE) {
|
return new StandardVersionedFlowStatus(VersionedFlowState.SYNC_FAILURE, syncFailureExplanation);
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean modified = isModified();
|
final boolean modified = isModified();
|
||||||
if (!modified) {
|
if (!modified) {
|
||||||
final VersionControlInformation vci = StandardProcessGroup.this.versionControlInfo.get();
|
final VersionControlInformation vci = StandardProcessGroup.this.versionControlInfo.get();
|
||||||
if (vci.getFlowSnapshot() == null) {
|
if (vci.getFlowSnapshot() == null) {
|
||||||
return new StandardVersionedFlowStatus(VersionedFlowState.SYNC_FAILURE, "Process Group has not yet been synchronized with Flow Registry", null);
|
return new StandardVersionedFlowStatus(VersionedFlowState.SYNC_FAILURE, "Process Group has not yet been synchronized with Flow Registry");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean stale = !isCurrent();
|
final boolean stale = versionControlFields.isStale();
|
||||||
|
|
||||||
|
final VersionedFlowState flowState;
|
||||||
if (modified && stale) {
|
if (modified && stale) {
|
||||||
return new StandardVersionedFlowStatus(VersionedFlowState.LOCALLY_MODIFIED_AND_STALE, "Local changes have been made and a newer version of this flow is available", null);
|
flowState = VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
|
||||||
} else if (modified) {
|
} else if (modified) {
|
||||||
return new StandardVersionedFlowStatus(VersionedFlowState.LOCALLY_MODIFIED, "Local changes have been made", null);
|
flowState = VersionedFlowState.LOCALLY_MODIFIED;
|
||||||
} else if (stale) {
|
} else if (stale) {
|
||||||
return new StandardVersionedFlowStatus(VersionedFlowState.STALE, "A newer version of this flow is available", null);
|
flowState = VersionedFlowState.STALE;
|
||||||
} else {
|
} else {
|
||||||
return new StandardVersionedFlowStatus(VersionedFlowState.UP_TO_DATE, "Flow version is current", null);
|
flowState = VersionedFlowState.UP_TO_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new StandardVersionedFlowStatus(flowState, flowState.getDescription());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3031,11 +3018,23 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
svci.setFlowName(versionControlInformation.getFlowName());
|
svci.setFlowName(versionControlInformation.getFlowName());
|
||||||
svci.setFlowDescription(versionControlInformation.getFlowDescription());
|
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();
|
writeLock.lock();
|
||||||
try {
|
try {
|
||||||
updateVersionedComponentIds(this, versionedComponentIds);
|
updateVersionedComponentIds(this, versionedComponentIds);
|
||||||
this.versionControlInfo.set(svci);
|
this.versionControlInfo.set(svci);
|
||||||
clearFlowDifferences();
|
versionControlFields.setFlowDifferences(null);
|
||||||
|
|
||||||
|
final ProcessGroup parent = getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.onComponentModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler.submitFrameworkTask(() -> synchronizeWithFlowRegistry(flowController.getFlowRegistryClient()));
|
||||||
} finally {
|
} finally {
|
||||||
writeLock.unlock();
|
writeLock.unlock();
|
||||||
}
|
}
|
||||||
|
@ -3156,14 +3155,6 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
.forEach(childGroup -> applyVersionedComponentIds(childGroup, lookup));
|
.forEach(childGroup -> applyVersionedComponentIds(childGroup, lookup));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSyncFailedState(final String explanation) {
|
|
||||||
boolean updated = false;
|
|
||||||
while (!updated) {
|
|
||||||
final StandardVersionedFlowStatus status = flowStatus.get();
|
|
||||||
final StandardVersionedFlowStatus updatedStatus = new StandardVersionedFlowStatus(VersionedFlowState.SYNC_FAILURE, explanation, status.getCurrentDifferences());
|
|
||||||
updated = flowStatus.compareAndSet(status, updatedStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void synchronizeWithFlowRegistry(final FlowRegistryClient flowRegistryClient) {
|
public void synchronizeWithFlowRegistry(final FlowRegistryClient flowRegistryClient) {
|
||||||
|
@ -3177,7 +3168,7 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
if (flowRegistry == null) {
|
if (flowRegistry == null) {
|
||||||
final String message = String.format("Unable to synchronize Process Group with Flow Registry because Process Group was placed under Version Control using Flow Registry "
|
final String message = String.format("Unable to synchronize Process Group with Flow Registry because Process Group was placed under Version Control using Flow Registry "
|
||||||
+ "with identifier %s but cannot find any Flow Registry with this identifier", registryId);
|
+ "with identifier %s but cannot find any Flow Registry with this identifier", registryId);
|
||||||
setSyncFailedState(message);
|
versionControlFields.setSyncFailureExplanation(message);
|
||||||
|
|
||||||
LOG.error("Unable to synchronize {} with Flow Registry because Process Group was placed under Version Control using Flow Registry "
|
LOG.error("Unable to synchronize {} with Flow Registry because Process Group was placed under Version Control using Flow Registry "
|
||||||
+ "with identifier {} but cannot find any Flow Registry with this identifier", this, registryId);
|
+ "with identifier {} but cannot find any Flow Registry with this identifier", this, registryId);
|
||||||
|
@ -3195,7 +3186,7 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
} catch (final IOException | NiFiRegistryException e) {
|
} catch (final IOException | NiFiRegistryException e) {
|
||||||
final String message = String.format("Failed to synchronize Process Group with Flow Registry because could not retrieve version %s of flow with identifier %s in bucket %s",
|
final String message = String.format("Failed to synchronize Process Group with Flow Registry because could not retrieve version %s of flow with identifier %s in bucket %s",
|
||||||
vci.getVersion(), vci.getFlowIdentifier(), vci.getBucketIdentifier());
|
vci.getVersion(), vci.getFlowIdentifier(), vci.getBucketIdentifier());
|
||||||
setSyncFailedState(message);
|
versionControlFields.setSyncFailureExplanation(message);
|
||||||
|
|
||||||
LOG.error("Failed to synchronize {} with Flow Registry because could not retrieve version {} of flow with identifier {} in bucket {}",
|
LOG.error("Failed to synchronize {} with Flow Registry because could not retrieve version {} of flow with identifier {} in bucket {}",
|
||||||
this, vci.getVersion(), vci.getFlowIdentifier(), vci.getBucketIdentifier(), e);
|
this, vci.getVersion(), vci.getFlowIdentifier(), vci.getBucketIdentifier(), e);
|
||||||
|
@ -3213,22 +3204,17 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
|
|
||||||
if (latestVersion == vci.getVersion()) {
|
if (latestVersion == vci.getVersion()) {
|
||||||
LOG.debug("{} is currently at the most recent version ({}) of the flow that is under Version Control", this, latestVersion);
|
LOG.debug("{} is currently at the most recent version ({}) of the flow that is under Version Control", this, latestVersion);
|
||||||
vci.setCurrent(true);
|
versionControlFields.setStale(false);
|
||||||
} else {
|
} else {
|
||||||
vci.setCurrent(false);
|
|
||||||
LOG.info("{} is not the most recent version of the flow that is under Version Control; current version is {}; most recent version is {}",
|
LOG.info("{} is not the most recent version of the flow that is under Version Control; current version is {}; most recent version is {}",
|
||||||
new Object[] {this, vci.getVersion(), latestVersion});
|
new Object[] {this, vci.getVersion(), latestVersion});
|
||||||
|
versionControlFields.setStale(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean updated = false;
|
versionControlFields.setSyncFailureExplanation(null);
|
||||||
while (!updated) {
|
|
||||||
final StandardVersionedFlowStatus status = flowStatus.get();
|
|
||||||
final StandardVersionedFlowStatus updatedStatus = new StandardVersionedFlowStatus(null, null, status.getCurrentDifferences());
|
|
||||||
updated = flowStatus.compareAndSet(status, updatedStatus);
|
|
||||||
}
|
|
||||||
} catch (final IOException | NiFiRegistryException e) {
|
} catch (final IOException | NiFiRegistryException e) {
|
||||||
final String message = String.format("Failed to synchronize Process Group with Flow Registry : " + e.getMessage());
|
final String message = String.format("Failed to synchronize Process Group with Flow Registry : " + e.getMessage());
|
||||||
setSyncFailedState(message);
|
versionControlFields.setSyncFailureExplanation(message);
|
||||||
|
|
||||||
LOG.error("Failed to synchronize {} with Flow Registry because could not determine the most recent version of the Flow in the Flow Registry", this, e);
|
LOG.error("Failed to synchronize {} with Flow Registry because could not determine the most recent version of the Flow in the Flow Registry", this, e);
|
||||||
}
|
}
|
||||||
|
@ -3253,10 +3239,6 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
|
|
||||||
final Set<String> updatedVersionedComponentIds = new HashSet<>();
|
final Set<String> updatedVersionedComponentIds = new HashSet<>();
|
||||||
for (final FlowDifference diff : flowComparison.getDifferences()) {
|
for (final FlowDifference diff : flowComparison.getDifferences()) {
|
||||||
if (diff.getDifferenceType() == DifferenceType.POSITION_CHANGED) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this update adds a new Controller Service, then we need to check if the service already exists at a higher level
|
// If this update adds a new Controller Service, then we need to check if the service already exists at a higher level
|
||||||
// and if so compare our VersionedControllerService to the existing service.
|
// and if so compare our VersionedControllerService to the existing service.
|
||||||
if (diff.getDifferenceType() == DifferenceType.COMPONENT_ADDED) {
|
if (diff.getDifferenceType() == DifferenceType.COMPONENT_ADDED) {
|
||||||
|
@ -3393,6 +3375,8 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
final FlowRegistry flowRegistry = flowController.getFlowRegistryClient().getFlowRegistry(registryId);
|
final FlowRegistry flowRegistry = flowController.getFlowRegistryClient().getFlowRegistry(registryId);
|
||||||
final String registryName = flowRegistry == null ? registryId : flowRegistry.getName();
|
final String registryName = flowRegistry == null ? registryId : flowRegistry.getName();
|
||||||
|
|
||||||
|
final VersionedFlowState flowState = remoteCoordinates.getLatest() ? VersionedFlowState.UP_TO_DATE : VersionedFlowState.STALE;
|
||||||
|
|
||||||
final VersionControlInformation vci = new StandardVersionControlInformation.Builder()
|
final VersionControlInformation vci = new StandardVersionControlInformation.Builder()
|
||||||
.registryId(registryId)
|
.registryId(registryId)
|
||||||
.registryName(registryName)
|
.registryName(registryName)
|
||||||
|
@ -3402,8 +3386,7 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
.flowName(flowId)
|
.flowName(flowId)
|
||||||
.version(version)
|
.version(version)
|
||||||
.flowSnapshot(proposed)
|
.flowSnapshot(proposed)
|
||||||
.modified(false)
|
.status(new StandardVersionedFlowStatus(flowState, flowState.getDescription()))
|
||||||
.current(remoteCoordinates.getLatest())
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
group.setVersionControlInformation(vci, Collections.emptyMap());
|
group.setVersionControlInformation(vci, Collections.emptyMap());
|
||||||
|
@ -4149,13 +4132,9 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
final FlowComparator flowComparator = new StandardFlowComparator(snapshotFlow, currentFlow, getAncestorGroupServiceIds(), new EvolvingDifferenceDescriptor());
|
final FlowComparator flowComparator = new StandardFlowComparator(snapshotFlow, currentFlow, getAncestorGroupServiceIds(), new EvolvingDifferenceDescriptor());
|
||||||
final FlowComparison comparison = flowComparator.compare();
|
final FlowComparison comparison = flowComparator.compare();
|
||||||
final Set<FlowDifference> differences = comparison.getDifferences();
|
final Set<FlowDifference> differences = comparison.getDifferences();
|
||||||
final Set<FlowDifference> functionalDifferences = differences.stream()
|
|
||||||
.filter(diff -> diff.getDifferenceType() != DifferenceType.POSITION_CHANGED)
|
|
||||||
.filter(diff -> diff.getDifferenceType() != DifferenceType.STYLE_CHANGED)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
LOG.debug("There are {} differences between this Local Flow and the Versioned Flow: {}", differences.size(), differences);
|
LOG.debug("There are {} differences between this Local Flow and the Versioned Flow: {}", differences.size(), differences);
|
||||||
return functionalDifferences;
|
return differences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4170,7 +4149,8 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verifyNotDirty) {
|
if (verifyNotDirty) {
|
||||||
final boolean modified = versionControlInfo.isModified();
|
final VersionedFlowState flowState = versionControlInfo.getStatus().getState();
|
||||||
|
final boolean modified = flowState == VersionedFlowState.LOCALLY_MODIFIED || flowState == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
|
||||||
|
|
||||||
final Set<FlowDifference> modifications = getModifications();
|
final Set<FlowDifference> modifications = getModifications();
|
||||||
|
|
||||||
|
@ -4186,7 +4166,7 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
throw new IllegalStateException("Cannot change the Version of the flow for " + this
|
throw new IllegalStateException("Cannot change the Version of the flow for " + this
|
||||||
+ " because the Process Group has been modified (" + modifications.size()
|
+ " because the Process Group has been modified (" + modifications.size()
|
||||||
+ " modifications) since it was last synchronized with the Flow Registry. The Process Group must be"
|
+ " modifications) since it was last synchronized with the Flow Registry. The Process Group must be"
|
||||||
+ " reverted to its original form before changing the version. See logs for more information on what has changed.");
|
+ " reverted to its original form before changing the version.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4393,8 +4373,8 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
if (flowId != null && flowId.equals(vci.getFlowIdentifier())) {
|
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.
|
// 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'.
|
// In order to do this, we have to ensure that the Process Group is 'current'.
|
||||||
final boolean current = vci.isCurrent();
|
final VersionedFlowState state = vci.getStatus().getState();
|
||||||
if (!current) {
|
if (state == VersionedFlowState.STALE || state == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE) {
|
||||||
throw new IllegalStateException("Cannot update Version Control Information for Process Group with ID " + getIdentifier()
|
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. "
|
+ " 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.");
|
+ "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.");
|
||||||
|
@ -4441,10 +4421,15 @@ public final class StandardProcessGroup implements ProcessGroup {
|
||||||
private void verifyNoDescendantsWithLocalModifications(final String action) {
|
private void verifyNoDescendantsWithLocalModifications(final String action) {
|
||||||
for (final ProcessGroup descendant : findAllProcessGroups()) {
|
for (final ProcessGroup descendant : findAllProcessGroups()) {
|
||||||
final VersionControlInformation descendantVci = descendant.getVersionControlInformation();
|
final VersionControlInformation descendantVci = descendant.getVersionControlInformation();
|
||||||
if (descendantVci != null && descendantVci.isModified()) {
|
if (descendantVci != null) {
|
||||||
throw new IllegalStateException("Process Group cannot " + action + " because it contains a child or descendant Process Group that is under Version Control and "
|
final VersionedFlowState flowState = descendantVci.getStatus().getState();
|
||||||
+ "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 "
|
final boolean modified = flowState == VersionedFlowState.LOCALLY_MODIFIED || flowState == VersionedFlowState.LOCALLY_MODIFIED_AND_STALE;
|
||||||
+ "this action can be performed on the parent Process Group.");
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,21 +17,16 @@
|
||||||
|
|
||||||
package org.apache.nifi.groups;
|
package org.apache.nifi.groups;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowState;
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowStatus;
|
import org.apache.nifi.registry.flow.VersionedFlowStatus;
|
||||||
import org.apache.nifi.registry.flow.diff.FlowDifference;
|
|
||||||
|
|
||||||
class StandardVersionedFlowStatus implements VersionedFlowStatus {
|
class StandardVersionedFlowStatus implements VersionedFlowStatus {
|
||||||
private final VersionedFlowState state;
|
private final VersionedFlowState state;
|
||||||
private final String explanation;
|
private final String explanation;
|
||||||
private final Set<FlowDifference> currentDifferences;
|
|
||||||
|
|
||||||
StandardVersionedFlowStatus(final VersionedFlowState state, final String explanation, final Set<FlowDifference> differences) {
|
StandardVersionedFlowStatus(final VersionedFlowState state, final String explanation) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.explanation = explanation;
|
this.explanation = explanation;
|
||||||
this.currentDifferences = differences;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,8 +38,4 @@ class StandardVersionedFlowStatus implements VersionedFlowStatus {
|
||||||
public String getStateExplanation() {
|
public String getStateExplanation() {
|
||||||
return explanation;
|
return explanation;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<FlowDifference> getCurrentDifferences() {
|
|
||||||
return currentDifferences;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.nifi.groups;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.nifi.registry.flow.diff.FlowDifference;
|
||||||
|
|
||||||
|
public class VersionControlFields {
|
||||||
|
private volatile boolean locallyModified;
|
||||||
|
private volatile boolean stale;
|
||||||
|
private volatile String syncFailureExplanation = "Not yet synchronized with Flow Registry";
|
||||||
|
private volatile Set<FlowDifference> flowDifferences;
|
||||||
|
|
||||||
|
boolean isLocallyModified() {
|
||||||
|
return locallyModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLocallyModified(final boolean locallyModified) {
|
||||||
|
this.locallyModified = locallyModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isStale() {
|
||||||
|
return stale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStale(final boolean stale) {
|
||||||
|
this.stale = stale;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getSyncFailureExplanation() {
|
||||||
|
return syncFailureExplanation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSyncFailureExplanation(final String syncFailureExplanation) {
|
||||||
|
this.syncFailureExplanation = syncFailureExplanation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<FlowDifference> getFlowDifferences() {
|
||||||
|
return flowDifferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFlowDifferences(final Set<FlowDifference> flowDifferences) {
|
||||||
|
this.flowDifferences = flowDifferences;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,8 +32,6 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
private volatile String flowDescription;
|
private volatile String flowDescription;
|
||||||
private final int version;
|
private final int version;
|
||||||
private volatile VersionedProcessGroup flowSnapshot;
|
private volatile VersionedProcessGroup flowSnapshot;
|
||||||
private volatile boolean modified;
|
|
||||||
private volatile boolean current;
|
|
||||||
private final VersionedFlowStatus status;
|
private final VersionedFlowStatus status;
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
@ -46,8 +44,6 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
private String flowDescription;
|
private String flowDescription;
|
||||||
private int version;
|
private int version;
|
||||||
private VersionedProcessGroup flowSnapshot;
|
private VersionedProcessGroup flowSnapshot;
|
||||||
private Boolean modified = null;
|
|
||||||
private Boolean current = null;
|
|
||||||
private VersionedFlowStatus status;
|
private VersionedFlowStatus status;
|
||||||
|
|
||||||
public Builder registryId(String registryId) {
|
public Builder registryId(String registryId) {
|
||||||
|
@ -90,16 +86,6 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder modified(boolean modified) {
|
|
||||||
this.modified = modified;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder current(boolean current) {
|
|
||||||
this.current = current;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder flowSnapshot(VersionedProcessGroup snapshot) {
|
public Builder flowSnapshot(VersionedProcessGroup snapshot) {
|
||||||
this.flowSnapshot = snapshot;
|
this.flowSnapshot = snapshot;
|
||||||
return this;
|
return this;
|
||||||
|
@ -119,8 +105,17 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
.flowId(dto.getFlowId())
|
.flowId(dto.getFlowId())
|
||||||
.flowName(dto.getFlowName())
|
.flowName(dto.getFlowName())
|
||||||
.flowDescription(dto.getFlowDescription())
|
.flowDescription(dto.getFlowDescription())
|
||||||
.current(dto.getCurrent() == null ? true : dto.getCurrent())
|
.status(new VersionedFlowStatus() {
|
||||||
.modified(dto.getModified() == null ? false : dto.getModified())
|
@Override
|
||||||
|
public VersionedFlowState getState() {
|
||||||
|
return VersionedFlowState.valueOf(dto.getState());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStateExplanation() {
|
||||||
|
return dto.getStateExplanation();
|
||||||
|
}
|
||||||
|
})
|
||||||
.version(dto.getVersion());
|
.version(dto.getVersion());
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -133,7 +128,7 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
Objects.requireNonNull(version, "Version must be specified");
|
Objects.requireNonNull(version, "Version must be specified");
|
||||||
|
|
||||||
final StandardVersionControlInformation svci = new StandardVersionControlInformation(registryIdentifier, registryName,
|
final StandardVersionControlInformation svci = new StandardVersionControlInformation(registryIdentifier, registryName,
|
||||||
bucketIdentifier, flowIdentifier, version, flowSnapshot, modified, current, status);
|
bucketIdentifier, flowIdentifier, version, flowSnapshot, status);
|
||||||
|
|
||||||
svci.setBucketName(bucketName);
|
svci.setBucketName(bucketName);
|
||||||
svci.setFlowName(flowName);
|
svci.setFlowName(flowName);
|
||||||
|
@ -145,15 +140,13 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
|
|
||||||
|
|
||||||
public StandardVersionControlInformation(final String registryId, final String registryName, final String bucketId, final String flowId, final int version,
|
public StandardVersionControlInformation(final String registryId, final String registryName, final String bucketId, final String flowId, final int version,
|
||||||
final VersionedProcessGroup snapshot, final boolean modified, final boolean current, final VersionedFlowStatus status) {
|
final VersionedProcessGroup snapshot, final VersionedFlowStatus status) {
|
||||||
this.registryIdentifier = registryId;
|
this.registryIdentifier = registryId;
|
||||||
this.registryName = registryName;
|
this.registryName = registryName;
|
||||||
this.bucketIdentifier = bucketId;
|
this.bucketIdentifier = bucketId;
|
||||||
this.flowIdentifier = flowId;
|
this.flowIdentifier = flowId;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.flowSnapshot = snapshot;
|
this.flowSnapshot = snapshot;
|
||||||
this.modified = modified;
|
|
||||||
this.current = current;
|
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,29 +207,11 @@ public class StandardVersionControlInformation implements VersionControlInformat
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isModified() {
|
|
||||||
return modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCurrent() {
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionedProcessGroup getFlowSnapshot() {
|
public VersionedProcessGroup getFlowSnapshot() {
|
||||||
return flowSnapshot;
|
return flowSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModified(final boolean modified) {
|
|
||||||
this.modified = modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrent(final boolean current) {
|
|
||||||
this.current = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFlowSnapshot(final VersionedProcessGroup flowSnapshot) {
|
public void setFlowSnapshot(final VersionedProcessGroup flowSnapshot) {
|
||||||
this.flowSnapshot = flowSnapshot;
|
this.flowSnapshot = flowSnapshot;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,9 +178,7 @@ public class StandardRemoteProcessGroup implements RemoteProcessGroup {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final Runnable checkAuthorizations = new InitializationTask();
|
|
||||||
backgroundThreadExecutor = new FlowEngine(1, "Remote Process Group " + id, true);
|
backgroundThreadExecutor = new FlowEngine(1, "Remote Process Group " + id, true);
|
||||||
backgroundThreadExecutor.scheduleWithFixedDelay(checkAuthorizations, 30L, 30L, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -197,6 +195,9 @@ public class StandardRemoteProcessGroup implements RemoteProcessGroup {
|
||||||
logger.warn("Unable to communicate with remote instance {}", new Object[] {this, e});
|
logger.warn("Unable to communicate with remote instance {}", new Object[] {this, e});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final Runnable checkAuthorizations = new InitializationTask();
|
||||||
|
backgroundThreadExecutor.scheduleWithFixedDelay(checkAuthorizations, 0L, 60L, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1442,20 +1442,6 @@ public interface NiFiServiceFacade {
|
||||||
*/
|
*/
|
||||||
void verifyCanRevertLocalModifications(String groupId, VersionedFlowSnapshot versionedFlowSnapshot);
|
void verifyCanRevertLocalModifications(String groupId, VersionedFlowSnapshot versionedFlowSnapshot);
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the Process group with the given ID to match the new snapshot
|
|
||||||
*
|
|
||||||
* @param revision the revision of the Process Group
|
|
||||||
* @param groupId the ID of the Process Group
|
|
||||||
* @param versionControlInfo the Version Control information
|
|
||||||
* @param snapshot the new snapshot
|
|
||||||
* @param componentIdSeed the seed to use for generating new component ID's
|
|
||||||
* @param updateDescendantVersionedFlows if a child/descendant Process Group is under Version Control, specifies whether or not to
|
|
||||||
* update the contents of that Process Group
|
|
||||||
* @return the Process Group
|
|
||||||
*/
|
|
||||||
ProcessGroupEntity updateProcessGroup(Revision revision, String groupId, VersionControlInformationDTO versionControlInfo, VersionedFlowSnapshot snapshot, String componentIdSeed,
|
|
||||||
boolean verifyNotModified, boolean updateDescendantVersionedFlows);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the Process group with the given ID to match the new snapshot
|
* Updates the Process group with the given ID to match the new snapshot
|
||||||
|
|
|
@ -97,6 +97,7 @@ import org.apache.nifi.registry.flow.VersionedConnection;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlow;
|
import org.apache.nifi.registry.flow.VersionedFlow;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
|
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
|
||||||
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
import org.apache.nifi.registry.flow.VersionedProcessGroup;
|
import org.apache.nifi.registry.flow.VersionedProcessGroup;
|
||||||
import org.apache.nifi.registry.flow.diff.ComparableDataFlow;
|
import org.apache.nifi.registry.flow.diff.ComparableDataFlow;
|
||||||
import org.apache.nifi.registry.flow.diff.ConciseEvolvingDifferenceDescriptor;
|
import org.apache.nifi.registry.flow.diff.ConciseEvolvingDifferenceDescriptor;
|
||||||
|
@ -292,6 +293,7 @@ import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of NiFiServiceFacade that performs revision checking.
|
* Implementation of NiFiServiceFacade that performs revision checking.
|
||||||
|
@ -1592,7 +1594,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
|
|
||||||
final D dto = dtoCreation.apply(component);
|
final D dto = dtoCreation.apply(component);
|
||||||
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
||||||
return new StandardRevisionUpdate<D>(dto, lastMod);
|
return new StandardRevisionUpdate<>(dto, lastMod);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1779,7 +1781,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
controllerFacade.save();
|
controllerFacade.save();
|
||||||
|
|
||||||
final SnippetDTO dto = dtoFactory.createSnippetDto(snippet);
|
final SnippetDTO dto = dtoFactory.createSnippetDto(snippet);
|
||||||
final RevisionUpdate<SnippetDTO> snapshot = new StandardRevisionUpdate<SnippetDTO>(dto, null);
|
final RevisionUpdate<SnippetDTO> snapshot = new StandardRevisionUpdate<>(dto, null);
|
||||||
|
|
||||||
return entityFactory.createSnippetEntity(snapshot.getComponent());
|
return entityFactory.createSnippetEntity(snapshot.getComponent());
|
||||||
}
|
}
|
||||||
|
@ -2088,7 +2090,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
controllerFacade.save();
|
controllerFacade.save();
|
||||||
|
|
||||||
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
||||||
return new StandardRevisionUpdate<ControllerServiceDTO>(dto, lastMod);
|
return new StandardRevisionUpdate<>(dto, lastMod);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
snapshot = revisionManager.updateRevision(claim, user, () -> {
|
snapshot = revisionManager.updateRevision(claim, user, () -> {
|
||||||
|
@ -2098,7 +2100,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
controllerFacade.save();
|
controllerFacade.save();
|
||||||
|
|
||||||
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
||||||
return new StandardRevisionUpdate<ControllerServiceDTO>(dto, lastMod);
|
return new StandardRevisionUpdate<>(dto, lastMod);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2440,7 +2442,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
final Revision updatedRevision = revisionManager.getRevision(revision.getComponentId()).incrementRevision(revision.getClientId());
|
final Revision updatedRevision = revisionManager.getRevision(revision.getComponentId()).incrementRevision(revision.getClientId());
|
||||||
final FlowModification lastModification = new FlowModification(updatedRevision, user.getIdentity());
|
final FlowModification lastModification = new FlowModification(updatedRevision, user.getIdentity());
|
||||||
|
|
||||||
return new StandardRevisionUpdate<FlowRegistry>(registry, lastModification);
|
return new StandardRevisionUpdate<>(registry, lastModification);
|
||||||
});
|
});
|
||||||
|
|
||||||
final FlowRegistry updatedReg = revisionUpdate.getComponent();
|
final FlowRegistry updatedReg = revisionUpdate.getComponent();
|
||||||
|
@ -2483,7 +2485,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
|
|
||||||
final ReportingTaskDTO dto = dtoFactory.createReportingTaskDto(reportingTask);
|
final ReportingTaskDTO dto = dtoFactory.createReportingTaskDto(reportingTask);
|
||||||
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity());
|
||||||
return new StandardRevisionUpdate<ReportingTaskDTO>(dto, lastMod);
|
return new StandardRevisionUpdate<>(dto, lastMod);
|
||||||
});
|
});
|
||||||
|
|
||||||
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId());
|
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId());
|
||||||
|
@ -3649,6 +3651,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
@Override
|
@Override
|
||||||
public VersionControlComponentMappingEntity registerFlowWithFlowRegistry(final String groupId, final StartVersionControlRequestEntity requestEntity) {
|
public VersionControlComponentMappingEntity registerFlowWithFlowRegistry(final String groupId, final StartVersionControlRequestEntity requestEntity) {
|
||||||
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
|
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
|
||||||
|
|
||||||
final VersionControlInformation currentVci = processGroup.getVersionControlInformation();
|
final VersionControlInformation currentVci = processGroup.getVersionControlInformation();
|
||||||
final int expectedVersion = currentVci == null ? 1 : currentVci.getVersion() + 1;
|
final int expectedVersion = currentVci == null ? 1 : currentVci.getVersion() + 1;
|
||||||
|
|
||||||
|
@ -3697,15 +3700,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
final VersionControlInformationDTO vci = new VersionControlInformationDTO();
|
final VersionControlInformationDTO vci = new VersionControlInformationDTO();
|
||||||
vci.setBucketId(bucket.getIdentifier());
|
vci.setBucketId(bucket.getIdentifier());
|
||||||
vci.setBucketName(bucket.getName());
|
vci.setBucketName(bucket.getName());
|
||||||
vci.setCurrent(true);
|
|
||||||
vci.setFlowId(flow.getIdentifier());
|
vci.setFlowId(flow.getIdentifier());
|
||||||
vci.setFlowName(flow.getName());
|
vci.setFlowName(flow.getName());
|
||||||
vci.setFlowDescription(flow.getDescription());
|
vci.setFlowDescription(flow.getDescription());
|
||||||
vci.setGroupId(groupId);
|
vci.setGroupId(groupId);
|
||||||
vci.setModified(false);
|
|
||||||
vci.setRegistryId(registryId);
|
vci.setRegistryId(registryId);
|
||||||
vci.setRegistryName(getFlowRegistryName(registryId));
|
vci.setRegistryName(getFlowRegistryName(registryId));
|
||||||
vci.setVersion(registeredSnapshot.getSnapshotMetadata().getVersion());
|
vci.setVersion(registeredSnapshot.getSnapshotMetadata().getVersion());
|
||||||
|
vci.setState(VersionedFlowState.UP_TO_DATE.name());
|
||||||
|
|
||||||
final Map<String, String> mapping = dtoFactory.createVersionControlComponentMappingDto(versionedProcessGroup);
|
final Map<String, String> mapping = dtoFactory.createVersionControlComponentMappingDto(versionedProcessGroup);
|
||||||
|
|
||||||
|
@ -3777,8 +3779,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
final FlowComparator flowComparator = new StandardFlowComparator(registryFlow, localFlow, ancestorServiceIds, new ConciseEvolvingDifferenceDescriptor());
|
final FlowComparator flowComparator = new StandardFlowComparator(registryFlow, localFlow, ancestorServiceIds, new ConciseEvolvingDifferenceDescriptor());
|
||||||
final FlowComparison flowComparison = flowComparator.compare();
|
final FlowComparison flowComparison = flowComparator.compare();
|
||||||
|
|
||||||
final Set<ComponentDifferenceDTO> differenceDtos = dtoFactory.createComponentDifferenceDtos(flowComparison,
|
final Set<ComponentDifferenceDTO> differenceDtos = dtoFactory.createComponentDifferenceDtos(flowComparison);
|
||||||
diff -> diff.getDifferenceType() != DifferenceType.POSITION_CHANGED && diff.getDifferenceType() != DifferenceType.STYLE_CHANGED);
|
|
||||||
|
|
||||||
final FlowComparisonEntity entity = new FlowComparisonEntity();
|
final FlowComparisonEntity entity = new FlowComparisonEntity();
|
||||||
entity.setComponentDifferences(differenceDtos);
|
entity.setComponentDifferences(differenceDtos);
|
||||||
|
@ -4079,30 +4080,88 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
return flowRegistry == null ? flowRegistryId : flowRegistry.getName();
|
return flowRegistry == null ? flowRegistryId : flowRegistry.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private List<Revision> getComponentRevisions(final ProcessGroup processGroup, final boolean includeGroupRevision) {
|
||||||
public ProcessGroupEntity updateProcessGroup(final Revision revision, final String groupId, final VersionControlInformationDTO versionControlInfo,
|
final List<Revision> revisions = new ArrayList<>();
|
||||||
final VersionedFlowSnapshot proposedFlowSnapshot, final String componentIdSeed, final boolean verifyNotModified, final boolean updateDescendantVersionedFlows) {
|
if (includeGroupRevision) {
|
||||||
|
revisions.add(revisionManager.getRevision(processGroup.getIdentifier()));
|
||||||
|
}
|
||||||
|
|
||||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
processGroup.findAllConnections().stream()
|
||||||
return updateProcessGroupContents(user, revision, groupId, versionControlInfo, proposedFlowSnapshot, componentIdSeed, verifyNotModified, true, updateDescendantVersionedFlows);
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllControllerServices().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllFunnels().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllInputPorts().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllOutputPorts().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllLabels().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllProcessGroups().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllProcessors().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllRemoteProcessGroups().stream()
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
processGroup.findAllRemoteProcessGroups().stream()
|
||||||
|
.flatMap(rpg -> Stream.concat(rpg.getInputPorts().stream(), rpg.getOutputPorts().stream()))
|
||||||
|
.map(component -> revisionManager.getRevision(component.getIdentifier()))
|
||||||
|
.forEach(revisions::add);
|
||||||
|
|
||||||
|
return revisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProcessGroupEntity updateProcessGroupContents(final NiFiUser user, final Revision revision, final String groupId, final VersionControlInformationDTO versionControlInfo,
|
public ProcessGroupEntity updateProcessGroupContents(final NiFiUser user, final Revision revision, final String groupId, final VersionControlInformationDTO versionControlInfo,
|
||||||
final VersionedFlowSnapshot proposedFlowSnapshot, final String componentIdSeed, final boolean verifyNotModified, final boolean updateSettings, final boolean updateDescendantVersionedFlows) {
|
final VersionedFlowSnapshot proposedFlowSnapshot, final String componentIdSeed, final boolean verifyNotModified, final boolean updateSettings, final boolean updateDescendantVersionedFlows) {
|
||||||
|
|
||||||
final ProcessGroup processGroupNode = processGroupDAO.getProcessGroup(groupId);
|
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
|
||||||
final RevisionUpdate<ProcessGroupDTO> snapshot = updateComponent(user, revision,
|
final List<Revision> revisions = getComponentRevisions(processGroup, false);
|
||||||
processGroupNode,
|
revisions.add(revision);
|
||||||
() -> processGroupDAO.updateProcessGroupFlow(groupId, user, proposedFlowSnapshot, versionControlInfo, componentIdSeed, verifyNotModified, updateSettings, updateDescendantVersionedFlows),
|
|
||||||
processGroup -> dtoFactory.createProcessGroupDto(processGroup));
|
|
||||||
|
|
||||||
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroupNode);
|
final RevisionClaim revisionClaim = new StandardRevisionClaim(revisions);
|
||||||
final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
|
|
||||||
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroupNode.getIdentifier()));
|
final RevisionUpdate<ProcessGroupDTO> revisionUpdate = revisionManager.updateRevision(revisionClaim, user, new UpdateRevisionTask<ProcessGroupDTO>() {
|
||||||
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroupNode.getIdentifier()));
|
@Override
|
||||||
|
public RevisionUpdate<ProcessGroupDTO> update() {
|
||||||
|
// update the Process Group
|
||||||
|
processGroupDAO.updateProcessGroupFlow(groupId, user, proposedFlowSnapshot, versionControlInfo, componentIdSeed, verifyNotModified, updateSettings, updateDescendantVersionedFlows);
|
||||||
|
|
||||||
|
// update the revisions
|
||||||
|
final Set<Revision> updatedRevisions = revisions.stream()
|
||||||
|
.map(rev -> revisionManager.getRevision(rev.getComponentId()).incrementRevision(revision.getClientId()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// save
|
||||||
|
controllerFacade.save();
|
||||||
|
|
||||||
|
// gather details for response
|
||||||
|
final ProcessGroupDTO dto = dtoFactory.createProcessGroupDto(processGroup);
|
||||||
|
|
||||||
|
final Revision updatedRevision = revisionManager.getRevision(groupId).incrementRevision(revision.getClientId());
|
||||||
|
final FlowModification lastModification = new FlowModification(updatedRevision, user.getIdentity());
|
||||||
|
return new StandardRevisionUpdate<>(dto, lastModification, updatedRevisions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final FlowModification lastModification = revisionUpdate.getLastModification();
|
||||||
|
|
||||||
|
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup);
|
||||||
|
final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(lastModification);
|
||||||
|
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroup.getIdentifier()));
|
||||||
|
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroup.getIdentifier()));
|
||||||
final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList());
|
final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList());
|
||||||
return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, permissions, status, bulletinEntities);
|
return entityFactory.createProcessGroupEntity(revisionUpdate.getComponent(), updatedRevision, permissions, status, bulletinEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuthorizationResult authorizeAction(final Action action) {
|
private AuthorizationResult authorizeAction(final Action action) {
|
||||||
|
|
|
@ -16,12 +16,32 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.web.api;
|
package org.apache.nifi.web.api;
|
||||||
|
|
||||||
import io.swagger.annotations.Api;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import javax.ws.rs.Consumes;
|
||||||
import io.swagger.annotations.ApiParam;
|
import javax.ws.rs.DELETE;
|
||||||
import io.swagger.annotations.ApiResponse;
|
import javax.ws.rs.DefaultValue;
|
||||||
import io.swagger.annotations.ApiResponses;
|
import javax.ws.rs.GET;
|
||||||
import io.swagger.annotations.Authorization;
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.MultivaluedHashMap;
|
||||||
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBElement;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
import javax.xml.stream.XMLStreamReader;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.AuthorizableLookup;
|
import org.apache.nifi.authorization.AuthorizableLookup;
|
||||||
import org.apache.nifi.authorization.AuthorizeAccess;
|
import org.apache.nifi.authorization.AuthorizeAccess;
|
||||||
|
@ -47,6 +67,7 @@ import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||||
import org.apache.nifi.registry.flow.FlowRegistryUtils;
|
import org.apache.nifi.registry.flow.FlowRegistryUtils;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlow;
|
import org.apache.nifi.registry.flow.VersionedFlow;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
||||||
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
import org.apache.nifi.registry.variable.VariableRegistryUpdateRequest;
|
import org.apache.nifi.registry.variable.VariableRegistryUpdateRequest;
|
||||||
import org.apache.nifi.registry.variable.VariableRegistryUpdateStep;
|
import org.apache.nifi.registry.variable.VariableRegistryUpdateStep;
|
||||||
import org.apache.nifi.remote.util.SiteToSiteRestApiClient;
|
import org.apache.nifi.remote.util.SiteToSiteRestApiClient;
|
||||||
|
@ -111,31 +132,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.DefaultValue;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.HttpMethod;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.QueryParam;
|
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.MultivaluedHashMap;
|
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBElement;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.stream.XMLStreamReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -161,6 +157,13 @@ import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import io.swagger.annotations.ApiResponse;
|
||||||
|
import io.swagger.annotations.ApiResponses;
|
||||||
|
import io.swagger.annotations.Authorization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RESTful endpoint for managing a Group.
|
* RESTful endpoint for managing a Group.
|
||||||
*/
|
*/
|
||||||
|
@ -1657,8 +1660,8 @@ public class ProcessGroupResource extends ApplicationResource {
|
||||||
versionControlInfo.setFlowDescription(flow.getDescription());
|
versionControlInfo.setFlowDescription(flow.getDescription());
|
||||||
|
|
||||||
versionControlInfo.setRegistryName(serviceFacade.getFlowRegistryName(versionControlInfo.getRegistryId()));
|
versionControlInfo.setRegistryName(serviceFacade.getFlowRegistryName(versionControlInfo.getRegistryId()));
|
||||||
versionControlInfo.setModified(false);
|
final VersionedFlowState flowState = flowSnapshot.isLatest() ? VersionedFlowState.UP_TO_DATE : VersionedFlowState.STALE;
|
||||||
versionControlInfo.setCurrent(flowSnapshot.isLatest());
|
versionControlInfo.setState(flowState.name());
|
||||||
|
|
||||||
// Step 3: Resolve Bundle info
|
// Step 3: Resolve Bundle info
|
||||||
BundleUtils.discoverCompatibleBundles(flowSnapshot.getFlowContents());
|
BundleUtils.discoverCompatibleBundles(flowSnapshot.getFlowContents());
|
||||||
|
@ -1689,8 +1692,12 @@ public class ProcessGroupResource extends ApplicationResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
},
|
final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
|
||||||
|
if (versionedFlowSnapshot != null) {
|
||||||
|
serviceFacade.verifyComponentTypes(versionedFlowSnapshot.getFlowContents());
|
||||||
|
}
|
||||||
|
},
|
||||||
processGroupEntity -> {
|
processGroupEntity -> {
|
||||||
final ProcessGroupDTO processGroup = processGroupEntity.getComponent();
|
final ProcessGroupDTO processGroup = processGroupEntity.getComponent();
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.nifi.registry.flow.FlowRegistryUtils;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlow;
|
import org.apache.nifi.registry.flow.VersionedFlow;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
|
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
|
||||||
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
import org.apache.nifi.registry.flow.VersionedProcessGroup;
|
import org.apache.nifi.registry.flow.VersionedProcessGroup;
|
||||||
import org.apache.nifi.util.BundleUtils;
|
import org.apache.nifi.util.BundleUtils;
|
||||||
import org.apache.nifi.web.NiFiServiceFacade;
|
import org.apache.nifi.web.NiFiServiceFacade;
|
||||||
|
@ -166,14 +167,14 @@ public class VersionsResource extends ApplicationResource {
|
||||||
|
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.WILDCARD)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("active-requests")
|
@Path("active-requests")
|
||||||
@ApiOperation(
|
@ApiOperation(
|
||||||
value = "Creates a request so that a Process Group can be placed under Version Control or have its Version Control configuration changed. Creating this request will "
|
value = "Creates a request so that a Process Group can be placed under Version Control or have its Version Control configuration changed. Creating this request will "
|
||||||
+ "prevent any other threads from simultaneously saving local changes to Version Control. It will not, however, actually save the local flow to the Flow Registry. A "
|
+ "prevent any other threads from simultaneously saving local changes to Version Control. It will not, however, actually save the local flow to the Flow Registry. A "
|
||||||
+ "POST to /versions/process-groups/{id} should be used to initiate saving of the local flow to the Flow Registry.",
|
+ "POST to /versions/process-groups/{id} should be used to initiate saving of the local flow to the Flow Registry.",
|
||||||
response = VersionControlInformationEntity.class,
|
response = String.class,
|
||||||
notes = NON_GUARANTEED_ENDPOINT)
|
notes = NON_GUARANTEED_ENDPOINT)
|
||||||
@ApiResponses(value = {
|
@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 = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||||
|
@ -186,7 +187,7 @@ public class VersionsResource extends ApplicationResource {
|
||||||
@ApiParam(value = "The versioned flow details.", required = true) final CreateActiveRequestEntity requestEntity) {
|
@ApiParam(value = "The versioned flow details.", required = true) final CreateActiveRequestEntity requestEntity) {
|
||||||
|
|
||||||
if (isReplicateRequest()) {
|
if (isReplicateRequest()) {
|
||||||
return replicate(HttpMethod.POST);
|
return replicate(HttpMethod.POST, requestEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestEntity.getProcessGroupId() == null) {
|
if (requestEntity.getProcessGroupId() == null) {
|
||||||
|
@ -548,11 +549,14 @@ public class VersionsResource extends ApplicationResource {
|
||||||
final CreateActiveRequestEntity activeRequestEntity = new CreateActiveRequestEntity();
|
final CreateActiveRequestEntity activeRequestEntity = new CreateActiveRequestEntity();
|
||||||
activeRequestEntity.setProcessGroupId(groupId);
|
activeRequestEntity.setProcessGroupId(groupId);
|
||||||
|
|
||||||
|
final Map<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("content-type", MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
if (getReplicationTarget() == ReplicationTarget.CLUSTER_NODES) {
|
if (getReplicationTarget() == ReplicationTarget.CLUSTER_NODES) {
|
||||||
clusterResponse = getRequestReplicator().replicate(HttpMethod.POST, createRequestUri, activeRequestEntity, Collections.emptyMap()).awaitMergedResponse();
|
clusterResponse = getRequestReplicator().replicate(HttpMethod.POST, createRequestUri, activeRequestEntity, headers).awaitMergedResponse();
|
||||||
} else {
|
} else {
|
||||||
clusterResponse = getRequestReplicator().forwardToCoordinator(
|
clusterResponse = getRequestReplicator().forwardToCoordinator(
|
||||||
getClusterCoordinatorNode(), HttpMethod.POST, createRequestUri, activeRequestEntity, Collections.emptyMap()).awaitMergedResponse();
|
getClusterCoordinatorNode(), HttpMethod.POST, createRequestUri, activeRequestEntity, headers).awaitMergedResponse();
|
||||||
}
|
}
|
||||||
} catch (final InterruptedException ie) {
|
} catch (final InterruptedException ie) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
@ -761,18 +765,20 @@ public class VersionsResource extends ApplicationResource {
|
||||||
final VersionControlInformationDTO versionControlInfoDto = new VersionControlInformationDTO();
|
final VersionControlInformationDTO versionControlInfoDto = new VersionControlInformationDTO();
|
||||||
versionControlInfoDto.setBucketId(snapshotMetadata.getBucketIdentifier());
|
versionControlInfoDto.setBucketId(snapshotMetadata.getBucketIdentifier());
|
||||||
versionControlInfoDto.setBucketName(bucket.getName());
|
versionControlInfoDto.setBucketName(bucket.getName());
|
||||||
versionControlInfoDto.setCurrent(snapshotMetadata.getVersion() == flow.getVersionCount());
|
|
||||||
versionControlInfoDto.setFlowId(snapshotMetadata.getFlowIdentifier());
|
versionControlInfoDto.setFlowId(snapshotMetadata.getFlowIdentifier());
|
||||||
versionControlInfoDto.setFlowName(flow.getName());
|
versionControlInfoDto.setFlowName(flow.getName());
|
||||||
versionControlInfoDto.setFlowDescription(flow.getDescription());
|
versionControlInfoDto.setFlowDescription(flow.getDescription());
|
||||||
versionControlInfoDto.setGroupId(groupId);
|
versionControlInfoDto.setGroupId(groupId);
|
||||||
versionControlInfoDto.setModified(false);
|
|
||||||
versionControlInfoDto.setVersion(snapshotMetadata.getVersion());
|
versionControlInfoDto.setVersion(snapshotMetadata.getVersion());
|
||||||
versionControlInfoDto.setRegistryId(entity.getRegistryId());
|
versionControlInfoDto.setRegistryId(entity.getRegistryId());
|
||||||
versionControlInfoDto.setRegistryName(serviceFacade.getFlowRegistryName(entity.getRegistryId()));
|
versionControlInfoDto.setRegistryName(serviceFacade.getFlowRegistryName(entity.getRegistryId()));
|
||||||
|
|
||||||
final ProcessGroupEntity updatedGroup = serviceFacade.updateProcessGroup(rev, groupId, versionControlInfoDto, flowSnapshot, getIdGenerationSeed().orElse(null), false,
|
final VersionedFlowState flowState = snapshotMetadata.getVersion() == flow.getVersionCount() ? VersionedFlowState.UP_TO_DATE : VersionedFlowState.STALE;
|
||||||
entity.getUpdateDescendantVersionedFlows());
|
versionControlInfoDto.setState(flowState.name());
|
||||||
|
|
||||||
|
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||||
|
final ProcessGroupEntity updatedGroup = serviceFacade.updateProcessGroupContents(user, rev, groupId, versionControlInfoDto, flowSnapshot, getIdGenerationSeed().orElse(null), false,
|
||||||
|
true, entity.getUpdateDescendantVersionedFlows());
|
||||||
final VersionControlInformationDTO updatedVci = updatedGroup.getComponent().getVersionControlInformation();
|
final VersionControlInformationDTO updatedVci = updatedGroup.getComponent().getVersionControlInformation();
|
||||||
|
|
||||||
final VersionControlInformationEntity responseEntity = new VersionControlInformationEntity();
|
final VersionControlInformationEntity responseEntity = new VersionControlInformationEntity();
|
||||||
|
@ -1103,7 +1109,7 @@ public class VersionsResource extends ApplicationResource {
|
||||||
affectedComponents, user, replicateRequest, processGroupEntity, flowSnapshot, request, idGenerationSeed, true, true);
|
affectedComponents, user, replicateRequest, processGroupEntity, flowSnapshot, request, idGenerationSeed, true, true);
|
||||||
|
|
||||||
vcur.markComplete(updatedVersionControlEntity);
|
vcur.markComplete(updatedVersionControlEntity);
|
||||||
} catch (final LifecycleManagementException e) {
|
} catch (final Exception e) {
|
||||||
logger.error("Failed to update flow to new version", e);
|
logger.error("Failed to update flow to new version", e);
|
||||||
vcur.setFailureReason("Failed to update flow to new version due to " + e);
|
vcur.setFailureReason("Failed to update flow to new version due to " + e);
|
||||||
}
|
}
|
||||||
|
@ -1268,7 +1274,7 @@ public class VersionsResource extends ApplicationResource {
|
||||||
affectedComponents, user, replicateRequest, processGroupEntity, flowSnapshot, request, idGenerationSeed, false, true);
|
affectedComponents, user, replicateRequest, processGroupEntity, flowSnapshot, request, idGenerationSeed, false, true);
|
||||||
|
|
||||||
vcur.markComplete(updatedVersionControlEntity);
|
vcur.markComplete(updatedVersionControlEntity);
|
||||||
} catch (final LifecycleManagementException e) {
|
} catch (final Exception e) {
|
||||||
logger.error("Failed to update flow to new version", e);
|
logger.error("Failed to update flow to new version", e);
|
||||||
vcur.setFailureReason("Failed to update flow to new version due to " + e.getMessage());
|
vcur.setFailureReason("Failed to update flow to new version due to " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -1403,15 +1409,14 @@ public class VersionsResource extends ApplicationResource {
|
||||||
final VersionControlInformationDTO vci = new VersionControlInformationDTO();
|
final VersionControlInformationDTO vci = new VersionControlInformationDTO();
|
||||||
vci.setBucketId(metadata.getBucketIdentifier());
|
vci.setBucketId(metadata.getBucketIdentifier());
|
||||||
vci.setBucketName(bucket.getName());
|
vci.setBucketName(bucket.getName());
|
||||||
vci.setCurrent(flowSnapshot.isLatest());
|
|
||||||
vci.setFlowDescription(flow.getDescription());
|
vci.setFlowDescription(flow.getDescription());
|
||||||
vci.setFlowId(flow.getIdentifier());
|
vci.setFlowId(flow.getIdentifier());
|
||||||
vci.setFlowName(flow.getName());
|
vci.setFlowName(flow.getName());
|
||||||
vci.setGroupId(groupId);
|
vci.setGroupId(groupId);
|
||||||
vci.setModified(false);
|
|
||||||
vci.setRegistryId(requestVci.getRegistryId());
|
vci.setRegistryId(requestVci.getRegistryId());
|
||||||
vci.setRegistryName(serviceFacade.getFlowRegistryName(requestVci.getRegistryId()));
|
vci.setRegistryName(serviceFacade.getFlowRegistryName(requestVci.getRegistryId()));
|
||||||
vci.setVersion(metadata.getVersion());
|
vci.setVersion(metadata.getVersion());
|
||||||
|
vci.setState(flowSnapshot.isLatest() ? VersionedFlowState.UP_TO_DATE.name() : VersionedFlowState.STALE.name());
|
||||||
|
|
||||||
serviceFacade.updateProcessGroupContents(user, revision, groupId, vci, flowSnapshot, idGenerationSeed, verifyNotModified, false, updateDescendantVersionedFlows);
|
serviceFacade.updateProcessGroupContents(user, revision, groupId, vci, flowSnapshot, idGenerationSeed, verifyNotModified, false, updateDescendantVersionedFlows);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.web.api.dto;
|
package org.apache.nifi.web.api.dto;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ClassUtils;
|
import org.apache.commons.lang3.ClassUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.action.Action;
|
import org.apache.nifi.action.Action;
|
||||||
|
@ -114,7 +116,6 @@ import org.apache.nifi.provenance.lineage.LineageNode;
|
||||||
import org.apache.nifi.provenance.lineage.ProvenanceEventLineageNode;
|
import org.apache.nifi.provenance.lineage.ProvenanceEventLineageNode;
|
||||||
import org.apache.nifi.registry.ComponentVariableRegistry;
|
import org.apache.nifi.registry.ComponentVariableRegistry;
|
||||||
import org.apache.nifi.registry.flow.FlowRegistry;
|
import org.apache.nifi.registry.flow.FlowRegistry;
|
||||||
import org.apache.nifi.registry.flow.FlowRegistryClient;
|
|
||||||
import org.apache.nifi.registry.flow.VersionControlInformation;
|
import org.apache.nifi.registry.flow.VersionControlInformation;
|
||||||
import org.apache.nifi.registry.flow.VersionedComponent;
|
import org.apache.nifi.registry.flow.VersionedComponent;
|
||||||
import org.apache.nifi.registry.flow.VersionedFlowState;
|
import org.apache.nifi.registry.flow.VersionedFlowState;
|
||||||
|
@ -140,7 +141,6 @@ import org.apache.nifi.reporting.BulletinRepository;
|
||||||
import org.apache.nifi.reporting.ReportingTask;
|
import org.apache.nifi.reporting.ReportingTask;
|
||||||
import org.apache.nifi.scheduling.SchedulingStrategy;
|
import org.apache.nifi.scheduling.SchedulingStrategy;
|
||||||
import org.apache.nifi.util.FormatUtils;
|
import org.apache.nifi.util.FormatUtils;
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
|
||||||
import org.apache.nifi.web.FlowModification;
|
import org.apache.nifi.web.FlowModification;
|
||||||
import org.apache.nifi.web.Revision;
|
import org.apache.nifi.web.Revision;
|
||||||
import org.apache.nifi.web.api.dto.action.ActionDTO;
|
import org.apache.nifi.web.api.dto.action.ActionDTO;
|
||||||
|
@ -192,7 +192,6 @@ import org.apache.nifi.web.api.entity.VariableEntity;
|
||||||
import org.apache.nifi.web.controller.ControllerFacade;
|
import org.apache.nifi.web.controller.ControllerFacade;
|
||||||
import org.apache.nifi.web.revision.RevisionManager;
|
import org.apache.nifi.web.revision.RevisionManager;
|
||||||
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -215,7 +214,6 @@ import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -234,8 +232,6 @@ public final class DtoFactory {
|
||||||
private ControllerServiceProvider controllerServiceProvider;
|
private ControllerServiceProvider controllerServiceProvider;
|
||||||
private EntityFactory entityFactory;
|
private EntityFactory entityFactory;
|
||||||
private Authorizer authorizer;
|
private Authorizer authorizer;
|
||||||
private NiFiProperties properties;
|
|
||||||
private FlowRegistryClient flowRegistryClient;
|
|
||||||
|
|
||||||
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade) {
|
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade) {
|
||||||
final ControllerConfigurationDTO dto = new ControllerConfigurationDTO();
|
final ControllerConfigurationDTO dto = new ControllerConfigurationDTO();
|
||||||
|
@ -2190,23 +2186,17 @@ public final class DtoFactory {
|
||||||
|
|
||||||
|
|
||||||
public Set<ComponentDifferenceDTO> createComponentDifferenceDtos(final FlowComparison comparison) {
|
public Set<ComponentDifferenceDTO> createComponentDifferenceDtos(final FlowComparison comparison) {
|
||||||
return createComponentDifferenceDtos(comparison, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<ComponentDifferenceDTO> createComponentDifferenceDtos(final FlowComparison comparison, final Predicate<FlowDifference> filter) {
|
|
||||||
final Map<ComponentDifferenceDTO, List<DifferenceDTO>> differencesByComponent = new HashMap<>();
|
final Map<ComponentDifferenceDTO, List<DifferenceDTO>> differencesByComponent = new HashMap<>();
|
||||||
|
|
||||||
for (final FlowDifference difference : comparison.getDifferences()) {
|
for (final FlowDifference difference : comparison.getDifferences()) {
|
||||||
if (filter == null || filter.test(difference)) {
|
final ComponentDifferenceDTO componentDiff = createComponentDifference(difference);
|
||||||
final ComponentDifferenceDTO componentDiff = createComponentDifference(difference);
|
final List<DifferenceDTO> differences = differencesByComponent.computeIfAbsent(componentDiff, key -> new ArrayList<>());
|
||||||
final List<DifferenceDTO> differences = differencesByComponent.computeIfAbsent(componentDiff, key -> new ArrayList<>());
|
|
||||||
|
|
||||||
final DifferenceDTO dto = new DifferenceDTO();
|
final DifferenceDTO dto = new DifferenceDTO();
|
||||||
dto.setDifferenceType(difference.getDifferenceType().getDescription());
|
dto.setDifferenceType(difference.getDifferenceType().getDescription());
|
||||||
dto.setDifference(difference.getDescription());
|
dto.setDifference(difference.getDescription());
|
||||||
|
|
||||||
differences.add(dto);
|
differences.add(dto);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Map.Entry<ComponentDifferenceDTO, List<DifferenceDTO>> entry : differencesByComponent.entrySet()) {
|
for (final Map.Entry<ComponentDifferenceDTO, List<DifferenceDTO>> entry : differencesByComponent.entrySet()) {
|
||||||
|
@ -2259,8 +2249,6 @@ public final class DtoFactory {
|
||||||
dto.setFlowName(versionControlInfo.getFlowName());
|
dto.setFlowName(versionControlInfo.getFlowName());
|
||||||
dto.setFlowDescription(versionControlInfo.getFlowDescription());
|
dto.setFlowDescription(versionControlInfo.getFlowDescription());
|
||||||
dto.setVersion(versionControlInfo.getVersion());
|
dto.setVersion(versionControlInfo.getVersion());
|
||||||
dto.setCurrent(versionControlInfo.isCurrent());
|
|
||||||
dto.setModified(versionControlInfo.isModified());
|
|
||||||
|
|
||||||
final VersionedFlowStatus status = versionControlInfo.getStatus();
|
final VersionedFlowStatus status = versionControlInfo.getStatus();
|
||||||
final VersionedFlowState state = status.getState();
|
final VersionedFlowState state = status.getState();
|
||||||
|
@ -3501,8 +3489,6 @@ public final class DtoFactory {
|
||||||
copy.setFlowName(original.getFlowName());
|
copy.setFlowName(original.getFlowName());
|
||||||
copy.setFlowDescription(original.getFlowDescription());
|
copy.setFlowDescription(original.getFlowDescription());
|
||||||
copy.setVersion(original.getVersion());
|
copy.setVersion(original.getVersion());
|
||||||
copy.setCurrent(original.getCurrent());
|
|
||||||
copy.setModified(original.getModified());
|
|
||||||
copy.setState(original.getState());
|
copy.setState(original.getState());
|
||||||
copy.setStateExplanation(original.getStateExplanation());
|
copy.setStateExplanation(original.getStateExplanation());
|
||||||
return copy;
|
return copy;
|
||||||
|
@ -3833,12 +3819,4 @@ public final class DtoFactory {
|
||||||
public void setBulletinRepository(BulletinRepository bulletinRepository) {
|
public void setBulletinRepository(BulletinRepository bulletinRepository) {
|
||||||
this.bulletinRepository = bulletinRepository;
|
this.bulletinRepository = bulletinRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProperties(final NiFiProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFlowRegistryClient(FlowRegistryClient flowRegistryClient) {
|
|
||||||
this.flowRegistryClient = flowRegistryClient;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.nifi.controller.ScheduledState;
|
||||||
import org.apache.nifi.controller.service.ControllerServiceNode;
|
import org.apache.nifi.controller.service.ControllerServiceNode;
|
||||||
import org.apache.nifi.controller.service.ControllerServiceState;
|
import org.apache.nifi.controller.service.ControllerServiceState;
|
||||||
import org.apache.nifi.groups.ProcessGroup;
|
import org.apache.nifi.groups.ProcessGroup;
|
||||||
|
import org.apache.nifi.groups.RemoteProcessGroup;
|
||||||
import org.apache.nifi.registry.flow.FlowRegistry;
|
import org.apache.nifi.registry.flow.FlowRegistry;
|
||||||
import org.apache.nifi.registry.flow.StandardVersionControlInformation;
|
import org.apache.nifi.registry.flow.StandardVersionControlInformation;
|
||||||
import org.apache.nifi.registry.flow.VersionControlInformation;
|
import org.apache.nifi.registry.flow.VersionControlInformation;
|
||||||
|
@ -234,6 +235,10 @@ public class StandardProcessGroupDAO extends ComponentDAO implements ProcessGrou
|
||||||
}
|
}
|
||||||
if (isNotNull(processGroupDTO.getPosition())) {
|
if (isNotNull(processGroupDTO.getPosition())) {
|
||||||
group.setPosition(new Position(processGroupDTO.getPosition().getX(), processGroupDTO.getPosition().getY()));
|
group.setPosition(new Position(processGroupDTO.getPosition().getX(), processGroupDTO.getPosition().getY()));
|
||||||
|
final ProcessGroup parent = group.getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.onComponentModified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isNotNull(comments)) {
|
if (isNotNull(comments)) {
|
||||||
group.setComments(comments);
|
group.setComments(comments);
|
||||||
|
@ -258,8 +263,6 @@ public class StandardProcessGroupDAO extends ComponentDAO implements ProcessGrou
|
||||||
final StandardVersionControlInformation vci = StandardVersionControlInformation.Builder.fromDto(versionControlInformation)
|
final StandardVersionControlInformation vci = StandardVersionControlInformation.Builder.fromDto(versionControlInformation)
|
||||||
.registryName(registryName)
|
.registryName(registryName)
|
||||||
.flowSnapshot(flowSnapshot)
|
.flowSnapshot(flowSnapshot)
|
||||||
.modified(false)
|
|
||||||
.current(true)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
group.setVersionControlInformation(vci, versionedComponentMapping);
|
group.setVersionControlInformation(vci, versionedComponentMapping);
|
||||||
|
@ -281,6 +284,7 @@ public class StandardProcessGroupDAO extends ComponentDAO implements ProcessGrou
|
||||||
|
|
||||||
final ProcessGroup group = locateProcessGroup(flowController, groupId);
|
final ProcessGroup group = locateProcessGroup(flowController, groupId);
|
||||||
group.updateFlow(proposedSnapshot, componentIdSeed, verifyNotModified, updateSettings, updateDescendantVersionedFlows);
|
group.updateFlow(proposedSnapshot, componentIdSeed, verifyNotModified, updateSettings, updateDescendantVersionedFlows);
|
||||||
|
group.findAllRemoteProcessGroups().stream().forEach(RemoteProcessGroup::initialize);
|
||||||
|
|
||||||
final StandardVersionControlInformation svci = StandardVersionControlInformation.Builder.fromDto(versionControlInformation)
|
final StandardVersionControlInformation svci = StandardVersionControlInformation.Builder.fromDto(versionControlInformation)
|
||||||
.flowSnapshot(proposedSnapshot.getFlowContents())
|
.flowSnapshot(proposedSnapshot.getFlowContents())
|
||||||
|
|
|
@ -448,7 +448,10 @@ public class StandardRemoteProcessGroupDAO extends ComponentDAO implements Remot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteProcessGroup.getProcessGroup().onComponentModified();
|
final ProcessGroup group = remoteProcessGroup.getProcessGroup();
|
||||||
|
if (group != null) {
|
||||||
|
group.onComponentModified();
|
||||||
|
}
|
||||||
return remoteProcessGroup;
|
return remoteProcessGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,6 @@
|
||||||
<property name="entityFactory" ref="entityFactory"/>
|
<property name="entityFactory" ref="entityFactory"/>
|
||||||
<property name="authorizer" ref="authorizer"/>
|
<property name="authorizer" ref="authorizer"/>
|
||||||
<property name="bulletinRepository" ref="bulletinRepository"/>
|
<property name="bulletinRepository" ref="bulletinRepository"/>
|
||||||
<property name="properties" ref="nifiProperties"/>
|
|
||||||
<property name="flowRegistryClient" ref="flowRegistryClient" />
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- snippet utils -->
|
<!-- snippet utils -->
|
||||||
|
|
Loading…
Reference in New Issue