This is an automated email from the ASF dual-hosted git repository.

pvillard 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 dd8b87f6f9 NIFI-14550 Allow setting version control info on a 
non-versioned process group - Update stopVersionControl to no longer clear 
versioned component ids in order to allow re-attaching later - Add new methods 
to service facade and PG DAO to pass the flow snapshot when setting VCI - Fix 
system test to ensure UP_TO_DATE after Set Version Info
dd8b87f6f9 is described below

commit dd8b87f6f9f374f367666d4311199bbdf29cd2e2
Author: Bryan Bende <[email protected]>
AuthorDate: Thu May 8 15:57:28 2025 -0400

    NIFI-14550 Allow setting version control info on a non-versioned process 
group
    - Update stopVersionControl to no longer clear versioned component ids in 
order to allow re-attaching later
    - Add new methods to service facade and PG DAO to pass the flow snapshot 
when setting VCI
    - Fix system test to ensure UP_TO_DATE after Set Version Info
    
    Signed-off-by: Pierre Villard <[email protected]>
    
    This closes #9930.
---
 .../StandardVersionedComponentSynchronizer.java    |  2 +-
 .../apache/nifi/groups/StandardProcessGroup.java   |  7 +--
 .../java/org/apache/nifi/groups/ProcessGroup.java  |  2 +-
 .../controller/service/mock/MockProcessGroup.java  |  2 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java     | 10 +++
 .../apache/nifi/web/StandardNiFiServiceFacade.java | 15 +++++
 .../apache/nifi/web/api/ProcessGroupResource.java  | 38 +++++++++++-
 .../org/apache/nifi/web/api/dto/DtoFactory.java    |  1 -
 .../org/apache/nifi/web/dao/ProcessGroupDAO.java   | 10 +++
 .../nifi/web/dao/impl/StandardProcessGroupDAO.java | 71 ++++++++++++++++++----
 .../registry/FileSystemFlowRegistryClient.java     |  3 +
 .../tests/system/registry/RegistryClientIT.java    | 46 ++++++++++++++
 12 files changed, 183 insertions(+), 24 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 3cc325862f..87f3f28e04 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
@@ -486,7 +486,7 @@ public class StandardVersionedComponentSynchronizer 
implements VersionedComponen
 
         final VersionedFlowCoordinates remoteCoordinates = 
proposed.getVersionedFlowCoordinates();
         if (remoteCoordinates == null) {
-            group.disconnectVersionControl(false);
+            group.disconnectVersionControl();
         } else {
             final String registryId = determineRegistryId(remoteCoordinates);
             final String branch = remoteCoordinates.getBranch();
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 786b8313f7..75af997977 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
@@ -3642,15 +3642,10 @@ public final class StandardProcessGroup implements 
ProcessGroup {
     }
 
     @Override
-    public void disconnectVersionControl(final boolean 
removeVersionedComponentIds) {
+    public void disconnectVersionControl() {
         writeLock.lock();
         try {
             this.versionControlInfo.set(null);
-
-            if (removeVersionedComponentIds) {
-                // remove version component ids from each component (until 
another versioned PG is encountered)
-                applyVersionedComponentIds(this, id -> null);
-            }
         } finally {
             writeLock.unlock();
         }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
index 510d7905a7..4a53e453f2 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java
@@ -1039,7 +1039,7 @@ public interface ProcessGroup extends 
ComponentAuthorizable, Positionable, Versi
     /**
      * Disconnects this Process Group from version control. If not currently 
under version control, this method does nothing.
      */
-    void disconnectVersionControl(boolean removeVersionedComponentIds);
+    void disconnectVersionControl();
 
     /**
      * Synchronizes the Process Group with the given Flow Registry, 
determining whether or not the local flow
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
index 9d153ecb7e..f96964bf44 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java
@@ -725,7 +725,7 @@ public class MockProcessGroup implements ProcessGroup {
     }
 
     @Override
-    public void disconnectVersionControl(final boolean 
removeVersionedComponentIds) {
+    public void disconnectVersionControl() {
         this.versionControlInfo = null;
     }
 
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index 708995fb86..84237e2757 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -1278,6 +1278,16 @@ public interface NiFiServiceFacade {
      */
     ProcessGroupEntity updateProcessGroup(Revision revision, ProcessGroupDTO 
processGroupDTO);
 
+    /**
+     * Sets the version control info of an unversioned process group.
+     *
+     * @param revision Revision to compare with the current base version
+     * @param processGroupDTO The ProcessGroupDTO
+     * @param flowSnapshot The flow snapshot matching the given version 
control info
+     * @return the updated process group entity
+     */
+    ProcessGroupEntity setVersionControlInformation(Revision revision, 
ProcessGroupDTO processGroupDTO, RegisteredFlowSnapshot flowSnapshot);
+
     /**
      * Verifies that the Process Group identified by the given DTO can be 
updated in the manner appropriate according
      * to the DTO
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 230b8bf432..684313d038 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
@@ -1821,6 +1821,21 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         return entityFactory.createProcessGroupEntity(snapshot.getComponent(), 
updatedRevision, permissions, status, bulletinEntities);
     }
 
+    @Override
+    public ProcessGroupEntity setVersionControlInformation(final Revision 
revision, final ProcessGroupDTO processGroupDTO, final RegisteredFlowSnapshot 
flowSnapshot) {
+        final ProcessGroup processGroupNode = 
processGroupDAO.getProcessGroup(processGroupDTO.getId());
+        final RevisionUpdate<ProcessGroupDTO> snapshot = 
updateComponent(revision,
+            processGroupNode,
+            () -> 
processGroupDAO.setVersionControlInformation(processGroupDTO, flowSnapshot),
+            processGroup -> dtoFactory.createProcessGroupDto(processGroup));
+
+        final PermissionsDTO permissions = 
dtoFactory.createPermissionsDto(processGroupNode);
+        final RevisionDTO updatedRevision = 
dtoFactory.createRevisionDTO(snapshot.getLastModification());
+        final ProcessGroupStatusDTO status = 
dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroupNode.getIdentifier()));
+        final List<BulletinEntity> bulletinEntities = 
getProcessGroupBulletins(processGroupNode);
+        return entityFactory.createProcessGroupEntity(snapshot.getComponent(), 
updatedRevision, permissions, status, bulletinEntities);
+    }
+
     @Override
     public void verifyUpdateProcessGroup(ProcessGroupDTO processGroupDTO) {
         if (processGroupDAO.hasProcessGroup(processGroupDTO.getId())) {
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index fc22bbdbff..145baaf47f 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -516,6 +516,34 @@ public class ProcessGroupResource extends 
FlowUpdateResource<ProcessGroupImportE
             updateStrategy = 
ProcessGroupRecursivity.valueOf(processGroupUpdateStrategy);
         }
 
+        final VersionControlInformationDTO versionControlInfo = 
requestProcessGroupDTO.getVersionControlInformation();
+        if (versionControlInfo != null) {
+            if (updateStrategy == ProcessGroupRecursivity.ALL_DESCENDANTS) {
+                throw new IllegalArgumentException("Version Control 
Information cannot be specified when applying updates recursively");
+            }
+
+            if (StringUtils.isBlank(versionControlInfo.getRegistryId())
+                || StringUtils.isBlank(versionControlInfo.getBucketId())
+                || StringUtils.isBlank(versionControlInfo.getFlowId())
+                || StringUtils.isBlank(versionControlInfo.getVersion())) {
+                throw new IllegalArgumentException("Version Control 
Information must contain a registry id, bucket id, flow id, and version");
+            }
+
+            final FlowSnapshotContainer flowSnapshotContainer = 
getFlowFromRegistry(versionControlInfo);
+            final RegisteredFlowSnapshot flowSnapshot = 
flowSnapshotContainer.getFlowSnapshot();
+            if (flowSnapshot.getFlowContents() != null) {
+                final VersionedFlowCoordinates versionedFlowCoordinates = 
flowSnapshot.getFlowContents().getVersionedFlowCoordinates();
+                if (versionedFlowCoordinates != null) {
+                    
versionControlInfo.setStorageLocation(versionedFlowCoordinates.getStorageLocation());
+                }
+            }
+            if (flowSnapshot.getSnapshotMetadata() != null && 
flowSnapshot.getSnapshotMetadata().getBranch() != null && 
versionControlInfo.getBranch() == null) {
+                
versionControlInfo.setBranch(flowSnapshot.getSnapshotMetadata().getBranch());
+            }
+            versionControlInfo.setGroupId(requestProcessGroupDTO.getId());
+            requestProcessGroupEntity.setVersionedFlowSnapshot(flowSnapshot);
+        }
+
         final String executionEngine = 
requestProcessGroupDTO.getExecutionEngine();
         if (executionEngine != null) {
             try {
@@ -630,7 +658,15 @@ public class ProcessGroupResource extends 
FlowUpdateResource<ProcessGroupImportE
                         final ProcessGroupEntity entity = 
serviceFacade.updateProcessGroup(revision, groupDTO);
 
                         if (requestGroupId.equals(entity.getId())) {
-                            responseEntity = entity;
+                            final VersionControlInformationDTO vciDto = 
entry.getKey().getComponent().getVersionControlInformation();
+                            final RegisteredFlowSnapshot flowSnapshot = 
entry.getKey().getVersionedFlowSnapshot();
+                            if (vciDto != null && flowSnapshot != null) {
+                                final Revision updatedRevision = 
getRevision(entity.getRevision(), entity.getId());
+                                responseEntity = 
serviceFacade.setVersionControlInformation(updatedRevision, groupDTO, 
flowSnapshot);
+                            } else {
+                                responseEntity = entity;
+                            }
+
                             
populateRemainingProcessGroupEntityContent(responseEntity);
 
                             // prune response as necessary
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 801d6cad76..482a899f35 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
@@ -2928,7 +2928,6 @@ public final class DtoFactory {
        return mapping;
    }
 
-
    /**
     * Creates a ProcessGroupContentDTO from the specified ProcessGroup.
     *
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
index ede838a5b8..c10f6145ca 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ProcessGroupDAO.java
@@ -23,6 +23,7 @@ import org.apache.nifi.flow.VersionedExternalFlow;
 import org.apache.nifi.groups.ComponentAdditions;
 import org.apache.nifi.groups.ProcessGroup;
 import org.apache.nifi.groups.VersionedComponentAdditions;
+import org.apache.nifi.registry.flow.RegisteredFlowSnapshot;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
 import org.apache.nifi.web.api.entity.ProcessGroupRecursivity;
@@ -136,6 +137,15 @@ public interface ProcessGroupDAO {
      */
     ProcessGroup updateProcessGroup(ProcessGroupDTO processGroup);
 
+    /**
+     * Sets the version control info on an unversioned process group.
+     *
+     * @param processGroup the process group with the version control info 
specified
+     * @param flowSnapshot the flow snapshot for the given version control info
+     * @return the updated process group
+     */
+    ProcessGroup setVersionControlInformation(ProcessGroupDTO processGroup, 
RegisteredFlowSnapshot flowSnapshot);
+
     /**
      * Updates the process group so that it matches the proposed flow
      *
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
index fa9eafa520..182985a16b 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardProcessGroupDAO.java
@@ -39,8 +39,10 @@ import org.apache.nifi.groups.RemoteProcessGroup;
 import org.apache.nifi.groups.VersionedComponentAdditions;
 import org.apache.nifi.parameter.ParameterContext;
 import org.apache.nifi.registry.flow.FlowRegistryClientNode;
+import org.apache.nifi.registry.flow.RegisteredFlowSnapshot;
 import org.apache.nifi.registry.flow.StandardVersionControlInformation;
 import org.apache.nifi.registry.flow.VersionControlInformation;
+import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedProcessGroup;
 import org.apache.nifi.registry.flow.mapping.NiFiRegistryFlowMapper;
 import org.apache.nifi.remote.RemoteGroupPort;
 import org.apache.nifi.web.ResourceNotFoundException;
@@ -124,19 +126,47 @@ public class StandardProcessGroupDAO extends ComponentDAO 
implements ProcessGrou
 
     @Override
     public void verifyUpdate(final ProcessGroupDTO processGroup) {
+        final ProcessGroup group = locateProcessGroup(flowController, 
processGroup.getId());
+        verifyCanSetParameterContext(processGroup, group);
+
+        final String executionEngine = processGroup.getExecutionEngine();
+        if (executionEngine != null) {
+            
group.verifyCanSetExecutionEngine(ExecutionEngine.valueOf(executionEngine));
+        }
+
+        final VersionControlInformationDTO versionControlInfoDTO = 
processGroup.getVersionControlInformation();
+        final VersionControlInformation versionControlInformation = 
group.getVersionControlInformation();
+        if (versionControlInfoDTO != null) {
+            if (versionControlInformation != null) {
+                throw new IllegalStateException("Cannot set Version Control 
Info because process group is already under version control");
+            }
+            
verifyChildProcessGroupsNotUnderVersionControl(group.getProcessGroups());
+        }
+    }
+
+    private void verifyChildProcessGroupsNotUnderVersionControl(final 
Set<ProcessGroup> childGroups) {
+        if (childGroups == null || childGroups.isEmpty()) {
+            return;
+        }
+
+        for (final ProcessGroup childGroup : childGroups) {
+            final VersionControlInformation versionControlInformation = 
childGroup.getVersionControlInformation();
+            if (versionControlInformation != null) {
+                throw new IllegalStateException("Cannot set Version Control 
Info because a child process group is already under version control");
+            }
+            
verifyChildProcessGroupsNotUnderVersionControl(childGroup.getProcessGroups());
+        }
+    }
+
+    private void verifyCanSetParameterContext(final ProcessGroupDTO 
processGroup, final ProcessGroup group) {
         final ParameterContextReferenceEntity parameterContextReference = 
processGroup.getParameterContext();
         if (parameterContextReference == null) {
             return;
         }
 
         final ParameterContext parameterContext = 
locateParameterContext(parameterContextReference.getId());
-        final ProcessGroup group = locateProcessGroup(flowController, 
processGroup.getId());
-        group.verifyCanSetParameterContext(parameterContext);
 
-        final String executionEngine = processGroup.getExecutionEngine();
-        if (executionEngine != null) {
-            
group.verifyCanSetExecutionEngine(ExecutionEngine.valueOf(executionEngine));
-        }
+        group.verifyCanSetParameterContext(parameterContext);
     }
 
     private ParameterContext locateParameterContext(final String id) {
@@ -481,33 +511,48 @@ public class StandardProcessGroupDAO extends ComponentDAO 
implements ProcessGrou
         return group;
     }
 
+    @Override
+    public ProcessGroup setVersionControlInformation(final ProcessGroupDTO 
processGroup, final RegisteredFlowSnapshot flowSnapshot) {
+        final ProcessGroup group = locateProcessGroup(flowController, 
processGroup.getId());
+        final VersionControlInformationDTO versionControlInfo = 
processGroup.getVersionControlInformation();
+        final VersionedProcessGroup versionedProcessGroup = 
flowSnapshot.getFlowContents();
+        updateVersionControlInformation(group, versionedProcessGroup, 
versionControlInfo, Collections.emptyMap());
+        return group;
+    }
+
     @Override
     public ProcessGroup updateVersionControlInformation(final 
VersionControlInformationDTO versionControlInformation, final Map<String, 
String> versionedComponentMapping) {
         final String groupId = versionControlInformation.getGroupId();
         final ProcessGroup group = locateProcessGroup(flowController, groupId);
 
+        final NiFiRegistryFlowMapper mapper = new 
NiFiRegistryFlowMapper(flowController.getExtensionManager());
+        final InstantiatedVersionedProcessGroup flowSnapshot = 
mapper.mapProcessGroup(group, flowController.getControllerServiceProvider(), 
flowController.getFlowManager(), false);
+
+        updateVersionControlInformation(group, flowSnapshot, 
versionControlInformation, versionedComponentMapping);
+        group.onComponentModified();
+
+        return group;
+    }
+
+    private void updateVersionControlInformation(final ProcessGroup group, 
final VersionedProcessGroup flowSnapshot,
+        final VersionControlInformationDTO versionControlInformation, final 
Map<String, String> versionedComponentMapping) {
+
         final String registryId = versionControlInformation.getRegistryId();
         final FlowRegistryClientNode flowRegistry = 
flowController.getFlowManager().getFlowRegistryClient(registryId);
         final String registryName = flowRegistry == null ? registryId : 
flowRegistry.getName();
 
-        final NiFiRegistryFlowMapper mapper = new 
NiFiRegistryFlowMapper(flowController.getExtensionManager());
-        final VersionedProcessGroup flowSnapshot = 
mapper.mapProcessGroup(group, flowController.getControllerServiceProvider(), 
flowController.getFlowManager(), false);
-
         final StandardVersionControlInformation vci = 
StandardVersionControlInformation.Builder.fromDto(versionControlInformation)
             .registryName(registryName)
             .flowSnapshot(flowSnapshot)
             .build();
 
         group.setVersionControlInformation(vci, versionedComponentMapping);
-        group.onComponentModified();
-
-        return group;
     }
 
     @Override
     public ProcessGroup disconnectVersionControl(final String groupId) {
         final ProcessGroup group = locateProcessGroup(flowController, groupId);
-        group.disconnectVersionControl(true);
+        group.disconnectVersionControl();
         group.onComponentModified();
         return group;
     }
diff --git 
a/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions/src/main/java/org/apache/nifi/flow/registry/FileSystemFlowRegistryClient.java
 
b/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions/src/main/java/org/apache/nifi/flow/registry/FileSystemFlowRegistryClient.java
index f0620605ef..bf7fbcfb42 100644
--- 
a/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions/src/main/java/org/apache/nifi/flow/registry/FileSystemFlowRegistryClient.java
+++ 
b/nifi-system-tests/nifi-system-test-extensions-bundle/nifi-system-test-extensions/src/main/java/org/apache/nifi/flow/registry/FileSystemFlowRegistryClient.java
@@ -238,6 +238,9 @@ public class FileSystemFlowRegistryClient extends 
AbstractFlowRegistryClient {
             populateBucket(snapshot, bucketId);
             populateFlow(snapshot, bucketId, flowId, versionFiles == null ? 0 
: versionFiles.length);
 
+            final String latestVersion = getLatestVersion(context, 
flowVersionLocation).orElse(null);
+            snapshot.setLatest(version.equals(latestVersion));
+
             return snapshot;
         }
     }
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 874fd21e1b..997885860f 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
@@ -25,6 +25,7 @@ import org.apache.nifi.web.api.dto.FlowSnippetDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.dto.SnippetDTO;
+import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
 import org.apache.nifi.web.api.dto.flow.FlowDTO;
 import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
 import org.apache.nifi.web.api.entity.ConnectionEntity;
@@ -369,4 +370,49 @@ public class RegistryClientIT extends NiFiSystemIT {
         assertEquals("UP_TO_DATE", versionedFlowState);
     }
 
+    @Test
+    public void testStopVersionControlThenSetVersionControlInfo() throws 
NiFiClientException, IOException, InterruptedException {
+        final FlowRegistryClientEntity clientEntity = registerClient();
+        final ProcessGroupEntity group = 
getClientUtil().createProcessGroup("Test Set Version Control Info", "root");
+
+        final VersionControlInformationEntity vci = 
getClientUtil().startVersionControl(group, clientEntity, TEST_FLOWS_BUCKET, 
FIRST_FLOW_ID);
+
+        // Retrieve PG under version control and verify the PG's VCI
+        final ProcessGroupEntity groupAfterStartVersionControl = 
getNifiClient().getProcessGroupClient().getProcessGroup(group.getId());
+        assertNotNull(groupAfterStartVersionControl);
+        assertNotNull(groupAfterStartVersionControl.getComponent());
+        
assertNotNull(groupAfterStartVersionControl.getComponent().getVersionControlInformation());
+        assertEquals(clientEntity.getId(), 
groupAfterStartVersionControl.getComponent().getVersionControlInformation().getRegistryId());
+        assertEquals(TEST_FLOWS_BUCKET, 
groupAfterStartVersionControl.getComponent().getVersionControlInformation().getBucketId());
+        assertEquals(vci.getVersionControlInformation().getFlowId(), 
groupAfterStartVersionControl.getComponent().getVersionControlInformation().getFlowId());
+        assertEquals(vci.getVersionControlInformation().getVersion(), 
groupAfterStartVersionControl.getComponent().getVersionControlInformation().getVersion());
+        assertEquals("UP_TO_DATE", 
groupAfterStartVersionControl.getComponent().getVersionControlInformation().getState());
+
+        // Stop version control
+        
getNifiClient().getVersionsClient().stopVersionControl(groupAfterStartVersionControl);
+
+        // Retrieve PG again and verify no VCI present
+        final ProcessGroupEntity groupAfterStopVersionControl = 
getNifiClient().getProcessGroupClient().getProcessGroup(group.getId());
+        assertNotNull(groupAfterStopVersionControl);
+        assertNotNull(groupAfterStopVersionControl.getComponent());
+        
assertNull(groupAfterStopVersionControl.getComponent().getVersionControlInformation());
+
+        // Submit PG update specifying VCI
+        final VersionControlInformationDTO setVersionInfo = new 
VersionControlInformationDTO();
+        setVersionInfo.setRegistryId(clientEntity.getId());
+        
setVersionInfo.setBucketId(vci.getVersionControlInformation().getBucketId());
+        
setVersionInfo.setFlowId(vci.getVersionControlInformation().getFlowId());
+        
setVersionInfo.setVersion(vci.getVersionControlInformation().getVersion());
+        
groupAfterStopVersionControl.getComponent().setVersionControlInformation(setVersionInfo);
+
+        final ProcessGroupEntity groupAfterSetVersionInfo = 
getNifiClient().getProcessGroupClient().updateProcessGroup(groupAfterStopVersionControl);
+        assertNotNull(groupAfterSetVersionInfo);
+        assertNotNull(groupAfterSetVersionInfo.getComponent());
+        
assertNotNull(groupAfterSetVersionInfo.getComponent().getVersionControlInformation());
+        assertEquals(clientEntity.getId(), 
groupAfterSetVersionInfo.getComponent().getVersionControlInformation().getRegistryId());
+        assertEquals(TEST_FLOWS_BUCKET, 
groupAfterSetVersionInfo.getComponent().getVersionControlInformation().getBucketId());
+        assertEquals(vci.getVersionControlInformation().getFlowId(), 
groupAfterSetVersionInfo.getComponent().getVersionControlInformation().getFlowId());
+        assertEquals(vci.getVersionControlInformation().getVersion(), 
groupAfterSetVersionInfo.getComponent().getVersionControlInformation().getVersion());
+        assertEquals("UP_TO_DATE", 
groupAfterSetVersionInfo.getComponent().getVersionControlInformation().getState());
+    }
 }

Reply via email to