diff --git a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java index 0e100078..1bbdcdea 100644 --- a/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java +++ b/src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java @@ -7,6 +7,7 @@ package org.gridsuite.securityanalysis.server.service; import com.fasterxml.jackson.databind.ObjectMapper; +import com.powsybl.commons.io.TreeDataFormat; import com.powsybl.commons.report.ReportNode; import com.powsybl.commons.report.TypedValue; import com.powsybl.contingency.Contingency; @@ -20,6 +21,8 @@ import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.NetworkFactory; import com.powsybl.iidm.network.VariantManagerConstants; +import com.powsybl.iidm.serde.ExportOptions; +import com.powsybl.iidm.serde.ImportOptions; import com.powsybl.iidm.serde.NetworkSerDe; import com.powsybl.loadflow.LoadFlowResult; import com.powsybl.network.store.client.NetworkStoreService; @@ -40,11 +43,10 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; +import java.io.*; +import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -66,6 +68,22 @@ public class SecurityAnalysisWorkerService extends AbstractWorkerService securityAnalysisFactorySupplier; + private static final Set OPENLOADFLOW_SECURITY_ANALYSIS_EXTENSIONS = Set.of( + "detail", + "slackTerminal", + "activePowerControl", + "voltageRegulation", + "lineFortescue", + "loadAsymmetrical", + "coordinatedReactiveControl", + "generatorFortescue", + "hvdcAngleDroopActivePowerControl", + "hvdcOperatorActivePowerRange", + "secondaryVoltageControl", + "voltagePerReactivePowerControl", + "standbyAutomaton", + "generatorRemoteReactivePowerControl"); + public SecurityAnalysisWorkerService(NetworkStoreService networkStoreService, ActionsService actionsService, ReportService reportService, SecurityAnalysisResultService resultService, ObjectMapper objectMapper, SecurityAnalysisRunnerSupplier securityAnalysisRunnerSupplier, NotificationService notificationService, ExecutionService executionService, @@ -125,7 +143,7 @@ protected CompletableFuture getCompletableFuture(Securit String originalVariant = originalNetwork.getVariantManager().getWorkingVariantId(); originalNetwork.getVariantManager().setWorkingVariant(variantId); - network = NetworkSerDe.copy(originalNetwork, NetworkFactory.find("Default")); + network = copy(originalNetwork, NetworkFactory.find("Default")); if (!variantId.equals(VariantManagerConstants.INITIAL_VARIANT_ID)) { network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, variantId); } @@ -148,6 +166,30 @@ protected CompletableFuture getCompletableFuture(Securit .thenApply(SecurityAnalysisReport::getResult); } + private static Network copy(Network network, NetworkFactory networkFactory) { + Objects.requireNonNull(network); + Objects.requireNonNull(networkFactory); + PipedOutputStream pos = new PipedOutputStream(); + try (InputStream is = new PipedInputStream(pos)) { + ForkJoinPool.commonPool().execute(() -> { + try { + NetworkSerDe.write(network, new ExportOptions().setExtensions(OPENLOADFLOW_SECURITY_ANALYSIS_EXTENSIONS).setFormat(TreeDataFormat.JSON), pos); + } catch (Exception t) { + LOGGER.error(t.toString(), t); + } finally { + try { + pos.close(); + } catch (IOException e) { + LOGGER.error(e.toString(), e); + } + } + }); + return NetworkSerDe.read(is, new ImportOptions().setExtensions(OPENLOADFLOW_SECURITY_ANALYSIS_EXTENSIONS).setFormat(TreeDataFormat.JSON), null, networkFactory, ReportNode.NO_OP); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + private List createLimitReductions(SecurityAnalysisRunContext runContext) { List limitReductions = new ArrayList<>(limitReductionService.getVoltageLevels().size() * limitReductionService.getLimitDurations().size());