From d6d8eae2fb1bc22c1f28dc01c427c25a96b6102c Mon Sep 17 00:00:00 2001 From: Abdelsalem Date: Thu, 16 Oct 2025 11:47:24 +0200 Subject: [PATCH 1/4] springboot 3.4.9 Signed-off-by: Abdelsalem --- pom.xml | 12 +++++- .../ModificationApplicationEntity.java | 1 - .../entities/ModificationGroupEntity.java | 3 +- .../AbstractShuntCompensatorEmbeddable.java | 2 - .../modification/GeneratorScalingEntity.java | 2 +- .../NetworkModificationRepository.java | 6 ++- .../server/ModificationControllerTest.java | 18 ++++---- .../server/SupervisionControllerTest.java | 4 +- .../AbstractNetworkModificationTest.java | 7 ++-- .../modifications/BalancesAdjustmentTest.java | 6 ++- .../CompositeModificationsTest.java | 4 +- .../TabularGeneratorModificationsTest.java | 4 +- .../server/service/BuildTest.java | 8 ++-- .../service/BuildWorkerServiceTest.java | 6 +-- .../service/EquipmentIndexationTest.java | 6 +-- .../service/ModificationIndexationTest.java | 6 +-- .../service/ModificationRepositoryTest.java | 18 ++++---- .../service/ModificationSearchTest.java | 4 +- .../NetworkModificationApplicatorTest.java | 14 +++---- .../server/service/SupervisionTest.java | 10 ++--- .../elasticsearch/DisableElasticsearch.java | 42 +++++++++++++++++-- 21 files changed, 116 insertions(+), 67 deletions(-) diff --git a/pom.xml b/pom.xml index e4984c966..ce1c4f052 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ - 43.0.0 + 43.2.0 1.0.5 5.0.0-alpha.14 org.gridsuite.modification.server @@ -52,8 +52,9 @@ gridsuite org.gridsuite:network-modification-server - 0.38.0 + 0.39.0 2.14.1 + 1.6.0 @@ -103,6 +104,13 @@ ${powsybl-balances-adjustment.version} + + + org.gridsuite + gridsuite-filter + ${gridsuite-filter.version} + + org.gridsuite diff --git a/src/main/java/org/gridsuite/modification/server/entities/ModificationApplicationEntity.java b/src/main/java/org/gridsuite/modification/server/entities/ModificationApplicationEntity.java index 4797eabef..30bec2237 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/ModificationApplicationEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/ModificationApplicationEntity.java @@ -18,7 +18,6 @@ * @author Kevin Le Saulnier */ @Builder -@Embeddable @AllArgsConstructor @NoArgsConstructor @Setter diff --git a/src/main/java/org/gridsuite/modification/server/entities/ModificationGroupEntity.java b/src/main/java/org/gridsuite/modification/server/entities/ModificationGroupEntity.java index a7c5ec30f..48a0b04a6 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/ModificationGroupEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/ModificationGroupEntity.java @@ -29,7 +29,8 @@ public class ModificationGroupEntity extends AbstractManuallyAssignedIdentifierE @OneToMany( mappedBy = "group", - cascade = CascadeType.ALL + //Remove is not here because we handle the deletion manually + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH} ) @OrderBy("modificationsOrder asc") private List modifications = new ArrayList<>(); diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/AbstractShuntCompensatorEmbeddable.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/AbstractShuntCompensatorEmbeddable.java index 5efb27669..ee55b25cb 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/AbstractShuntCompensatorEmbeddable.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/AbstractShuntCompensatorEmbeddable.java @@ -8,7 +8,6 @@ package org.gridsuite.modification.server.entities.equipment.modification; import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; import jakarta.persistence.MappedSuperclass; import lombok.AllArgsConstructor; import lombok.Getter; @@ -17,7 +16,6 @@ @NoArgsConstructor @AllArgsConstructor @Getter -@Embeddable @MappedSuperclass public abstract class AbstractShuntCompensatorEmbeddable { @Column(name = "shunt_compensator_id") diff --git a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/GeneratorScalingEntity.java b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/GeneratorScalingEntity.java index c1ffe564a..2d6d69746 100644 --- a/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/GeneratorScalingEntity.java +++ b/src/main/java/org/gridsuite/modification/server/entities/equipment/modification/GeneratorScalingEntity.java @@ -22,7 +22,7 @@ @Getter @Setter @Entity -@EqualsAndHashCode +@EqualsAndHashCode(callSuper = false) @Table(name = "GeneratorScaling") public class GeneratorScalingEntity extends ScalingEntity { diff --git a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java index 14c310fb0..52305981e 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -466,8 +466,10 @@ public void deleteModificationGroup(UUID groupUuid, boolean errorOnGroupNotFound try { ModificationGroupEntity groupEntity = getModificationGroup(groupUuid); if (!groupEntity.getModifications().isEmpty()) { - deleteModifications(groupEntity.getModifications().stream().filter(Objects::nonNull).toList()); - groupEntity.getModifications().clear(); + //TODO: is there a way to avoid doing this setGroup(null) that triggers a useless update since the entity will be deleted right after + groupEntity.getModifications().forEach(modif -> modif.setGroup(null)); + List modifications = groupEntity.getModifications(); + deleteModifications(modifications.stream().filter(Objects::nonNull).toList()); } modificationGroupRepository.delete(groupEntity); } catch (NetworkModificationException e) { diff --git a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java index 27775445f..0ef0533c5 100644 --- a/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java @@ -19,7 +19,6 @@ import com.powsybl.network.store.client.NetworkStoreService; import com.powsybl.network.store.client.PreloadingStrategy; import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl; -import jakarta.servlet.ServletException; import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.tuple.Pair; import org.gridsuite.modification.NetworkModificationException; @@ -52,9 +51,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; @@ -118,13 +117,13 @@ class ModificationControllerTest { @Autowired private ObjectMapper mapper; - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; @Autowired private NetworkModificationRepository modificationRepository; - @MockBean + @MockitoBean private ReportService reportService; @Autowired @@ -1613,11 +1612,16 @@ private MockMultipartFile createMockMultipartFile(String fileName) throws IOExce } @Test - void testPostLineTypeWithLimitsCatalogError() throws IOException { + void testPostLineTypeWithLimitsCatalogError() throws Exception { MockMultipartHttpServletRequestBuilder mockMultipartHttpServletRequestBuilder = multipart(URI_LINE_CATALOG) .file(createMockMultipartFile(NOT_EXISTING_JSON_FILE)); - String message = assertThrows(ServletException.class, () -> mockMvc.perform(mockMultipartHttpServletRequestBuilder)).getMessage(); - assertEquals("Request processing failed: java.io.UncheckedIOException: java.io.EOFException", message); + + mockMvc.perform(mockMultipartHttpServletRequestBuilder) + .andExpect(result -> { + assertNotNull(result.getResolvedException()); + assertEquals("java.io.EOFException", + result.getResolvedException().getMessage()); + }); } @Test diff --git a/src/test/java/org/gridsuite/modification/server/SupervisionControllerTest.java b/src/test/java/org/gridsuite/modification/server/SupervisionControllerTest.java index ed82d0f93..4d91449bc 100644 --- a/src/test/java/org/gridsuite/modification/server/SupervisionControllerTest.java +++ b/src/test/java/org/gridsuite/modification/server/SupervisionControllerTest.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.web.servlet.MockMvc; import java.util.UUID; @@ -24,7 +24,7 @@ @SpringBootTest @DisableElasticsearch class SupervisionControllerTest { - @SpyBean + @MockitoSpyBean private SupervisionService supervisionService; @Autowired diff --git a/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java index 30a64efda..1d547bff9 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/AbstractNetworkModificationTest.java @@ -35,8 +35,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -70,7 +70,6 @@ public abstract class AbstractNetworkModificationTest { private static final UUID TEST_NETWORK_ID = UUID.randomUUID(); private static final UUID NOT_FOUND_NETWORK_ID = UUID.randomUUID(); protected static final UUID TEST_GROUP_ID = UUID.randomUUID(); - private static final UUID TEST_REPORT_ID = UUID.randomUUID(); private static final String URI_NETWORK_MODIF_BASE = "/v1/network-modifications"; private static final String URI_NETWORK_MODIF_GET_PUT = URI_NETWORK_MODIF_BASE + "/"; @@ -83,10 +82,10 @@ public abstract class AbstractNetworkModificationTest { protected WireMockUtils wireMockUtils; - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; - @MockBean + @MockitoBean protected ReportService reportService; @Autowired diff --git a/src/test/java/org/gridsuite/modification/server/modifications/BalancesAdjustmentTest.java b/src/test/java/org/gridsuite/modification/server/modifications/BalancesAdjustmentTest.java index f73ed15a0..f5333aecb 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/BalancesAdjustmentTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/BalancesAdjustmentTest.java @@ -16,13 +16,14 @@ import org.gridsuite.modification.server.dto.NetworkModificationsResult; import org.gridsuite.modification.server.service.LoadFlowService; import org.gridsuite.modification.server.NetworkModificationServerException; +import org.gridsuite.modification.server.utils.elasticsearch.DisableElasticsearch; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MvcResult; import org.springframework.web.client.HttpStatusCodeException; @@ -40,12 +41,13 @@ * @author Joris Mancini */ @Tag("IntegrationTest") +@DisableElasticsearch class BalancesAdjustmentTest extends AbstractNetworkModificationTest { private static final UUID LOADFLOW_PARAMETERS_UUID = UUID.randomUUID(); private static final UUID NON_EXISTENT_LOADFLOW_PARAMETERS_UUID = UUID.randomUUID(); private static final UUID ERROR_LOADFLOW_PARAMETERS_UUID = UUID.randomUUID(); - @MockBean + @MockitoBean private LoadFlowService loadFlowService; @BeforeEach diff --git a/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java b/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java index 216267640..58d2ace41 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java @@ -20,8 +20,8 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.stubbing.Answer; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import java.util.List; import java.util.UUID; @@ -40,7 +40,7 @@ @Tag("IntegrationTest") class CompositeModificationsTest extends AbstractNetworkModificationTest { - @MockBean + @MockitoBean private NetworkModificationApplicator networkModificationApplicator; @BeforeEach diff --git a/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java b/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java index ceb79c2a8..f20ebd41d 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java @@ -365,7 +365,7 @@ void testSqlRequestsCountOnDeleteGroup() throws Exception { reset(); ApiUtils.deleteGroup(mockMvc, getGroupId()); // It is actually (8, 0, 0, 15) because deletes made in the native query are not counted - TestUtils.assertRequestsCount(8, 0, 0, 1); + TestUtils.assertRequestsCount(7, 0, 1, 1); assertEquals(0, modificationRepository.count()); assertEquals(0, tabularPropertyRepository.count()); } @@ -377,7 +377,7 @@ void testSqlRequestsCountOnDeleteGroup2() throws Exception { reset(); ApiUtils.deleteGroup(mockMvc, getGroupId()); // It is actually (12, 0, 0, 29) because deletes made in the native query are not counted - TestUtils.assertRequestsCount(12, 0, 0, 1); + TestUtils.assertRequestsCount(11, 0, 1, 1); assertEquals(0, modificationRepository.count()); } diff --git a/src/test/java/org/gridsuite/modification/server/service/BuildTest.java b/src/test/java/org/gridsuite/modification/server/service/BuildTest.java index 0667e7a29..961706d69 100644 --- a/src/test/java/org/gridsuite/modification/server/service/BuildTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/BuildTest.java @@ -52,13 +52,13 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.cloud.stream.binder.test.OutputDestination; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.messaging.Message; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.web.servlet.MockMvc; import java.io.IOException; @@ -125,7 +125,7 @@ class BuildTest { @Autowired private OutputDestination output; - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; @Autowired @@ -152,7 +152,7 @@ class BuildTest { @Autowired private EquipmentInfosRepository equipmentInfosRepository; - @SpyBean + @MockitoSpyBean private NotificationService notificationService; @Autowired diff --git a/src/test/java/org/gridsuite/modification/server/service/BuildWorkerServiceTest.java b/src/test/java/org/gridsuite/modification/server/service/BuildWorkerServiceTest.java index cab2e4d31..1872add92 100644 --- a/src/test/java/org/gridsuite/modification/server/service/BuildWorkerServiceTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/BuildWorkerServiceTest.java @@ -17,11 +17,11 @@ import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.cloud.stream.function.StreamBridge; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import java.util.HashMap; import java.util.List; @@ -41,9 +41,9 @@ class BuildWorkerServiceTest { private BuildWorkerService buildWorkerService; @Autowired private ObjectMapper objectMapper; - @MockBean + @MockitoBean private NetworkModificationService networkModificationService; - @MockBean + @MockitoBean private StreamBridge publisher; @Test diff --git a/src/test/java/org/gridsuite/modification/server/service/EquipmentIndexationTest.java b/src/test/java/org/gridsuite/modification/server/service/EquipmentIndexationTest.java index ad492f6a8..cf08bbdf2 100644 --- a/src/test/java/org/gridsuite/modification/server/service/EquipmentIndexationTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/EquipmentIndexationTest.java @@ -24,8 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -67,10 +67,10 @@ class EquipmentIndexationTest { @Autowired private ModificationRepository modificationRepository; - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; - @MockBean + @MockitoBean private ReportService reportService; @Autowired diff --git a/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java b/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java index b6d5fa610..7df893709 100644 --- a/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/ModificationIndexationTest.java @@ -36,7 +36,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import java.util.*; @@ -52,7 +52,7 @@ class ModificationIndexationTest { // Need to mock the send reports - @MockBean + @MockitoBean private ReportService reportService; @Autowired @@ -64,7 +64,7 @@ class ModificationIndexationTest { @Mock private NetworkInfos networkInfos; - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; @Mock diff --git a/src/test/java/org/gridsuite/modification/server/service/ModificationRepositoryTest.java b/src/test/java/org/gridsuite/modification/server/service/ModificationRepositoryTest.java index 4a3ddb6be..b00a9c9f1 100644 --- a/src/test/java/org/gridsuite/modification/server/service/ModificationRepositoryTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/ModificationRepositoryTest.java @@ -225,7 +225,7 @@ void testDeleteModificationQueryCount() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(5, 0, 0, 3); + assertRequestsCount(5, 0, 1, 3); // Non-existent group modification uuid assertThrows(NetworkModificationException.class, () -> networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true), @@ -264,7 +264,7 @@ void testLoadCreation() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(5, 0, 0, 3); + assertRequestsCount(5, 0, 1, 3); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, true, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); @@ -345,7 +345,7 @@ void testGeneratorCreation() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(5, 0, 0, 4); + assertRequestsCount(5, 0, 1, 4); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, true, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); @@ -395,7 +395,7 @@ void testShuntCompensatorCreation() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(5, 0, 0, 3); + assertRequestsCount(5, 0, 1, 3); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, true, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); @@ -475,7 +475,7 @@ void testLineCreation() { networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); // TODO : Due to an issue the deletion counter is not deterministic // https://github.com/jdbc-observations/datasource-proxy/issues/123 - assertRequestsCount(9, 0, 0); + assertRequestsCount(9, 0, 1); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, true, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); @@ -714,7 +714,7 @@ void testGroovyScript() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(4, 0, 0, 3); + assertRequestsCount(4, 0, 1, 3); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, false, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); @@ -767,7 +767,7 @@ void testSubstationCreation() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(5, 0, 1, 4); + assertRequestsCount(5, 0, 2, 4); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, false, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); @@ -857,7 +857,7 @@ void testStatusLineModification() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); // n+1 query because we are deleting modifications 1 by 1, it's for now accepted according to a comment in "deleteModificationGroup" - assertRequestsCount(9, 0, 0, 3); + assertRequestsCount(9, 0, 1, 3); } @Test @@ -1367,7 +1367,7 @@ void testStaticVarCompensatorCreation() { SQLStatementCountValidator.reset(); networkModificationRepository.deleteModificationGroup(TEST_GROUP_ID, true); - assertRequestsCount(5, 0, 0, 3); + assertRequestsCount(5, 0, 1, 3); assertThrows(NetworkModificationException.class, () -> networkModificationRepository.getModifications(TEST_GROUP_ID, true, true), new NetworkModificationException(MODIFICATION_GROUP_NOT_FOUND, TEST_GROUP_ID.toString()).getMessage()); diff --git a/src/test/java/org/gridsuite/modification/server/service/ModificationSearchTest.java b/src/test/java/org/gridsuite/modification/server/service/ModificationSearchTest.java index f0eea7243..53639970e 100644 --- a/src/test/java/org/gridsuite/modification/server/service/ModificationSearchTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/ModificationSearchTest.java @@ -32,7 +32,7 @@ import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import java.util.*; import java.util.stream.Collectors; @@ -57,7 +57,7 @@ class ModificationSearchTest { @Mock private NetworkInfos networkInfos; - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; @Mock diff --git a/src/test/java/org/gridsuite/modification/server/service/NetworkModificationApplicatorTest.java b/src/test/java/org/gridsuite/modification/server/service/NetworkModificationApplicatorTest.java index ea34efbe2..10664675d 100644 --- a/src/test/java/org/gridsuite/modification/server/service/NetworkModificationApplicatorTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/NetworkModificationApplicatorTest.java @@ -31,8 +31,8 @@ import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import java.util.List; import java.util.UUID; @@ -47,19 +47,19 @@ @Tag("UnitTest") class NetworkModificationApplicatorTest { - @MockBean + @MockitoBean private NetworkStoreService networkStoreService; - @MockBean + @MockitoBean private ReportService reportService; - @MockBean + @MockitoBean private FilterService filterService; - @MockBean + @MockitoBean private NetworkModificationObserver networkModificationObserver; - @SpyBean + @MockitoSpyBean private LargeNetworkModificationExecutionService largeNetworkModificationExecutionService; @Autowired diff --git a/src/test/java/org/gridsuite/modification/server/service/SupervisionTest.java b/src/test/java/org/gridsuite/modification/server/service/SupervisionTest.java index d367bf844..07fe3b97d 100644 --- a/src/test/java/org/gridsuite/modification/server/service/SupervisionTest.java +++ b/src/test/java/org/gridsuite/modification/server/service/SupervisionTest.java @@ -14,10 +14,10 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.http.HttpStatus; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.web.server.ResponseStatusException; import java.util.List; @@ -36,16 +36,16 @@ class SupervisionTest { @Autowired private SupervisionService supervisionService; - @MockBean + @MockitoBean private ElasticsearchOperations elasticsearchOperations; - @MockBean + @MockitoBean private IndexOperations indexOperations; - @MockBean + @MockitoBean private ModificationApplicationRepository modificationApplicationRepository; - @MockBean + @MockitoBean private ModificationApplicationInfosRepository modificationApplicationInfosRepository; @Captor diff --git a/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/DisableElasticsearch.java b/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/DisableElasticsearch.java index aed3fdf52..5aa310c29 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/DisableElasticsearch.java +++ b/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/DisableElasticsearch.java @@ -10,8 +10,12 @@ import org.gridsuite.modification.server.elasticsearch.EquipmentInfosRepository; import org.gridsuite.modification.server.elasticsearch.TombstonedEquipmentInfosRepository; import org.junit.jupiter.api.Tag; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.MockBeans; +import org.mockito.Mockito; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.test.context.TestPropertySource; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -23,7 +27,39 @@ */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) -@MockBeans({@MockBean(EmbeddedElasticsearch.class), @MockBean(EquipmentInfosRepository.class), @MockBean(ModificationApplicationInfosRepository.class), @MockBean(TombstonedEquipmentInfosRepository.class)}) +@TestPropertySource(properties = { + "spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration" +}) +@Import(DisableElasticsearch.MockConfig.class) @Tag("Docker") public @interface DisableElasticsearch { + + @TestConfiguration(proxyBeanMethods = false) + class MockConfig { + @Bean + public EmbeddedElasticsearch embeddedElasticsearch() { + return Mockito.mock(EmbeddedElasticsearch.class); + } + + @Bean + public EquipmentInfosRepository equipmentInfosRepository() { + return Mockito.mock(EquipmentInfosRepository.class); + } + + @Bean + public ModificationApplicationInfosRepository modificationApplicationInfosRepository() { + return Mockito.mock(ModificationApplicationInfosRepository.class); + } + + @Bean + public TombstonedEquipmentInfosRepository tombstonedEquipmentInfosRepository() { + return Mockito.mock(TombstonedEquipmentInfosRepository.class); + } + + @Bean + public ElasticsearchOperations elasticsearchOperations() { + return Mockito.mock(ElasticsearchOperations.class); + } + } + } From 54d990ca7ccdcbe4de7f47d62f82bf3a5a773f87 Mon Sep 17 00:00:00 2001 From: Abdelsalem Date: Mon, 20 Oct 2025 12:22:56 +0200 Subject: [PATCH 2/4] elasticsearch 8.7.1 -> 8.15.5 in tests Signed-off-by: Abdelsalem --- .../server/utils/elasticsearch/EmbeddedElasticsearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/EmbeddedElasticsearch.java b/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/EmbeddedElasticsearch.java index 73e5221b7..eadb638e9 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/EmbeddedElasticsearch.java +++ b/src/test/java/org/gridsuite/modification/server/utils/elasticsearch/EmbeddedElasticsearch.java @@ -21,7 +21,7 @@ public class EmbeddedElasticsearch { private static final String ES_DOCKER_IMAGE_NAME = "docker.elastic.co/elasticsearch/elasticsearch"; - private static final String ES_DOCKER_IMAGE_VERSION = "8.7.1"; + private static final String ES_DOCKER_IMAGE_VERSION = "8.15.5"; private static ElasticsearchContainer elasticsearchContainer; From dd03118bea835d37fd92a0f8308df0d7d801a9e9 Mon Sep 17 00:00:00 2001 From: Abdelsalem Date: Thu, 30 Oct 2025 09:16:21 +0100 Subject: [PATCH 3/4] update filter version Signed-off-by: Abdelsalem --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be8d17dde..66905e02e 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.31.0 2.14.1 - 1.6.0 + 1.7.0 From 44f1a57d09f0865936e6d7574f7596262599b18f Mon Sep 17 00:00:00 2001 From: HARPER Jon Date: Fri, 31 Oct 2025 17:45:03 +0100 Subject: [PATCH 4/4] Fix hangs when applying modification (network store service flush) Springboot now uses httpclients detected from the classpath, in our case ReactorClient. The workaround is to go back to using restclient simple as the resttemplate implementation in networkstore service. This has the additional advantage of avoiding 20 exta threads for netty.. For some reason (I don't know if it's a bug in reactor client or a bug in our code...), during network store flush after a modification, sometimes one of the http requests never returns from reactorclient. So our code blocks infinitely in the message consumer waiting for the http requests to return (waitAllFutures) Additionally, we can see in the network store server logs "java.net.SocketTimeoutException" after 30s. Threads when blocked Thread A at app//com.powsybl.network.store.client.util.ExecutorUtil.waitAllFutures(ExecutorUtil.java:52) at app//com.powsybl.network.store.client.BufferedNetworkStoreClient.flush(BufferedNetworkStoreClient.java:599) at app//com.powsybl.network.store.iidm.impl.AbstractForwardingNetworkStoreClient.flush(AbstractForwardingNetworkStoreClient.java:18) at app//com.powsybl.network.store.iidm.impl.AbstractForwardingNetworkStoreClient.flush(AbstractForwardingNetworkStoreClient.java:18) at app//com.powsybl.network.store.client.NetworkStoreService.flush(NetworkStoreService.java:246) at app//org.gridsuite.modification.server.modifications.NetworkStoreListener.flushModificationApplications(NetworkStoreListener.java:264) "pool-2-thread-2" - Thread t@111 java.lang.Thread.State: WAITING at java.base@21.0.6/jdk.internal.misc.Unsafe.park(Native Method) - parking to wait for <26231e99> (a java.util.concurrent.CountDownLatch$Sync) at java.base@21.0.6/java.util.concurrent.locks.LockSupport.park(Unknown Source) at java.base@21.0.6/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Unknown Source) at java.base@21.0.6/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source) at java.base@21.0.6/java.util.concurrent.CountDownLatch.await(Unknown Source) at app//reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:91) at app//reactor.core.publisher.Mono.block(Mono.java:1779) at app//org.springframework.http.client.ReactorClientHttpRequest.executeInternal(ReactorClientHttpRequest.java:129) at app//org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:71) at app//org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:81) at app//org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:900) at app//org.springframework.web.client.RestTemplate.execute(RestTemplate.java:801) at app//org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:683) at app//com.powsybl.network.store.client.RestClientImpl.updateAll(RestClientImpl.java:134) Also, because we kind of miscoded the NetworkStoreService, it can't use standards spring boot systems (RestTemplateCustomizer, or --spring.http.client.factory=simple) to change its behavior, so we have to override it fully with @primary --- .../NetworkModificationApplication.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/org/gridsuite/modification/server/NetworkModificationApplication.java b/src/main/java/org/gridsuite/modification/server/NetworkModificationApplication.java index 3881d8723..55cacaacf 100644 --- a/src/main/java/org/gridsuite/modification/server/NetworkModificationApplication.java +++ b/src/main/java/org/gridsuite/modification/server/NetworkModificationApplication.java @@ -7,8 +7,15 @@ package org.gridsuite.modification.server; import com.powsybl.network.store.client.NetworkStoreService; +import com.powsybl.network.store.client.PreloadingStrategy; +import com.powsybl.network.store.client.RestClientImpl; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; /** * @author Franck Lecuyer @@ -19,4 +26,20 @@ public class NetworkModificationApplication { public static void main(String[] args) { SpringApplication.run(NetworkModificationApplication.class, args); } + + + // Override NetworkStoreService defined in the lib network-store-client + // because it always autodetects the resttemplate httpclient from the classpath + // instead of using the resttemplatebuilder that can be controlled by runtime configuration/ + @Primary + @Bean + public NetworkStoreService networkstoreservice( + @Value("${powsybl.services.network-store-server.base-uri:http://network-store-server/}") String baseUri, + @Value("${powsybl.services.network-store-server.preloading-strategy:NONE}") PreloadingStrategy defaultPreloadingStrategy + ) { + RestTemplateBuilder builder = RestClientImpl.createRestTemplateBuilder(baseUri); + builder = builder.requestFactoryBuilder(ClientHttpRequestFactoryBuilder.simple()); + RestClientImpl restClient = new RestClientImpl(builder); + return new NetworkStoreService(restClient, defaultPreloadingStrategy); + } }