Skip to content

Commit 4195544

Browse files
authored
Adjust copy cut paste rules (#804)
* create security node and adjust network modification node creation rules --------- Signed-off-by: SOUISSI Maissa (Externe) <[email protected]>
1 parent d14c025 commit 4195544

File tree

3 files changed

+163
-41
lines changed

3 files changed

+163
-41
lines changed

src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -603,46 +603,63 @@ public void assertIsRootOrConstructionNode(UUID nodeUuid) {
603603
}
604604
}
605605

606-
private NetworkModificationNodeType getReferenceNodeType(NodeEntity referenceNode) {
607-
return referenceNode.getType().equals(NodeType.ROOT)
608-
? null
609-
: getNetworkModificationNodeInfoEntity(referenceNode.getIdNode()).getNodeType();
610-
}
611-
612-
private boolean isConstructionUnderSecurityNode(NetworkModificationNodeType newNodeType, NetworkModificationNodeType referenceNodeType) {
613-
return newNodeType == NetworkModificationNodeType.CONSTRUCTION &&
614-
referenceNodeType == NetworkModificationNodeType.SECURITY;
615-
}
616-
617-
private boolean isInvalidSecurityNodeInsertion(NetworkModificationNodeType newNodeType, InsertMode insertMode, NetworkModificationNodeType referenceNodeType) {
618-
return newNodeType == NetworkModificationNodeType.SECURITY &&
619-
insertMode != InsertMode.CHILD &&
620-
referenceNodeType != NetworkModificationNodeType.SECURITY;
621-
}
622-
623-
private void assertIsNetworkModificationInsertionAllowed(
624-
NodeEntity nodeEntity,
606+
private void assertInsertNode(
607+
UUID parentNodeId,
625608
NetworkModificationNodeType newNodeType,
626609
InsertMode insertMode
627610
) {
628-
NetworkModificationNodeType referenceNodeType = getReferenceNodeType(nodeEntity);
629611

630-
if (isConstructionUnderSecurityNode(newNodeType, referenceNodeType) ||
631-
isInvalidSecurityNodeInsertion(newNodeType, insertMode, referenceNodeType)) {
612+
if (getNodeEntity(parentNodeId).getType() == NodeType.ROOT) {
613+
if (newNodeType == NetworkModificationNodeType.SECURITY && insertMode != InsertMode.CHILD) {
614+
throw new StudyException(NOT_ALLOWED);
615+
}
616+
return;
617+
}
618+
619+
NetworkModificationNodeType parentNodeType = getNetworkModificationNodeInfoEntity(parentNodeId).getNodeType();
620+
621+
if (parentNodeType == NetworkModificationNodeType.SECURITY
622+
&& newNodeType == NetworkModificationNodeType.CONSTRUCTION) {
632623
throw new StudyException(NOT_ALLOWED);
633624
}
634-
}
635625

636-
public void assertIsNetworkModificationNodeCreationAllowed(UUID nodeId, NetworkModificationNode nodeInfo, InsertMode insertMode) {
637-
NetworkModificationNodeType newNodeType = nodeInfo.getNodeType();
638-
NodeEntity nodeEntity = getNodeEntity(nodeId);
639-
assertIsNetworkModificationInsertionAllowed(nodeEntity, newNodeType, insertMode);
626+
if (parentNodeType == NetworkModificationNodeType.CONSTRUCTION
627+
&& newNodeType == NetworkModificationNodeType.SECURITY
628+
&& insertMode != InsertMode.CHILD
629+
) {
630+
throw new StudyException(NOT_ALLOWED);
631+
}
640632
}
641633

642634
public boolean isConstructionNode(UUID nodeUuid) {
643635
return getNetworkModificationNodeInfoEntity(nodeUuid).getNodeType() == NetworkModificationNodeType.CONSTRUCTION;
644636
}
645637

638+
public void assertCreateNode(UUID parentNodeId, NetworkModificationNodeType newNodeType, InsertMode insertMode) {
639+
assertInsertNode(parentNodeId, newNodeType, insertMode);
640+
}
641+
642+
public void assertMoveOrDuplicateNode(UUID nodeToCopyUuid, UUID parentNodeId, InsertMode insertMode) {
643+
NetworkModificationNodeInfoEntity nodeToCopy = getNetworkModificationNodeInfoEntity(nodeToCopyUuid);
644+
assertInsertNode(parentNodeId, nodeToCopy.getNodeType(), insertMode);
645+
}
646+
647+
public void assertMoveOrDuplicateSubtree(UUID nodeTreeUuid, UUID referenceNodeUuid) {
648+
if (getNodeEntity(referenceNodeUuid).getType() == NodeType.ROOT) {
649+
return;
650+
}
651+
652+
NetworkModificationNodeType referenceNodeType = getNetworkModificationNodeInfoEntity(referenceNodeUuid).getNodeType();
653+
if (referenceNodeType == NetworkModificationNodeType.CONSTRUCTION) {
654+
return;
655+
}
656+
657+
List<NetworkModificationNodeInfoEntity> subtreeNodes = networkModificationNodeInfoRepository.findAllById(getNodeTreeUuids(nodeTreeUuid));
658+
if (subtreeNodes.stream().anyMatch(node -> node.getNodeType() == NetworkModificationNodeType.CONSTRUCTION)) {
659+
throw new StudyException(NOT_ALLOWED);
660+
}
661+
}
662+
646663
@Transactional(readOnly = true)
647664
public boolean isNodeNameExists(UUID studyUuid, String nodeName) {
648665
return ROOT_NODE_NAME.equals(nodeName) || !networkModificationNodeInfoRepository.findAllByNodeStudyIdAndName(studyUuid, nodeName).stream().filter(abstractNodeInfoEntity -> !abstractNodeInfoEntity.getNode().isStashed()).toList().isEmpty();

src/main/java/org/gridsuite/study/server/service/StudyService.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,11 +1780,22 @@ public void stopBuild(@NonNull UUID nodeUuid, UUID rootNetworkUuid) {
17801780
networkModificationService.stopBuild(nodeUuid, rootNetworkUuid);
17811781
}
17821782

1783-
@Transactional
1784-
public void duplicateStudyNode(UUID sourceStudyUuid, UUID targetStudyUuid, UUID nodeToCopyUuid, UUID referenceNodeUuid, InsertMode insertMode, String userId) {
1783+
private void assertDuplicateStudyNode(UUID sourceStudyUuid, UUID targetStudyUuid, UUID nodeToCopyUuid, UUID referenceNodeUuid, InsertMode insertMode) {
17851784
checkStudyContainsNode(sourceStudyUuid, nodeToCopyUuid);
17861785
checkStudyContainsNode(targetStudyUuid, referenceNodeUuid);
1787-
networkModificationTreeService.assertIsRootOrConstructionNode(referenceNodeUuid);
1786+
networkModificationTreeService.assertMoveOrDuplicateNode(nodeToCopyUuid, referenceNodeUuid, insertMode);
1787+
}
1788+
1789+
private void assertMoveStudyNode(UUID studyUuid, UUID nodeToMoveUuid, UUID referenceNodeUuid, InsertMode insertMode) {
1790+
checkStudyContainsNode(studyUuid, nodeToMoveUuid);
1791+
checkStudyContainsNode(studyUuid, referenceNodeUuid);
1792+
networkModificationTreeService.assertMoveOrDuplicateNode(nodeToMoveUuid, referenceNodeUuid, insertMode);
1793+
}
1794+
1795+
@Transactional
1796+
public void duplicateStudyNode(UUID sourceStudyUuid, UUID targetStudyUuid, UUID nodeToCopyUuid, UUID referenceNodeUuid, InsertMode insertMode, String userId) {
1797+
assertDuplicateStudyNode(sourceStudyUuid, targetStudyUuid, nodeToCopyUuid, referenceNodeUuid, insertMode);
1798+
17881799
UUID duplicatedNodeUuid = networkModificationTreeService.duplicateStudyNode(nodeToCopyUuid, referenceNodeUuid, insertMode);
17891800
boolean invalidateBuild = networkModificationTreeService.hasModifications(nodeToCopyUuid, false);
17901801
if (invalidateBuild) {
@@ -1795,10 +1806,9 @@ public void duplicateStudyNode(UUID sourceStudyUuid, UUID targetStudyUuid, UUID
17951806

17961807
@Transactional
17971808
public void moveStudyNode(UUID studyUuid, UUID nodeToMoveUuid, UUID referenceNodeUuid, InsertMode insertMode, String userId) {
1809+
assertMoveStudyNode(studyUuid, nodeToMoveUuid, referenceNodeUuid, insertMode);
1810+
17981811
List<NodeEntity> oldChildren = null;
1799-
checkStudyContainsNode(studyUuid, nodeToMoveUuid);
1800-
checkStudyContainsNode(studyUuid, referenceNodeUuid);
1801-
networkModificationTreeService.assertIsRootOrConstructionNode(referenceNodeUuid);
18021812
boolean shouldUnbuildChildren = networkModificationTreeService.hasModifications(nodeToMoveUuid, false);
18031813

18041814
//Unbuild previous children if necessary
@@ -1818,30 +1828,38 @@ public void moveStudyNode(UUID studyUuid, UUID nodeToMoveUuid, UUID referenceNod
18181828
notificationService.emitElementUpdated(studyUuid, userId);
18191829
}
18201830

1821-
@Transactional
1822-
public void duplicateStudySubtree(UUID sourceStudyUuid, UUID targetStudyUuid, UUID parentNodeToCopyUuid, UUID referenceNodeUuid, String userId) {
1831+
private void assertDuplicateStudySubtree(UUID sourceStudyUuid, UUID targetStudyUuid, UUID parentNodeToCopyUuid, UUID referenceNodeUuid) {
18231832
checkStudyContainsNode(sourceStudyUuid, parentNodeToCopyUuid);
18241833
checkStudyContainsNode(targetStudyUuid, referenceNodeUuid);
1825-
networkModificationTreeService.assertIsRootOrConstructionNode(referenceNodeUuid);
1834+
networkModificationTreeService.assertMoveOrDuplicateSubtree(parentNodeToCopyUuid, referenceNodeUuid);
1835+
}
18261836

1837+
@Transactional
1838+
public void duplicateStudySubtree(UUID sourceStudyUuid, UUID targetStudyUuid, UUID parentNodeToCopyUuid, UUID referenceNodeUuid, String userId) {
1839+
assertDuplicateStudySubtree(sourceStudyUuid, targetStudyUuid, parentNodeToCopyUuid, referenceNodeUuid);
1840+
AbstractNode studySubTree = networkModificationTreeService.getStudySubtree(sourceStudyUuid, parentNodeToCopyUuid, null);
18271841
StudyEntity studyEntity = studyRepository.findById(targetStudyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND));
18281842
StudyEntity sourceStudyEntity = studyRepository.findById(sourceStudyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND));
1829-
AbstractNode studySubTree = networkModificationTreeService.getStudySubtree(sourceStudyUuid, parentNodeToCopyUuid, null);
18301843
UUID duplicatedNodeUuid = networkModificationTreeService.cloneStudyTree(studySubTree, referenceNodeUuid, studyEntity, sourceStudyEntity, false);
18311844
notificationService.emitSubtreeInserted(targetStudyUuid, duplicatedNodeUuid, referenceNodeUuid);
18321845
notificationService.emitElementUpdated(targetStudyUuid, userId);
18331846
}
18341847

1835-
@Transactional
1836-
public void moveStudySubtree(UUID studyUuid, UUID parentNodeToMoveUuid, UUID referenceNodeUuid, String userId) {
1848+
private void assertMoveStudySubtree(UUID studyUuid, UUID parentNodeToMoveUuid, UUID referenceNodeUuid) {
18371849
checkStudyContainsNode(studyUuid, parentNodeToMoveUuid);
18381850
checkStudyContainsNode(studyUuid, referenceNodeUuid);
1839-
networkModificationTreeService.assertIsRootOrConstructionNode(referenceNodeUuid);
1851+
networkModificationTreeService.assertMoveOrDuplicateSubtree(parentNodeToMoveUuid, referenceNodeUuid);
1852+
}
1853+
1854+
@Transactional
1855+
public void moveStudySubtree(UUID studyUuid, UUID parentNodeToMoveUuid, UUID referenceNodeUuid, String userId) {
1856+
assertMoveStudySubtree(studyUuid, parentNodeToMoveUuid, referenceNodeUuid);
18401857

18411858
List<UUID> allChildren = networkModificationTreeService.getChildrenUuids(parentNodeToMoveUuid);
18421859
if (allChildren.contains(referenceNodeUuid)) {
18431860
throw new StudyException(NOT_ALLOWED);
18441861
}
1862+
18451863
networkModificationTreeService.moveStudySubtree(parentNodeToMoveUuid, referenceNodeUuid);
18461864

18471865
getStudyRootNetworks(studyUuid).forEach(rootNetworkEntity -> {
@@ -3260,7 +3278,7 @@ public void createOrUpdateStateEstimationParameters(StudyEntity studyEntity, Str
32603278
@Transactional
32613279
public NetworkModificationNode createNode(UUID studyUuid, UUID nodeId, NetworkModificationNode nodeInfo, InsertMode insertMode, String userId) {
32623280
StudyEntity study = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND));
3263-
networkModificationTreeService.assertIsNetworkModificationNodeCreationAllowed(nodeId, nodeInfo, insertMode);
3281+
networkModificationTreeService.assertCreateNode(nodeId, nodeInfo.getNodeType(), insertMode);
32643282
NetworkModificationNode newNode = networkModificationTreeService.createNode(study, nodeId, nodeInfo, insertMode, userId);
32653283

32663284
UUID parentUuid = networkModificationTreeService.getParentNodeUuid(newNode.getId()).orElse(null);

src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,93 @@ void testNodeCreation() throws Exception {
414414
deleteNode(root.getStudyId(), children, false, Set.of(children.get(0)), userId);
415415
}
416416

417+
private void assertForbiddenNodeInsertions(UUID studyId, String userId,
418+
NetworkModificationNode construction2,
419+
NetworkModificationNode construction1,
420+
NetworkModificationNode security1,
421+
NetworkModificationNode security2) throws Exception {
422+
// Construction node cannot be inserted before a security node
423+
mockMvc.perform(post("/v1/studies/{studyUuid}/tree/nodes?nodeToCutUuid={nodeUuid}&referenceNodeUuid={referenceNodeUuid}&insertMode={insertMode}",
424+
studyId, construction2.getId(), security1.getId(), InsertMode.BEFORE)
425+
.header(USER_ID_HEADER, userId))
426+
.andExpect(status().isForbidden());
427+
428+
// Security node cannot be inserted before a construction node (not a NEW_BRANCH)
429+
mockMvc.perform(post("/v1/studies/{studyUuid}/tree/nodes?nodeToCutUuid={nodeUuid}&referenceNodeUuid={referenceNodeUuid}&insertMode={insertMode}",
430+
studyId, security2.getId(), construction2.getId(), InsertMode.BEFORE)
431+
.header(USER_ID_HEADER, userId))
432+
.andExpect(status().isForbidden());
433+
434+
// Security node cannot be inserted before another construction node at root level
435+
mockMvc.perform(post("/v1/studies/{studyUuid}/tree/nodes?nodeToCutUuid={nodeUuid}&referenceNodeUuid={referenceNodeUuid}&insertMode={insertMode}",
436+
studyId, security2.getId(), construction1.getId(), InsertMode.BEFORE)
437+
.header(USER_ID_HEADER, userId))
438+
.andExpect(status().isForbidden());
439+
}
440+
441+
private void assertForbiddenSubtreeInsertions(UUID studyId, String userId,
442+
NetworkModificationNode subtreeRoot,
443+
NetworkModificationNode targetNode) throws Exception {
444+
// Construction subtree cannot be inserted as a child of a security node
445+
mockMvc.perform(post("/v1/studies/{studyUuid}/tree/subtrees?subtreeToCutParentNodeUuid={subtreeRoot}&referenceNodeUuid={targetNodeUuid}&insertMode={mode}",
446+
studyId, subtreeRoot.getId(), targetNode.getId(), InsertMode.CHILD)
447+
.header(USER_ID_HEADER, userId))
448+
.andExpect(status().isForbidden());
449+
450+
// Mixed subtree (construction + security) cannot be inserted into a security node
451+
mockMvc.perform(post("/v1/studies/{studyUuid}/tree/subtrees?subtreeToCutParentNodeUuid={subtreeRoot}&referenceNodeUuid={targetNodeUuid}&insertMode={mode}",
452+
studyId, subtreeRoot.getId(), targetNode.getId(), InsertMode.CHILD)
453+
.header(USER_ID_HEADER, userId))
454+
.andExpect(status().isForbidden());
455+
}
456+
457+
@Test
458+
void testNodeAndSubtreeInsertionRules() throws Exception {
459+
String userId = "userId";
460+
RootNode root = createRoot();
461+
UUID studyId = root.getStudyId();
462+
463+
// Create tree structure
464+
final NetworkModificationNode construction1 = buildNetworkModificationConstructionNode(
465+
"construction1", "n1", UUID.randomUUID(), "variant1",
466+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
467+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), BuildStatus.NOT_BUILT);
468+
createNode(studyId, root, construction1, userId);
469+
470+
final NetworkModificationNode construction2 = buildNetworkModificationConstructionNode(
471+
"construction2", "n2", UUID.randomUUID(), "variant2",
472+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
473+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), BuildStatus.NOT_BUILT);
474+
createNode(studyId, construction1, construction2, userId);
475+
476+
final NetworkModificationNode security1 = buildNetworkModificationSecurityNode(
477+
"security1", "sec1", UUID.randomUUID(), VARIANT_ID,
478+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
479+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), BuildStatus.NOT_BUILT);
480+
createNode(studyId, root, security1, userId);
481+
482+
final NetworkModificationNode security2 = buildNetworkModificationSecurityNode(
483+
"security2", "sec2", UUID.randomUUID(), VARIANT_ID,
484+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
485+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), BuildStatus.NOT_BUILT);
486+
createNode(studyId, root, security2, userId);
487+
488+
final NetworkModificationNode security3 = buildNetworkModificationSecurityNode(
489+
"security3", "sec3", UUID.randomUUID(), VARIANT_ID,
490+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
491+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), BuildStatus.NOT_BUILT);
492+
createNode(studyId, security2, security3, userId);
493+
494+
final NetworkModificationNode security4 = buildNetworkModificationSecurityNode(
495+
"security4", "sec4", UUID.randomUUID(), "variant2",
496+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
497+
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), BuildStatus.NOT_BUILT);
498+
createNode(studyId, construction2, security4, userId); // Creates a mixed subtree
499+
500+
assertForbiddenNodeInsertions(studyId, userId, construction2, construction1, security1, security2);
501+
assertForbiddenSubtreeInsertions(studyId, userId, construction1, security1);
502+
}
503+
417504
@Test
418505
void testNodeCreationRules() throws Exception {
419506
RootNode root = createRoot();

0 commit comments

Comments
 (0)