This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 49d0760430 NIFI-14442 Show Bundle Version Changes with other Versioned
Flow Differences (#9967)
49d0760430 is described below
commit 49d0760430816c3e3c169ae112906dc59d531d30
Author: Michael Moser <[email protected]>
AuthorDate: Wed Oct 22 15:56:51 2025 -0400
NIFI-14442 Show Bundle Version Changes with other Versioned Flow
Differences (#9967)
Signed-off-by: David Handermann <[email protected]>
---
.../apache/nifi/util/FlowDifferenceFilters.java | 6 ++-
.../apache/nifi/web/StandardNiFiServiceFacade.java | 7 +---
.../org/apache/nifi/web/api/dto/DtoFactory.java | 49 +++++++++++++++++++---
.../local-changes-table/local-changes-table.ts | 2 +-
.../diff/ConciseEvolvingDifferenceDescriptor.java | 23 +++++++---
5 files changed, 68 insertions(+), 19 deletions(-)
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/util/FlowDifferenceFilters.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/util/FlowDifferenceFilters.java
index ea4e8d0ad9..5f8da2e20e 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/util/FlowDifferenceFilters.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/util/FlowDifferenceFilters.java
@@ -83,7 +83,7 @@ public class FlowDifferenceFilters {
public static boolean isEnvironmentalChange(final FlowDifference
difference, final VersionedProcessGroup localGroup, final FlowManager
flowManager,
final
EnvironmentalChangeContext context) {
final EnvironmentalChangeContext evaluatedContext =
Objects.requireNonNull(context, "EnvironmentalChangeContext required");
- return difference.getDifferenceType() == DifferenceType.BUNDLE_CHANGED
+ return isBundleChange(difference)
|| isSensitivePropertyDueToGhosting(difference, flowManager)
|| isRpgUrlChange(difference)
|| isAddedOrRemovedRemotePort(difference)
@@ -106,6 +106,10 @@ public class FlowDifferenceFilters {
|| isSelectedRelationshipChangeForNewRelationship(difference,
flowManager);
}
+ public static boolean isBundleChange(final FlowDifference difference) {
+ return difference.getDifferenceType() == DifferenceType.BUNDLE_CHANGED;
+ }
+
private static boolean isSensitivePropertyDueToGhosting(final
FlowDifference difference, final FlowManager flowManager) {
final DifferenceType differenceType = difference.getDifferenceType();
if (differenceType != DifferenceType.PROPERTY_SENSITIVITY_CHANGED &&
differenceType != DifferenceType.PROPERTY_ADDED) {
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 05c9f63c17..a50cfed673 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -5601,12 +5601,7 @@ public class StandardNiFiServiceFacade implements
NiFiServiceFacade {
+ " but cannot find a Flow Registry with that identifier");
}
- VersionedProcessGroup registryGroup = null;
- final VersionControlInformation vci =
processGroup.getVersionControlInformation();
- if (vci != null) {
- registryGroup = vci.getFlowSnapshot();
- }
-
+ VersionedProcessGroup registryGroup =
versionControlInfo.getFlowSnapshot();
if (registryGroup == null) {
try {
final FlowVersionLocation flowVersionLocation = new
FlowVersionLocation(versionControlInfo.getBranch(),
versionControlInfo.getBucketIdentifier(),
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 1c401ba690..684435065f 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -2799,6 +2799,7 @@ public final class DtoFactory {
public Set<ComponentDifferenceDTO>
createComponentDifferenceDtosForLocalModifications(final FlowComparison
comparison, final VersionedProcessGroup localGroup, final FlowManager
flowManager) {
final Map<ComponentDifferenceDTO, List<DifferenceDTO>>
differencesByComponent = new HashMap<>();
+ final Map<ComponentDifferenceDTO, Set<DifferenceDTO>>
bundleDifferencesByComponent = new HashMap<>();
final Map<String, VersionedProcessGroup> versionedGroups =
flattenProcessGroups(comparison.getFlowA().getContents());
@@ -2807,6 +2808,13 @@ public final class DtoFactory {
FlowDifferenceFilters.buildEnvironmentalChangeContext(comparisonDifferences,
flowManager);
for (final FlowDifference difference : comparisonDifferences) {
+ // capture bundle differences and dedupe those differences
+ if (FlowDifferenceFilters.isBundleChange(difference)) {
+ final ComponentDifferenceDTO componentDiff =
createBundleDifference(difference);
+ final Set<DifferenceDTO> differences =
bundleDifferencesByComponent.computeIfAbsent(componentDiff, key -> new
HashSet<>());
+ differences.add(createDifferenceDto(difference));
+ }
+
// Ignore any environment-specific change
if (FlowDifferenceFilters.isEnvironmentalChange(difference,
localGroup, flowManager, environmentalContext)) {
continue;
@@ -2820,12 +2828,19 @@ public final class DtoFactory {
final ComponentDifferenceDTO componentDiff =
createComponentDifference(difference);
final List<DifferenceDTO> differences =
differencesByComponent.computeIfAbsent(componentDiff, key -> new ArrayList<>());
-
- final DifferenceDTO dto = new DifferenceDTO();
-
dto.setDifferenceType(difference.getDifferenceType().getDescription());
- dto.setDifference(difference.getDescription());
-
- differences.add(dto);
+ differences.add(createDifferenceDto(difference));
+ }
+
+ if (!differencesByComponent.isEmpty()) {
+ // differences were found, so now let's add back in any
BUNDLE_CHANGED differences
+ // since they were initially filtered out as an
environment-specific change
+ bundleDifferencesByComponent.forEach((key, value) -> {
+ List<DifferenceDTO> values = value.stream().toList();
+ differencesByComponent.merge(key, values, (v1, v2) -> {
+ v1.addAll(v2);
+ return v1;
+ });
+ });
}
for (final Map.Entry<ComponentDifferenceDTO, List<DifferenceDTO>> entry
: differencesByComponent.entrySet()) {
@@ -2835,6 +2850,16 @@ public final class DtoFactory {
return differencesByComponent.keySet();
}
+ /*
+ * Create a custom difference with a simpler difference description, only
for matching descriptions.
+ */
+ DifferenceDTO createDifferenceDto(final FlowDifference difference) {
+ final DifferenceDTO dto = new DifferenceDTO();
+ dto.setDifferenceType(difference.getDifferenceType().getDescription());
+ dto.setDifference(difference.getDescription());
+ return dto;
+ }
+
private Map<String, VersionedProcessGroup> flattenProcessGroups(final
VersionedProcessGroup group) {
final Map<String, VersionedProcessGroup> flattened = new HashMap<>();
flattenProcessGroups(group, flattened);
@@ -2849,6 +2874,18 @@ public final class DtoFactory {
}
}
+ private ComponentDifferenceDTO createBundleDifference(final FlowDifference
difference) {
+ VersionedComponent component = difference.getComponentB();
+
+ final ComponentDifferenceDTO dto = new ComponentDifferenceDTO();
+ dto.setComponentType(component.getComponentType().toString());
+ // bundle difference could apply to many components, but use the
Process Group identifier as
+ // the Component Identifier here so that many similar component
differences can be easily deduped
+ dto.setComponentId(component.getGroupIdentifier());
+
+ return dto;
+ }
+
private ComponentDifferenceDTO createComponentDifference(final
FlowDifference difference) {
VersionedComponent component = difference.getComponentA();
if (component == null || difference.getComponentB() instanceof
InstantiatedVersionedComponent) {
diff --git
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts
index e7123f8057..6d38b44c7d 100644
---
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts
+++
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/ui/canvas/items/flow/local-changes-dialog/local-changes-table/local-changes-table.ts
@@ -125,7 +125,7 @@ export class LocalChangesTable implements AfterViewInit {
}
canGoTo(item: LocalChange): boolean {
- return item.differenceType !== 'Component Removed';
+ return (item.differenceType !== 'Component Removed') &&
(item.differenceType !== 'Component Bundle Changed');
}
formatDifference(item: LocalChange): string {
diff --git
a/nifi-registry/nifi-registry-core/nifi-registry-flow-diff/src/main/java/org/apache/nifi/registry/flow/diff/ConciseEvolvingDifferenceDescriptor.java
b/nifi-registry/nifi-registry-core/nifi-registry-flow-diff/src/main/java/org/apache/nifi/registry/flow/diff/ConciseEvolvingDifferenceDescriptor.java
index 2e6cf79a7e..1a26441cc7 100644
---
a/nifi-registry/nifi-registry-core/nifi-registry-flow-diff/src/main/java/org/apache/nifi/registry/flow/diff/ConciseEvolvingDifferenceDescriptor.java
+++
b/nifi-registry/nifi-registry-core/nifi-registry-flow-diff/src/main/java/org/apache/nifi/registry/flow/diff/ConciseEvolvingDifferenceDescriptor.java
@@ -20,6 +20,7 @@ package org.apache.nifi.registry.flow.diff;
import org.apache.nifi.flow.ScheduledState;
import org.apache.nifi.flow.VersionedComponent;
import org.apache.nifi.flow.VersionedFlowCoordinates;
+import org.apache.nifi.flow.VersionedProcessor;
import java.util.Objects;
@@ -72,9 +73,7 @@ public class ConciseEvolvingDifferenceDescriptor implements
DifferenceDescriptor
description = "Connection Bendpoints changed";
break;
case VERSIONED_FLOW_COORDINATES_CHANGED:
- if (valueA instanceof VersionedFlowCoordinates && valueB
instanceof VersionedFlowCoordinates) {
- final VersionedFlowCoordinates coordinatesA =
(VersionedFlowCoordinates) valueA;
- final VersionedFlowCoordinates coordinatesB =
(VersionedFlowCoordinates) valueB;
+ if (valueA instanceof VersionedFlowCoordinates coordinatesA &&
valueB instanceof VersionedFlowCoordinates coordinatesB) {
// If the two vary only by version, then use a more
concise message. If anything else is different, then use a fully explanation.
if (Objects.equals(coordinatesA.getStorageLocation(),
coordinatesB.getStorageLocation()) &&
Objects.equals(coordinatesA.getBucketId(), coordinatesB.getBucketId())
@@ -85,14 +84,28 @@ public class ConciseEvolvingDifferenceDescriptor implements
DifferenceDescriptor
}
}
- description = String.format("From '%s' to '%s'", valueA,
valueB);
+ description = defaultDescription(valueA, valueB);
+ break;
+ case BUNDLE_CHANGED:
+ if (componentA instanceof VersionedProcessor processorA &&
componentB instanceof VersionedProcessor processorB) {
+ String artifact = processorA.getBundle().getArtifact();
+ String versionA = processorA.getBundle().getVersion();
+ String versionB = processorB.getBundle().getVersion();
+ description = String.format("%s version %s to %s",
artifact, versionA, versionB);
+ break;
+ }
+
+ description = defaultDescription(valueA, valueB);
break;
default:
- description = String.format("From '%s' to '%s'", valueA,
valueB);
+ description = defaultDescription(valueA, valueB);
break;
}
return description;
}
+ private String defaultDescription(Object valueA, Object valueB) {
+ return String.format("From '%s' to '%s'", valueA, valueB);
+ }
}