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 51a07427d9 NIFI-14478 Fixed Modification Tracking for Pasted Versioned 
Process Groups (#9894)
51a07427d9 is described below

commit 51a07427d99a69568605920f06ac7f9d3e229da8
Author: Michael Moser <[email protected]>
AuthorDate: Sat Sep 6 21:18:51 2025 -0400

    NIFI-14478 Fixed Modification Tracking for Pasted Versioned Process Groups 
(#9894)
    
    - Removed ability for a version controlled Process Group to be compared 
against anything but the version from the Flow Registry
    
    Signed-off-by: David Handermann <[email protected]>
---
 .../StandardVersionedComponentSynchronizer.java    |  2 +-
 .../apache/nifi/groups/StandardProcessGroup.java   |  1 -
 .../nifi/groups/FlowSynchronizationOptions.java    | 22 ------------------
 .../flow/StandardStatelessGroupNodeFactory.java    |  1 -
 .../serialization/VersionedFlowSynchronizer.java   |  1 -
 .../apache/nifi/tests/system/pg/CopyPasteIT.java   | 27 ++++++++++++++++++++++
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
index 7623bdd504..b79ee4d6e8 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
@@ -517,7 +517,7 @@ public class StandardVersionedComponentSynchronizer 
implements VersionedComponen
                     .storageLocation(storageLocation)
                     .flowName(flowId)
                     .version(version)
-                    
.flowSnapshot(syncOptions.isUpdateGroupVersionControlSnapshot() ? proposed : 
null)
+                    .flowSnapshot(null)
                     .status(new StandardVersionedFlowStatus(flowState, 
flowState.getDescription()))
                     .build();
 
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
index cc1928a070..54436ada0d 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
@@ -3846,7 +3846,6 @@ public final class StandardProcessGroup implements 
ProcessGroup {
             .ignoreLocalModifications(!verifyNotDirty)
             .updateDescendantVersionedFlows(updateDescendantVersionedFlows)
             .updateGroupSettings(updateSettings)
-            .updateGroupVersionControlSnapshot(true)
             .updateRpgUrls(false)
             .propertyDecryptor(value -> null)
             .build();
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
index f609a8b88b..b857f07f05 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
@@ -30,7 +30,6 @@ public class FlowSynchronizationOptions {
     private final boolean ignoreLocalModifications;
     private final boolean updateSettings;
     private final boolean updateDescendantVersionedFlows;
-    private final boolean updateGroupVersionControlSnapshot;
     private final boolean updateRpgUrls;
     private final Duration componentStopTimeout;
     private final ComponentStopTimeoutAction timeoutAction;
@@ -45,7 +44,6 @@ public class FlowSynchronizationOptions {
         this.ignoreLocalModifications = builder.ignoreLocalModifications;
         this.updateSettings = builder.updateSettings;
         this.updateDescendantVersionedFlows = 
builder.updateDescendantVersionedFlows;
-        this.updateGroupVersionControlSnapshot = 
builder.updateGroupVersionControlSnapshot;
         this.updateRpgUrls = builder.updateRpgUrls;
         this.componentStopTimeout = builder.componentStopTimeout;
         this.timeoutAction = builder.timeoutAction;
@@ -77,10 +75,6 @@ public class FlowSynchronizationOptions {
         return updateDescendantVersionedFlows;
     }
 
-    public boolean isUpdateGroupVersionControlSnapshot() {
-        return updateGroupVersionControlSnapshot;
-    }
-
     public boolean isUpdateRpgUrls() {
         return updateRpgUrls;
     }
@@ -112,7 +106,6 @@ public class FlowSynchronizationOptions {
         private boolean ignoreLocalModifications = false;
         private boolean updateSettings = true;
         private boolean updateDescendantVersionedFlows = true;
-        private boolean updateGroupVersionControlSnapshot = true;
         private boolean updateRpgUrls = false;
         private ScheduledStateChangeListener scheduledStateChangeListener;
         private PropertyDecryptor propertyDecryptor = value -> value;
@@ -183,20 +176,6 @@ public class FlowSynchronizationOptions {
             return this;
         }
 
-        /**
-         * When a Process Group is version controlled, it tracks whether or 
not there are any local modifications by comparing the current dataflow
-         * to a snapshot of what the Versioned Flow looks like. If this value 
is set to <code>true</code>, when the Process Group is synchronized
-         * with a VersionedProcessGroup, that VersionedProcessGroup will 
become the snapshot of what the Versioned Flow looks like. If 
<code>false</code>,
-         * the snapshot is not updated.
-         *
-         * @param updateGroupVersionControlSnapshot <code>true</code> to 
update the snapshot, <code>false</code> otherwise
-         * @return the builder
-         */
-        public Builder updateGroupVersionControlSnapshot(final boolean 
updateGroupVersionControlSnapshot) {
-            this.updateGroupVersionControlSnapshot = 
updateGroupVersionControlSnapshot;
-            return this;
-        }
-
         /**
          * Specifies whether or not the URLs / "Target URIs" of a Remote 
Process Group that exists in both the proposed flow and the current flow
          * should be updated to match that of the proposed flow
@@ -285,7 +264,6 @@ public class FlowSynchronizationOptions {
             builder.ignoreLocalModifications = 
options.isIgnoreLocalModifications();
             builder.updateSettings = options.isUpdateSettings();
             builder.updateDescendantVersionedFlows = 
options.isUpdateDescendantVersionedFlows();
-            builder.updateGroupVersionControlSnapshot = 
options.isUpdateGroupVersionControlSnapshot();
             builder.updateRpgUrls = options.isUpdateRpgUrls();
             builder.propertyDecryptor = options.getPropertyDecryptor();
             builder.componentStopTimeout = options.getComponentStopTimeout();
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
index 41568ed9a2..879023445a 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
@@ -293,7 +293,6 @@ public class StandardStatelessGroupNodeFactory implements 
StatelessGroupNodeFact
             .topLevelGroupId(group.getIdentifier())
             .updateDescendantVersionedFlows(true)
             .updateGroupSettings(true)
-            .updateGroupVersionControlSnapshot(false)
             .updateRpgUrls(true)
             .ignoreLocalModifications(true)
             .build();
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
index 68b2713048..61a586edd8 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
@@ -445,7 +445,6 @@ public class VersionedFlowSynchronizer implements 
FlowSynchronizer {
                     .ignoreLocalModifications(true)
                     .updateGroupSettings(true)
                     .updateDescendantVersionedFlows(true)
-                    .updateGroupVersionControlSnapshot(false)
                     .updateRpgUrls(true)
                     .propertyDecryptor(encryptor::decrypt)
                     .build();
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
index c86b4f619c..f66c800695 100644
--- 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
@@ -402,4 +402,31 @@ public class CopyPasteIT extends NiFiSystemIT {
         assertNotEquals(terminate1.getComponent().getId(), 
terminate2.getComponent().getId());
         assertEquals(terminate1.getComponent().getVersionedComponentId(), 
terminate2.getComponent().getVersionedComponentId());
     }
+
+    @Test
+    public void testCopyPasteVersionControlledProcessGroupWithLocalChanges()  
throws NiFiClientException, IOException, InterruptedException {
+        // Create a top-level PG and version it with nothing in it.
+        final FlowRegistryClientEntity clientEntity = registerClient();
+        final ProcessGroupEntity topLevel1 = 
getClientUtil().createProcessGroup("Top Level 1", "root");
+
+        // Create a lower level PG and add a Processor.  Commit as Version 1 
of the PG.
+        final ProcessGroupEntity innerGroup = 
getClientUtil().createProcessGroup("Inner 1", topLevel1.getId());
+        ProcessorEntity terminate1 = 
getClientUtil().createProcessor("TerminateFlowFile", innerGroup.getId());
+        VersionControlInformationEntity vciEntity = 
getClientUtil().startVersionControl(innerGroup, clientEntity, 
TEST_FLOWS_BUCKET, FIRST_FLOW_ID);
+        assertEquals("1", 
vciEntity.getVersionControlInformation().getVersion());
+
+        // Modify the processor and wait for the group to show it has local 
changes
+        getClientUtil().updateProcessorSchedulingPeriod(terminate1, "2 mins");
+        waitFor(() -> 
VersionControlInformationDTO.LOCALLY_MODIFIED.equals(getClientUtil().getVersionControlState(innerGroup.getId())));
+
+        // Copy the versioned and modified process group and paste it to a new 
PG.
+        final ProcessGroupEntity topLevel2 = 
getClientUtil().createProcessGroup("Top Level 2", "root");
+        final CopyRequestEntity copyRequestEntity = new CopyRequestEntity();
+        copyRequestEntity.setProcessGroups(Set.of(innerGroup.getId()));
+        final FlowDTO flowDto = 
getClientUtil().copyAndPaste(topLevel1.getId(), copyRequestEntity, 
topLevel2.getRevision(), topLevel2.getId());
+
+        // The new PG should also show as being locally modified from Version 
1 of the PG
+        final String pastedGroupId = 
flowDto.getProcessGroups().iterator().next().getId();
+        waitFor(() -> 
VersionControlInformationDTO.LOCALLY_MODIFIED.equals(getClientUtil().getVersionControlState(pastedGroupId)));
+    }
 }

Reply via email to