77package org .gridsuite .securityanalysis .server .service ;
88
99import com .fasterxml .jackson .databind .ObjectMapper ;
10+ import com .powsybl .commons .io .TreeDataFormat ;
1011import com .powsybl .commons .report .ReportNode ;
1112import com .powsybl .commons .report .TypedValue ;
1213import com .powsybl .contingency .Contingency ;
2021import com .powsybl .iidm .network .Network ;
2122import com .powsybl .iidm .network .NetworkFactory ;
2223import com .powsybl .iidm .network .VariantManagerConstants ;
24+ import com .powsybl .iidm .serde .ExportOptions ;
25+ import com .powsybl .iidm .serde .ImportOptions ;
2326import com .powsybl .iidm .serde .NetworkSerDe ;
2427import com .powsybl .loadflow .LoadFlowResult ;
2528import com .powsybl .network .store .client .NetworkStoreService ;
4043import org .springframework .stereotype .Service ;
4144import org .springframework .util .CollectionUtils ;
4245
43- import java .util .ArrayList ;
44- import java .util .List ;
45- import java .util .Objects ;
46- import java .util .UUID ;
46+ import java .io .*;
47+ import java .util .*;
4748import java .util .concurrent .CompletableFuture ;
49+ import java .util .concurrent .ForkJoinPool ;
4850import java .util .concurrent .TimeUnit ;
4951import java .util .concurrent .atomic .AtomicReference ;
5052import java .util .function .Consumer ;
@@ -66,6 +68,22 @@ public class SecurityAnalysisWorkerService extends AbstractWorkerService<Securit
6668
6769 private Function <String , SecurityAnalysis .Runner > securityAnalysisFactorySupplier ;
6870
71+ private static final Set <String > OPENLOADFLOW_SECURITY_ANALYSIS_EXTENSIONS = Set .of (
72+ "detail" ,
73+ "slackTerminal" ,
74+ "activePowerControl" ,
75+ "voltageRegulation" ,
76+ "lineFortescue" ,
77+ "loadAsymmetrical" ,
78+ "coordinatedReactiveControl" ,
79+ "generatorFortescue" ,
80+ "hvdcAngleDroopActivePowerControl" ,
81+ "hvdcOperatorActivePowerRange" ,
82+ "secondaryVoltageControl" ,
83+ "voltagePerReactivePowerControl" ,
84+ "standbyAutomaton" ,
85+ "generatorRemoteReactivePowerControl" );
86+
6987 public SecurityAnalysisWorkerService (NetworkStoreService networkStoreService , ActionsService actionsService , ReportService reportService ,
7088 SecurityAnalysisResultService resultService , ObjectMapper objectMapper ,
7189 SecurityAnalysisRunnerSupplier securityAnalysisRunnerSupplier , NotificationService notificationService , ExecutionService executionService ,
@@ -125,7 +143,7 @@ protected CompletableFuture<SecurityAnalysisResult> getCompletableFuture(Securit
125143 String originalVariant = originalNetwork .getVariantManager ().getWorkingVariantId ();
126144 originalNetwork .getVariantManager ().setWorkingVariant (variantId );
127145
128- network = NetworkSerDe . copy (originalNetwork , NetworkFactory .find ("Default" ));
146+ network = copy (originalNetwork , NetworkFactory .find ("Default" ));
129147 if (!variantId .equals (VariantManagerConstants .INITIAL_VARIANT_ID )) {
130148 network .getVariantManager ().cloneVariant (VariantManagerConstants .INITIAL_VARIANT_ID , variantId );
131149 }
@@ -148,6 +166,30 @@ protected CompletableFuture<SecurityAnalysisResult> getCompletableFuture(Securit
148166 .thenApply (SecurityAnalysisReport ::getResult );
149167 }
150168
169+ private static Network copy (Network network , NetworkFactory networkFactory ) {
170+ Objects .requireNonNull (network );
171+ Objects .requireNonNull (networkFactory );
172+ PipedOutputStream pos = new PipedOutputStream ();
173+ try (InputStream is = new PipedInputStream (pos )) {
174+ ForkJoinPool .commonPool ().execute (() -> {
175+ try {
176+ NetworkSerDe .write (network , new ExportOptions ().setExtensions (OPENLOADFLOW_SECURITY_ANALYSIS_EXTENSIONS ).setFormat (TreeDataFormat .JSON ), pos );
177+ } catch (Exception t ) {
178+ LOGGER .error (t .toString (), t );
179+ } finally {
180+ try {
181+ pos .close ();
182+ } catch (IOException e ) {
183+ LOGGER .error (e .toString (), e );
184+ }
185+ }
186+ });
187+ return NetworkSerDe .read (is , new ImportOptions ().setExtensions (OPENLOADFLOW_SECURITY_ANALYSIS_EXTENSIONS ).setFormat (TreeDataFormat .JSON ), null , networkFactory , ReportNode .NO_OP );
188+ } catch (IOException e ) {
189+ throw new UncheckedIOException (e );
190+ }
191+ }
192+
151193 private List <LimitReduction > createLimitReductions (SecurityAnalysisRunContext runContext ) {
152194 List <LimitReduction > limitReductions = new ArrayList <>(limitReductionService .getVoltageLevels ().size () * limitReductionService .getLimitDurations ().size ());
153195
0 commit comments