Skip to content

Unify move endpoints#1000

Open
Meklo wants to merge 22 commits into
mainfrom
marcellinh/unify_move_endpoints
Open

Unify move endpoints#1000
Meklo wants to merge 22 commits into
mainfrom
marcellinh/unify_move_endpoints

Conversation

@Meklo
Copy link
Copy Markdown
Contributor

@Meklo Meklo commented May 28, 2026

PR Summary

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Review Change Stack

Warning

Review limit reached

@Meklo, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 58 minutes and 22 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb848d71-5f05-4efe-8a71-6fdbe8c9db68

📥 Commits

Reviewing files that changed from the base of the PR and between f9be565 and 793dff2.

📒 Files selected for processing (2)
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/RebuildNodeServiceTest.java
📝 Walkthrough

Walkthrough

Controller move endpoint now accepts optional source/target container IDs (with fallback); RebuildNodeService and StudyService propagate container IDs to NetworkModificationService.moveModifications; tests updated to exercise explicit and fallback move scenarios.

Changes

Container-based modification movement

Layer / File(s) Summary
NetworkModificationService move API rename
src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java
Renames moveModifications parameters to sourceContainerId/targetContainerId, builds a PUT MOVE request using originGroupUuid from source, optionally includes before, targets expanded targetContainerId, and returns NetworkModificationsResult.
Node lookup helper and import cleanup
src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java, src/main/java/org/gridsuite/study/server/controller/StudyController.java
Adds getNodeUuidByModificationGroup(UUID) and removes unused jakarta.annotation.Nullable import from StudyController.
Controller endpoint with container fallback
src/main/java/org/gridsuite/study/server/controller/StudyController.java
moveModification accepts optional sourceContainerId/targetContainerId/beforeUuid, resolves missing container IDs via networkModificationTreeService.getModificationGroupUuid(nodeUuid), and delegates resolved IDs to rebuildNodeService.moveNetworkModification(...).
RebuildNodeService: forward container IDs and new move overload
src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java
Updates handlers to derive container IDs via NetworkModificationTreeService, forward them to studyService.moveNetworkModifications(...), replaces moveNetworkModification(...) with overload accepting targetContainerId/sourceContainerId, and removes moveSubModification API.
Core movement logic refactor in StudyService
src/main/java/org/gridsuite/study/server/service/StudyService.java
moveNetworkModifications now takes targetContainerId/sourceContainerId, derives originNodeUuid from sourceContainerId, validates target membership, builds modification application contexts across root networks for target node, calls networkModificationService.moveModifications(source,target,...), updates exclusions, and emits impact and equipment notifications.
Test updates for new signatures and scenarios
src/test/java/org/gridsuite/study/server/*
Removes obsolete single-node rebuild and controller move tests; updates testMoveExcludedModification mocks and calls; adjusts reorder test to pass beforeUuid via queryParam; replaces testMoveSubModification with testMoveCompositeSubmodification covering explicit and fallback container scenarios and WireMock stubs for group endpoints.

Sequence Diagram

sequenceDiagram
  participant Client
  participant StudyController
  participant NetworkModificationTreeService
  participant RebuildNodeService
  participant StudyService
  participant NetworkModificationService
  participant ModificationServer
  Client->>StudyController: PUT /studies/{studyUuid}/nodes/{nodeUuid}/network-modification/{modificationUuid}?sourceContainerId&targetContainerId&beforeUuid
  StudyController->>NetworkModificationTreeService: getModificationGroupUuid(nodeUuid) (when missing)
  StudyController->>RebuildNodeService: moveNetworkModification(targetContainerId, sourceContainerId, modificationUuid, beforeUuid, userId)
  RebuildNodeService->>StudyService: moveNetworkModifications(studyUuid, targetNodeUuid, targetContainerId, sourceContainerId, [modUuid], beforeUuid, isDifferentTree, userId)
  StudyService->>NetworkModificationService: moveModifications(sourceContainerId, targetContainerId, beforeUuid, body, buildTargetNode)
  NetworkModificationService->>ModificationServer: PUT /v1/groups/{targetContainerId}?action=MOVE&originGroupUuid={sourceContainerId}&before={before}
Loading

Suggested reviewers

  • Mathieu-Deharbe
  • SlimaneAmar
  • etiennehomer
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is completely empty, containing only a template header with no actual content describing the changes, objectives, or implementation details. Provide a substantive description explaining what was unified, why the changes were made, and any migration notes or testing guidance for reviewers.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Unify move endpoints' directly aligns with the changeset, which consolidates move-related endpoint logic across multiple services by standardizing parameter names (sourceContainerId/targetContainerId) and internal flows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/org/gridsuite/study/server/controller/StudyController.java`:
- Around line 628-653: Add backward-compatible alias mappings that route the
removed v1 endpoints to the existing moveModification handler: keep the new
method moveModification and add additional `@PutMapping` entries (or new methods
that delegate to moveModification) for the old paths
/network-modification/{modificationUuid} and
/composite-sub-modification/{modificationUuid} so existing clients won’t 404;
ensure the aliases accept the same path variables, request params
(sourceContainerId, targetContainerId, beforeUuid) and HEADER_USER_ID and then
call the same logic (delegate to rebuildNodeService.moveNetworkModification via
moveModification or a shared private helper) so behavior remains identical until
callers migrate.

In
`@src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java`:
- Around line 1298-1302: The method getNodeUuidByModificationGroup currently
returns null when no node is found; change it to fail-fast by throwing a
StudyException with NOT_FOUND instead of returning null: in
getNodeUuidByModificationGroup call
networkModificationNodeInfoRepository.findByModificationGroupUuidIn(List.of(groupUuid))
as before, but if the result is empty throw new
StudyException(StudyException.ErrorCode.NOT_FOUND, "Modification group node not
found: " + groupUuid) (or similar message), otherwise return
node.getFirst().getIdNode(); update imports if needed and keep the method
signature returning UUID (do not return null) so downstream code always receives
a non-null UUID or an exception.

In `@src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java`:
- Around line 91-105: The code calls handleRebuildNode with a lambda that
invokes studyService.moveNetworkModifications passing a hardcoded false for the
cross-tree flag, which can skip origin-tree invalidation/unblock and
notifications; update the single-move flow to compute the cross-tree flag the
same way as the multi-move path (reuse the same logic used there to determine
isTargetInDifferentNodeTree) and pass that computed boolean into
studyService.moveNetworkModifications, ensuring
invalidateNodeTreeWhenMoveModification and unblockNodeTree are still executed in
the same try/finally so origin-tree handling and notifications remain correct;
refer to handleRebuildNode, studyService.moveNetworkModifications,
invalidateNodeTreeWhenMoveModification and unblockNodeTree for where to apply
the change.

In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 2258-2270: The NetworkModificationsResult returned by
networkModificationService.moveModifications must be null-checked before calling
result.modificationUuids() or result.modificationResults(); update the code
around the call to networkModificationService.moveModifications (which assigns
to variable result) to guard against a null or empty result and only call
rootNetworkNodeInfoService.moveModificationsToExclude(originNodeUuid,
targetNodeUuid, result.modificationUuids()) and
emitNetworkModificationImpactsForAllRootNetworks(result.modificationResults(),
studyEntity, targetNodeUuid) when result is non-null (and contains the expected
collections), otherwise handle the empty response path (e.g., skip those calls
or log/throw as appropriate).
- Around line 2240-2256: The code resolves sourceContainerId to originNodeUuid
via networkModificationTreeService.getNodeUuidByModificationGroup but never
validates that originNodeUuid belongs to the same study, allowing cross-study
moves; after obtaining originNodeUuid (and before using it or emitting
notifications), call the existing checkStudyContainsNode(studyUuid,
originNodeUuid) (or an equivalent containment/authorization check) to enforce
study-boundary validation for sourceContainerId and fail early if it does not
belong to the study.

In
`@src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java`:
- Line 787: The test currently calls
studyService.moveNetworkModifications(studyUuid, firstNodeUuid, firstNodeUuid,
...) using firstNodeUuid for both node parameters, which prevents exercising a
cross-node move; change the second occurrence of firstNodeUuid to secondNodeUuid
so the call becomes studyService.moveNetworkModifications(studyUuid,
firstNodeUuid, secondNodeUuid, modificationsToMove, false, USER_ID) to properly
test the failure-path for moving excluded modifications between nodes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 13e8ef7c-c7f9-489c-a866-f1b641a20b4d

📥 Commits

Reviewing files that changed from the base of the PR and between 159ad86 and d28f0a1.

📒 Files selected for processing (8)
  • src/main/java/org/gridsuite/study/server/controller/StudyController.java
  • src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java
  • src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java
  • src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/RebuildNodeServiceTest.java
  • src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java
  • src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java
💤 Files with no reviewable changes (2)
  • src/test/java/org/gridsuite/study/server/studycontroller/StudyControllerRebuildNodeTest.java
  • src/test/java/org/gridsuite/study/server/RebuildNodeServiceTest.java

Comment thread src/main/java/org/gridsuite/study/server/controller/StudyController.java Outdated
Comment thread src/main/java/org/gridsuite/study/server/service/StudyService.java
Comment thread src/main/java/org/gridsuite/study/server/service/StudyService.java
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/java/org/gridsuite/study/server/NetworkModificationTest.java`:
- Around line 3188-3250: The three MOVE cases (moveUrlCase1, moveUrlNodeGroup,
moveUrlCase3) currently only assert URL and query params; add assertions that
the forwarded PUT body includes the moved node UUID and the
ModificationApplicationContext payload (the same shape expected by
testReorderModification). Update the three
WireMockUtilsCriteria.verifyPutRequest(...) calls to include a body matcher
(instead of the current null) that verifies the JSON contains the moved UUID
(nodeUuid) in the UUIDs/uuids array and contains the
ModificationApplicationContext field/key expected by the downstream API.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 898fbb3f-cdfa-4a7c-81fd-968c01a87a6d

📥 Commits

Reviewing files that changed from the base of the PR and between d28f0a1 and aab2a27.

📒 Files selected for processing (3)
  • src/main/java/org/gridsuite/study/server/controller/StudyController.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/NetworkModificationTest.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/gridsuite/study/server/controller/StudyController.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java

Comment thread src/test/java/org/gridsuite/study/server/NetworkModificationTest.java Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java (1)

785-787: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use secondNodeUuid in the failure-path move call.

This branch still passes firstNodeUuid as targetNodeUuid while targetContainerId points to secondNode. StudyService.moveNetworkModifications(...) builds application contexts and notifications from targetNodeUuid, so this no longer exercises the cross-node failure path the test is describing.

Suggested fix
-        assertThrows(RuntimeException.class, () -> studyService.moveNetworkModifications(studyUuid, firstNodeUuid, secondNode.getModificationGroupUuid(), firstNode.getModificationGroupUuid(), modificationsToMove, null, false, USER_ID));
+        assertThrows(RuntimeException.class, () -> studyService.moveNetworkModifications(studyUuid, secondNodeUuid, secondNode.getModificationGroupUuid(), firstNode.getModificationGroupUuid(), modificationsToMove, null, false, USER_ID));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java`
around lines 785 - 787, The test calls
studyService.moveNetworkModifications(...) but mistakenly passes firstNodeUuid
as the targetNodeUuid while targetContainerId/target modification group is from
secondNode, so change the failure-path invocation to use secondNodeUuid as the
targetNodeUuid; update the assertThrows call to pass secondNodeUuid (instead of
firstNodeUuid) so the call to networkModificationService.moveModifications(...)
exercised by Mockito.doThrow(new RuntimeException()) correctly represents the
cross-node failure path (refer to
Mockito.doThrow(...).when(networkModificationService).moveModifications(...) and
the studyService.moveNetworkModifications(...) invocation and the variables
firstNodeUuid, secondNodeUuid, secondNode.getModificationGroupUuid()).
src/main/java/org/gridsuite/study/server/service/StudyService.java (1)

2250-2262: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate node-backed source containers against the study.

Line 2250 resolves sourceContainerId into originNodeUuid, but Line 2262 only checks targetNodeUuid. The composite-null case is fine, but when originNodeUuid is non-null this still lets a caller pass a modification-group UUID from another study and have it forwarded to networkModificationService.moveModifications(...).

Suggested fix
         try {
             StudyEntity studyEntity = getStudy(studyUuid);
             checkStudyContainsNode(studyUuid, targetNodeUuid);
+            if (originNodeUuid != null) {
+                checkStudyContainsNode(studyUuid, originNodeUuid);
+            }
             List<ModificationApplicationContext> applicationContexts = studyEntity.getRootNetworks().stream()
                     .map(rn -> rootNetworkNodeInfoService.getNetworkModificationApplicationContext(rn.getId(), targetNodeUuid, rn.getNetworkUuid()))
                     .toList();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/gridsuite/study/server/service/StudyService.java` around
lines 2250 - 2262, The code resolves sourceContainerId into originNodeUuid but
never validates that originNodeUuid belongs to the same study; add a check using
the existing checkStudyContainsNode(studyUuid, originNodeUuid) for non-null
originNodeUuid (i.e., when the source is node-backed) after you obtain
studyEntity (or before calling
networkModificationService.moveModifications(...)) so a modification-group UUID
from another study cannot be forwarded; reference the variables originNodeUuid,
sourceContainerId and the method checkStudyContainsNode to locate where to
insert this validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 2250-2262: The code resolves sourceContainerId into originNodeUuid
but never validates that originNodeUuid belongs to the same study; add a check
using the existing checkStudyContainsNode(studyUuid, originNodeUuid) for
non-null originNodeUuid (i.e., when the source is node-backed) after you obtain
studyEntity (or before calling
networkModificationService.moveModifications(...)) so a modification-group UUID
from another study cannot be forwarded; reference the variables originNodeUuid,
sourceContainerId and the method checkStudyContainsNode to locate where to
insert this validation.

In
`@src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java`:
- Around line 785-787: The test calls studyService.moveNetworkModifications(...)
but mistakenly passes firstNodeUuid as the targetNodeUuid while
targetContainerId/target modification group is from secondNode, so change the
failure-path invocation to use secondNodeUuid as the targetNodeUuid; update the
assertThrows call to pass secondNodeUuid (instead of firstNodeUuid) so the call
to networkModificationService.moveModifications(...) exercised by
Mockito.doThrow(new RuntimeException()) correctly represents the cross-node
failure path (refer to
Mockito.doThrow(...).when(networkModificationService).moveModifications(...) and
the studyService.moveNetworkModifications(...) invocation and the variables
firstNodeUuid, secondNodeUuid, secondNode.getModificationGroupUuid()).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e274c2f2-e31b-40dd-b60f-a100ce2780b9

📥 Commits

Reviewing files that changed from the base of the PR and between aab2a27 and 6ec4a78.

📒 Files selected for processing (4)
  • src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/NetworkModificationTest.java
  • src/test/java/org/gridsuite/study/server/rootnetworks/ModificationToExcludeTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/org/gridsuite/study/server/NetworkModificationTest.java

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jun 3, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant