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 12633c596c8 NIFI-15841 Relaxed versioning of a parent Process Group 
with locally modified child groups (#11145)
12633c596c8 is described below

commit 12633c596c867e513cf56685f299a3d72352a1f1
Author: Pierre Villard <[email protected]>
AuthorDate: Mon Jun 1 07:00:31 2026 -0700

    NIFI-15841 Relaxed versioning of a parent Process Group with locally 
modified child groups (#11145)
    
    Signed-off-by: David Handermann <[email protected]>
---
 .../apache/nifi/groups/StandardProcessGroup.java   |  2 -
 .../tests/system/registry/RegistryClientIT.java    | 45 ++++++++++++++++++++++
 2 files changed, 45 insertions(+), 2 deletions(-)

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 c6de28a3083..af0992b2582 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
@@ -4210,8 +4210,6 @@ public final class StandardProcessGroup implements 
ProcessGroup {
 
     @Override
     public void verifyCanSaveToFlowRegistry(final String registryId, final 
FlowLocation flowLocation, final String saveAction) {
-        verifyNoDescendantsWithLocalModifications("be saved to a Flow 
Registry");
-
         final StandardVersionControlInformation vci = versionControlInfo.get();
         if (vci != null) {
             final String flowId = flowLocation.getFlowId();
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/registry/RegistryClientIT.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/registry/RegistryClientIT.java
index d9876ceb725..4903372c5b2 100644
--- 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/registry/RegistryClientIT.java
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/registry/RegistryClientIT.java
@@ -550,6 +550,51 @@ public class RegistryClientIT extends NiFiSystemIT {
         }
     }
 
+    /**
+     * Test that a parent Process Group can be committed to a Flow Registry 
even when a child Process Group
+     * that is separately under Version Control has local modifications. The 
parent's snapshot only stores
+     * version coordinate references for child versioned PGs, so uncommitted 
changes in the child are
+     * irrelevant to the parent's save operation.
+     *
+     * Scenario:
+     * 1. Create parent PG with a processor and child PG with a processor
+     * 2. Commit child PG (v1), then commit parent PG (v1)
+     * 3. Modify a processor in the child PG so the child becomes 
LOCALLY_MODIFIED
+     * 4. Commit the parent PG as v2 -- this should succeed
+     */
+    @Test
+    public void testSaveParentFlowVersionWithLocallyModifiedChild() throws 
NiFiClientException, IOException, InterruptedException {
+        final FlowRegistryClientEntity clientEntity = registerClient();
+        final NiFiClientUtil util = getClientUtil();
+
+        final ProcessGroupEntity parent = util.createProcessGroup("Parent", 
"root");
+        final ProcessorEntity parentProcessor = 
util.createProcessor("GenerateFlowFile", parent.getId());
+
+        final ProcessGroupEntity child = util.createProcessGroup("Child", 
parent.getId());
+        final ProcessorEntity childProcessor = 
util.createProcessor("TerminateFlowFile", child.getId());
+
+        final VersionControlInformationEntity childVci = 
util.startVersionControl(child, clientEntity, TEST_FLOWS_BUCKET, "Child");
+        assertEquals("1", 
childVci.getVersionControlInformation().getVersion());
+
+        final VersionControlInformationEntity parentVci = 
util.startVersionControl(parent, clientEntity, TEST_FLOWS_BUCKET, "Parent");
+        assertEquals("1", 
parentVci.getVersionControlInformation().getVersion());
+
+        util.assertFlowUpToDate(parent.getId());
+        util.assertFlowUpToDate(child.getId());
+
+        util.updateProcessorSchedulingPeriod(childProcessor, "2 min");
+        waitFor(() -> 
VersionControlInformationDTO.LOCALLY_MODIFIED.equals(util.getVersionControlState(child.getId())));
+
+        util.updateProcessorProperties(parentProcessor, 
Collections.singletonMap("Text", "Modified"));
+
+        final VersionControlInformationEntity parentV2 = 
util.saveFlowVersion(parent, clientEntity, parentVci);
+        assertEquals("2", 
parentV2.getVersionControlInformation().getVersion());
+
+        util.assertFlowUpToDate(parent.getId());
+
+        assertEquals(VersionControlInformationDTO.LOCALLY_MODIFIED, 
util.getVersionControlState(child.getId()));
+    }
+
     @Test
     public void testStopVersionControlThenSetVersionControlInfo() throws 
NiFiClientException, IOException, InterruptedException {
         final FlowRegistryClientEntity clientEntity = registerClient();

Reply via email to