Skip to content

Commit 3518dc0

Browse files
committed
move apply in another component using its own Tx
Signed-off-by: David BRAQUART <[email protected]>
1 parent 87d58fc commit 3518dc0

File tree

5 files changed

+67
-41
lines changed

5 files changed

+67
-41
lines changed

src/main/java/org/gridsuite/modification/server/modifications/NetworkModificationApplicator.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
1717
import com.powsybl.network.store.client.NetworkStoreService;
1818
import com.powsybl.network.store.client.PreloadingStrategy;
1919
import lombok.Getter;
20+
import lombok.NonNull;
2021
import org.gridsuite.modification.ModificationType;
2122
import org.gridsuite.modification.dto.ModificationInfos;
2223
import org.gridsuite.modification.modifications.AbstractModification;
24+
import org.gridsuite.modification.server.dto.ModificationApplicationContext;
2325
import org.gridsuite.modification.server.dto.ModificationApplicationGroup;
2426
import org.gridsuite.modification.server.dto.NetworkInfos;
2527
import org.gridsuite.modification.server.dto.NetworkModificationResult;
2628
import org.gridsuite.modification.server.dto.NetworkModificationResult.ApplicationStatus;
29+
import org.gridsuite.modification.server.dto.NetworkModificationsResult;
30+
import org.gridsuite.modification.server.dto.ReportInfos;
2731
import org.gridsuite.modification.server.elasticsearch.EquipmentInfosService;
2832
import org.gridsuite.modification.server.elasticsearch.ModificationApplicationInfosService;
2933
import org.gridsuite.modification.server.entities.ModificationEntity;
@@ -33,9 +37,12 @@
3337
import org.slf4j.Logger;
3438
import org.slf4j.LoggerFactory;
3539
import org.springframework.beans.factory.annotation.Value;
40+
import org.springframework.context.annotation.Lazy;
3641
import org.springframework.stereotype.Service;
42+
import org.springframework.transaction.annotation.Transactional;
3743

3844
import java.util.List;
45+
import java.util.Optional;
3946
import java.util.UUID;
4047

4148
import static org.gridsuite.modification.server.report.NetworkModificationServerReportResourceBundle.ERROR_MESSAGE_KEY;
@@ -55,6 +62,8 @@ public class NetworkModificationApplicator {
5562

5663
private final ReportService reportService;
5764

65+
private final NetworkModificationService networkModificationService;
66+
5867
@Getter private final FilterService filterService;
5968

6069
@Getter private final LoadFlowService loadFlowService;
@@ -77,6 +86,7 @@ public NetworkModificationApplicator(NetworkStoreService networkStoreService, Eq
7786
LoadFlowService loadFlowService,
7887
NetworkModificationObserver networkModificationObserver,
7988
NetworkModificationRepository networkModificationRepository,
89+
@Lazy NetworkModificationService networkModificationService,
8090
LargeNetworkModificationExecutionService largeNetworkModificationExecutionService) {
8191
this.networkStoreService = networkStoreService;
8292
this.equipmentInfosService = equipmentInfosService;
@@ -86,6 +96,7 @@ public NetworkModificationApplicator(NetworkStoreService networkStoreService, Eq
8696
this.loadFlowService = loadFlowService;
8797
this.networkModificationObserver = networkModificationObserver;
8898
this.networkModificationRepository = networkModificationRepository;
99+
this.networkModificationService = networkModificationService;
89100
this.largeNetworkModificationExecutionService = largeNetworkModificationExecutionService;
90101
}
91102

@@ -263,4 +274,41 @@ public static ApplicationStatus getApplicationStatus(ReportNode reportNode) {
263274
throw new IllegalArgumentException(String.format("Report severity '%s' unknown !", severity.getValue()));
264275
}
265276
}
277+
278+
/**
279+
* Apply modifications on several networks
280+
*/
281+
public List<Optional<NetworkModificationResult>> applyModifications(UUID groupUuid, List<ModificationEntity> modifications, List<ModificationApplicationContext> applicationContexts) {
282+
return applicationContexts.stream().map(modificationApplicationContext ->
283+
applyModifications(
284+
modificationApplicationContext.networkUuid(),
285+
modificationApplicationContext.variantId(),
286+
new ModificationApplicationGroup(groupUuid,
287+
modifications.stream().filter(m -> !modificationApplicationContext.excludedModifications().contains(m.getId())).toList(),
288+
new ReportInfos(modificationApplicationContext.reportUuid(), modificationApplicationContext.reporterId())
289+
))
290+
).toList();
291+
}
292+
293+
private Optional<NetworkModificationResult> applyModifications(UUID networkUuid, String variantId, ModificationApplicationGroup modificationGroupInfos) {
294+
if (!modificationGroupInfos.modifications().isEmpty()) {
295+
PreloadingStrategy preloadingStrategy = modificationGroupInfos.modifications().stream()
296+
.map(ModificationEntity::getType)
297+
.map(ModificationType::valueOf)
298+
.reduce(ModificationType::maxStrategy).map(ModificationType::getStrategy).orElse(PreloadingStrategy.NONE);
299+
NetworkInfos networkInfos = networkModificationService.getNetworkInfos(networkUuid, variantId, preloadingStrategy);
300+
301+
// try to apply the modifications (incremental mode)
302+
if (networkInfos.isVariantPresent()) {
303+
return Optional.of(applyModifications(modificationGroupInfos, networkInfos));
304+
}
305+
}
306+
return Optional.empty();
307+
}
308+
309+
@Transactional
310+
public NetworkModificationsResult applyNewNetworkModification(@NonNull UUID modificationUuid, @NonNull UUID groupUuid, @NonNull List<ModificationApplicationContext> applicationContexts) {
311+
ModificationEntity entity = networkModificationRepository.getModificationEntity(modificationUuid);
312+
return new NetworkModificationsResult(List.of(modificationUuid), applyModifications(groupUuid, List.of(entity), applicationContexts));
313+
}
266314
}

src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ public void deleteAll() {
109109
// This method should be package-private and not used as API of the service as it uses ModificationEntity and
110110
// we want to encapsulate the use of Entity related objects to this service.
111111
// Nevertheless We have to keep it public for transactional annotation.
112+
// TODO: only used by tests - could be replaced by function below ?
112113
public List<ModificationEntity> saveModifications(UUID groupUuid, List<ModificationEntity> modifications) {
113114
return saveModificationsNonTransactional(groupUuid, modifications);
114115
}
115116

117+
@Transactional
116118
public List<ModificationEntity> saveModificationInfos(UUID groupUuid, List<ModificationInfos> modifications) {
117119
List<ModificationEntity> entities = modifications.stream().map(ModificationEntity::fromDTO).toList();
118120

src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -191,27 +191,11 @@ public void restoreNetworkModifications(UUID groupUuid, @NonNull List<UUID> modi
191191
networkModificationRepository.getModificationsCount(groupUuid, false));
192192
}
193193

194-
@Transactional
195194
public NetworkModificationsResult createNetworkModification(@NonNull UUID groupUuid, @NonNull ModificationInfos modificationInfo, @NonNull List<ModificationApplicationContext> applicationContexts) {
195+
// We call 2 methods having a distinct Transaction. This is important for this use-case: when we create a Modification M on a built node,
196+
// we want M to be inserted in database even if apply(M) raises an exception.
196197
List<ModificationEntity> modificationEntities = networkModificationRepository.saveModificationInfos(groupUuid, List.of(modificationInfo));
197-
198-
return new NetworkModificationsResult(modificationEntities.stream().map(ModificationEntity::getId).toList(),
199-
applyModifications(groupUuid, modificationEntities, applicationContexts));
200-
}
201-
202-
/**
203-
* Apply modifications on several networks
204-
*/
205-
private List<Optional<NetworkModificationResult>> applyModifications(UUID groupUuid, List<ModificationEntity> modifications, List<ModificationApplicationContext> applicationContexts) {
206-
return applicationContexts.stream().map(modificationApplicationContext ->
207-
applyModifications(
208-
modificationApplicationContext.networkUuid(),
209-
modificationApplicationContext.variantId(),
210-
new ModificationApplicationGroup(groupUuid,
211-
modifications.stream().filter(m -> !modificationApplicationContext.excludedModifications().contains(m.getId())).toList(),
212-
new ReportInfos(modificationApplicationContext.reportUuid(), modificationApplicationContext.reporterId())
213-
))
214-
).toList();
198+
return modificationApplicator.applyNewNetworkModification(modificationEntities.getFirst().getId(), groupUuid, applicationContexts);
215199
}
216200

217201
public Network cloneNetworkVariant(UUID networkUuid,
@@ -292,7 +276,7 @@ public NetworkModificationsResult moveModifications(@NonNull UUID destinationGro
292276
// update origin/destinations groups to cut and paste all modificationsToMove
293277
List<ModificationEntity> modificationEntities = networkModificationRepository.moveModifications(destinationGroupUuid, originGroupUuid, modificationsToMoveUuids, beforeModificationUuid);
294278

295-
List<Optional<NetworkModificationResult>> result = applyModifications && !modificationEntities.isEmpty() ? applyModifications(destinationGroupUuid, modificationEntities, applicationContexts) : List.of();
279+
List<Optional<NetworkModificationResult>> result = applyModifications && !modificationEntities.isEmpty() ? modificationApplicator.applyModifications(destinationGroupUuid, modificationEntities, applicationContexts) : List.of();
296280
return new NetworkModificationsResult(modificationEntities.stream().map(ModificationEntity::getId).toList(), result);
297281
}
298282

@@ -316,22 +300,6 @@ public Map<UUID, UUID> duplicateGroup(UUID sourceGroupUuid, UUID groupUuid) {
316300
}
317301
}
318302

319-
private Optional<NetworkModificationResult> applyModifications(UUID networkUuid, String variantId, ModificationApplicationGroup modificationGroupInfos) {
320-
if (!modificationGroupInfos.modifications().isEmpty()) {
321-
PreloadingStrategy preloadingStrategy = modificationGroupInfos.modifications().stream()
322-
.map(ModificationEntity::getType)
323-
.map(ModificationType::valueOf)
324-
.reduce(ModificationType::maxStrategy).map(ModificationType::getStrategy).orElse(PreloadingStrategy.NONE);
325-
NetworkInfos networkInfos = getNetworkInfos(networkUuid, variantId, preloadingStrategy);
326-
327-
// try to apply the duplicated modifications (incremental mode)
328-
if (networkInfos.isVariantPresent()) {
329-
return Optional.of(modificationApplicator.applyModifications(modificationGroupInfos, networkInfos));
330-
}
331-
}
332-
return Optional.empty();
333-
}
334-
335303
@Transactional
336304
public NetworkModificationsResult duplicateModifications(@NonNull UUID targetGroupUuid, UUID originGroupUuid, @NonNull List<UUID> modificationsUuids, @NonNull List<ModificationApplicationContext> applicationContexts) {
337305
if (originGroupUuid != null && !modificationsUuids.isEmpty()) { // Duplicate modifications from a group or from a list only
@@ -341,15 +309,15 @@ public NetworkModificationsResult duplicateModifications(@NonNull UUID targetGro
341309
List<ModificationEntity> duplicateModifications = networkModificationRepository.saveModificationInfos(targetGroupUuid, modificationInfos);
342310
return new NetworkModificationsResult(
343311
duplicateModifications.stream().map(ModificationEntity::getId).toList(),
344-
applyModifications(targetGroupUuid, duplicateModifications, applicationContexts)
312+
modificationApplicator.applyModifications(targetGroupUuid, duplicateModifications, applicationContexts)
345313
);
346314
}
347315

348316
@Transactional
349317
public NetworkModificationsResult insertCompositeModifications(@NonNull UUID targetGroupUuid, @NonNull List<UUID> modificationsUuids, @NonNull List<ModificationApplicationContext> applicationContexts) {
350318
List<ModificationInfos> modificationInfos = networkModificationRepository.getCompositeModificationsInfos(modificationsUuids);
351319
List<ModificationEntity> modificationEntities = networkModificationRepository.saveModificationInfos(targetGroupUuid, modificationInfos);
352-
return new NetworkModificationsResult(modificationEntities.stream().map(ModificationEntity::getId).toList(), applyModifications(targetGroupUuid, modificationEntities, applicationContexts));
320+
return new NetworkModificationsResult(modificationEntities.stream().map(ModificationEntity::getId).toList(), modificationApplicator.applyModifications(targetGroupUuid, modificationEntities, applicationContexts));
353321
}
354322

355323
@Transactional

src/test/java/org/gridsuite/modification/server/ModificationControllerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ void testNetworkModificationsWithErrorOnNetworkFlush() throws Exception {
451451

452452
mockMvc.perform(post(NETWORK_MODIFICATION_URI).content(groovyScriptInfosJson).contentType(MediaType.APPLICATION_JSON)).andExpect(status().is5xxServerError());
453453

454-
assertEquals(0, modificationRepository.getModifications(TEST_GROUP_ID, true, false).size());
454+
assertEquals(1, modificationRepository.getModifications(TEST_GROUP_ID, true, false).size());
455455
}
456456

457457
@Test

src/test/java/org/gridsuite/modification/server/modifications/CompositeModificationsTest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.gridsuite.modification.dto.ModificationInfos;
1515
import org.gridsuite.modification.server.dto.ModificationApplicationGroup;
1616
import org.gridsuite.modification.server.dto.NetworkModificationResult;
17+
import org.gridsuite.modification.server.dto.NetworkModificationsResult;
1718
import org.gridsuite.modification.server.utils.ModificationCreation;
1819
import org.gridsuite.modification.server.utils.NetworkCreation;
1920
import org.junit.jupiter.api.BeforeEach;
@@ -24,6 +25,7 @@
2425
import org.springframework.http.MediaType;
2526

2627
import java.util.List;
28+
import java.util.Optional;
2729
import java.util.UUID;
2830

2931
import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount;
@@ -40,19 +42,25 @@
4042
@Tag("IntegrationTest")
4143
class CompositeModificationsTest extends AbstractNetworkModificationTest {
4244

45+
// TODO We try to create a Composite Modification using the generic way like any other modification.
46+
// But a Composite Modification should be created using a dedicated endpoint, so maybe this test is not relevant?
47+
4348
@MockBean
4449
private NetworkModificationApplicator networkModificationApplicator;
4550

4651
@BeforeEach
4752
void specificSetUp() {
4853
// Currently we never apply composite modifications (apply mocked)
49-
NetworkModificationResult networkModificationResultMock = NetworkModificationResult.builder()
54+
NetworkModificationResult result = NetworkModificationResult.builder()
5055
.applicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK)
5156
.lastGroupApplicationStatus(NetworkModificationResult.ApplicationStatus.ALL_OK)
5257
.networkImpacts(List.of())
5358
.build();
5459
when(networkModificationApplicator.applyModifications(any(ModificationApplicationGroup.class), any()))
55-
.then((Answer<NetworkModificationResult>) invocation -> networkModificationResultMock);
60+
.then((Answer<NetworkModificationResult>) invocation -> result);
61+
when(networkModificationApplicator.applyNewNetworkModification(any(UUID.class), any(UUID.class), any()))
62+
.then((Answer<NetworkModificationsResult>) invocation ->
63+
new NetworkModificationsResult(List.of(UUID.randomUUID()), List.of(Optional.of(result))));
5664
}
5765

5866
@Override

0 commit comments

Comments
 (0)