Skip to content

Commit

Permalink
Merge branch 'main' into rao_parameters_forbid_cost_increase_always_true
Browse files Browse the repository at this point in the history
  • Loading branch information
phiedw authored Oct 30, 2024
2 parents b1a5757 + 7d8318c commit 82aacb6
Show file tree
Hide file tree
Showing 39 changed files with 1,009 additions and 479 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @author Viktor Terrier {@literal <viktor.terrier at rte-france.com>}
* @author Peter Mitri {@literal <peter.mitri at rte-france.com>}
*/
class JsonCracCreationContext implements CracCreationContext {
public class JsonCracCreationContext implements CracCreationContext {
private final boolean isCreationSuccessful;
private final Crac crac;
private final String networkName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.powsybl.openrao.commons.PhysicalParameter;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.cracapi.Crac;
import com.powsybl.openrao.data.cracapi.CracCreationContext;
import com.powsybl.openrao.data.cracapi.Instant;
import com.powsybl.openrao.data.cracapi.RemedialAction;
import com.powsybl.openrao.data.cracapi.State;
Expand All @@ -33,6 +34,7 @@
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
Expand Down Expand Up @@ -492,28 +494,61 @@ private static byte[] getBytesFromInputStream(InputStream inputStream) throws IO
return baos.toByteArray();
}

/**
* Write CRAC data into a file
*
* @param exporters candidate CRAC exporters
* @param format desired output CRAC data type
* @param cracCreationContext CRAC creation context that contains the original CRAC
* @param properties specific information needed for export
* @param outputStream file where to write the CRAC data
*/
private void write(List<Exporter> exporters, String format, CracCreationContext cracCreationContext, Properties properties, OutputStream outputStream) {
exporters.stream()
.filter(ex -> format.equals(ex.getFormat()))
.findAny()
.orElseThrow(() -> new OpenRaoException("Export format " + format + " not supported"))
.exportData(this, cracCreationContext, properties, outputStream);
}

/**
* Write CRAC data into a file
*
* @param format desired output CRAC data type
* @param cracCreationContext CRAC creation context that contains the original CRAC
* @param properties specific information needed for export
* @param outputStream file where to write the CRAC data
*/
default void write(String format, CracCreationContext cracCreationContext, Properties properties, OutputStream outputStream) {
write(new ServiceLoaderCache<>(Exporter.class).getServices(), format, cracCreationContext, properties, outputStream);
}

/**
* Write CRAC data into a file
*
* @param exporters candidate CRAC exporters
* @param format desired output CRAC data type
* @param crac CRAC data
* @param properties specific information needed for export
* @param outputStream file where to write the CRAC data
*/
private void write(List<Exporter> exporters, String format, Crac crac, Set<Unit> flowUnits, OutputStream outputStream) {
private void write(List<Exporter> exporters, String format, Crac crac, Properties properties, OutputStream outputStream) {
exporters.stream()
.filter(ex -> format.equals(ex.getFormat()))
.findAny()
.orElseThrow(() -> new OpenRaoException("Export format " + format + " not supported"))
.exportData(this, crac, flowUnits, outputStream);
.exportData(this, crac, properties, outputStream);
}

/**
* Write CRAC data into a file
*
* @param format desired output CRAC data type
* @param crac CRAC data
* @param properties specific information needed for export
* @param outputStream file where to write the CRAC data
*/
default void write(String format, Crac crac, Set<Unit> flowUnits, OutputStream outputStream) {
write(new ServiceLoaderCache<>(Exporter.class).getServices(), format, crac, flowUnits, outputStream);
default void write(String format, Crac crac, Properties properties, OutputStream outputStream) {
write(new ServiceLoaderCache<>(Exporter.class).getServices(), format, crac, properties, outputStream);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

package com.powsybl.openrao.data.raoresultapi.io;

import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.data.cracapi.Crac;
import com.powsybl.openrao.data.cracapi.CracCreationContext;
import com.powsybl.openrao.data.raoresultapi.RaoResult;

import java.io.OutputStream;
import java.util.Properties;
import java.util.Set;

/**
Expand All @@ -23,5 +25,25 @@ public interface Exporter {
*/
String getFormat();

void exportData(RaoResult raoResult, Crac crac, Set<Unit> flowUnits, OutputStream outputStream);
Set<String> getRequiredProperties();

Class<? extends CracCreationContext> getCracCreationContextClass();

default void validateDataToExport(CracCreationContext cracCreationContext, Properties properties) {
if (!getCracCreationContextClass().isInstance(cracCreationContext)) {
throw new OpenRaoException("%s exporter expects a %s.".formatted(getFormat(), getCracCreationContextClass().getSimpleName()));
}
if (!getRequiredProperties().isEmpty() && properties == null) {
throw new OpenRaoException("The export properties cannot be null for %s export.".formatted(getFormat()));
}
for (String requiredProperty : getRequiredProperties()) {
if (!properties.containsKey(requiredProperty)) {
throw new OpenRaoException("The mandatory %s property is missing for %s export.".formatted(requiredProperty, getFormat()));
}
}
}

void exportData(RaoResult raoResult, CracCreationContext cracCreationContext, Properties properties, OutputStream outputStream);

void exportData(RaoResult raoResult, Crac crac, Properties properties, OutputStream outputStream);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

package com.powsybl.openrao.data.raoresultapi;

import com.powsybl.openrao.data.cracapi.Crac;
import com.powsybl.openrao.data.cracapi.CracCreationContext;
import com.powsybl.openrao.data.cracapi.CracCreationReport;

import java.time.OffsetDateTime;

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
*/
public class MockCracCreationContext implements CracCreationContext {
@Override
public boolean isCreationSuccessful() {
return false;
}

@Override
public Crac getCrac() {
return null;
}

@Override
public OffsetDateTime getTimeStamp() {
return null;
}

@Override
public String getNetworkName() {
return null;
}

@Override
public CracCreationReport getCreationReport() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
package com.powsybl.openrao.data.raoresultapi;

import com.google.auto.service.AutoService;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.cracapi.Crac;
import com.powsybl.openrao.data.cracapi.CracCreationContext;
import com.powsybl.openrao.data.raoresultapi.io.Exporter;

import java.io.OutputStream;
import java.util.Properties;
import java.util.Set;

/**
Expand All @@ -26,7 +27,24 @@ public String getFormat() {
}

@Override
public void exportData(RaoResult raoResult, Crac crac, Set<Unit> flowUnits, OutputStream outputStream) {
public Set<String> getRequiredProperties() {
return Set.of("rao-result.export.mock.property-1", "rao-result.export.mock.property-2");
}

@Override
public Class<? extends CracCreationContext> getCracCreationContextClass() {
return MockCracCreationContext.class;
}

@Override
public void exportData(RaoResult raoResult, CracCreationContext cracCreationContext, Properties properties, OutputStream outputStream) {
if (raoResult instanceof MockRaoResult mockRaoResult) {
mockRaoResult.setExportSuccessful();
}
}

@Override
public void exportData(RaoResult raoResult, Crac crac, Properties properties, OutputStream outputStream) {
if (raoResult instanceof MockRaoResult mockRaoResult) {
mockRaoResult.setExportSuccessful();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
package com.powsybl.openrao.data.raoresultapi;

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.cracapi.CracCreationContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.Set;
import java.util.Properties;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
Expand All @@ -33,15 +34,32 @@ void setUp() {

@Test
void testExportWithUnknownExporter() {
Set<Unit> emptySet = Set.of();
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> raoResult.write("unknownFormat", null, emptySet, null));
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> raoResult.write("unknownFormat", (CracCreationContext) null, null, null));
assertEquals("Export format unknownFormat not supported", exception.getMessage());
assertFalse(raoResult.wasExportSuccessful());
}

@Test
void testExportCracWithValidExporter() {
raoResult.write("Mock", null, Set.of(), null);
raoResult.write("Mock", (CracCreationContext) null, new Properties(), null);
assertTrue(raoResult.wasExportSuccessful());
}

@Test
void testValidateExportData() {
OpenRaoException exception;
CracCreationContext cracCreationContext = Mockito.mock(CracCreationContext.class);
MockRaoResultExporter exporter = new MockRaoResultExporter();
// wrong CRAC creation context class
exception = assertThrows(OpenRaoException.class, () -> exporter.validateDataToExport(cracCreationContext, new Properties()));
assertEquals("Mock exporter expects a MockCracCreationContext.", exception.getMessage());
// null properties
exception = assertThrows(OpenRaoException.class, () -> exporter.validateDataToExport(new MockCracCreationContext(), null));
assertEquals("The export properties cannot be null for Mock export.", exception.getMessage());
// missing required properties
Properties properties = new Properties();
properties.setProperty("rao-result.export.mock.property-1", "true");
exception = assertThrows(OpenRaoException.class, () -> exporter.validateDataToExport(new MockCracCreationContext(), properties));
assertEquals("The mandatory rao-result.export.mock.property-2 property is missing for Mock export.", exception.getMessage());
}
}
11 changes: 5 additions & 6 deletions data/rao-result/rao-result-json/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,25 @@
<artifactId>open-rao-search-tree-rao</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>open-rao-crac-impl</artifactId>
<artifactId>open-rao-crac-io-json</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>open-rao-crac-impl</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>open-rao-crac-io-json</artifactId>
<artifactId>open-rao-crac-impl</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.cracapi.Crac;
import com.powsybl.openrao.data.cracapi.CracCreationContext;
import com.powsybl.openrao.data.cracio.json.JsonCracCreationContext;
import com.powsybl.openrao.data.raoresultapi.io.Exporter;
import com.powsybl.openrao.data.raoresultapi.RaoResult;
import com.powsybl.openrao.data.raoresultjson.serializers.RaoResultJsonSerializerModule;
Expand All @@ -22,27 +24,65 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
* Rao Result exporter in JSON format.
* <p/>
* Optional properties:
* <ul>
* <li>
* <i>flows-in-amperes</i>: boolean (default is "false").
* </li>
* <li>
* <i>flows-in-megawatts</i>: boolean (default is "false").
* </li>
* </ul>
*
* @author Baptiste Seguinot {@literal <baptiste.seguinot at rte-france.com>}
*/
@AutoService(Exporter.class)
public class RaoResultJsonExporter implements Exporter {
private static final String JSON_EXPORT_PROPERTIES_PREFIX = "rao-result.export.json.";
private static final String FLOWS_IN_AMPERES = "flows-in-amperes";
private static final String FLOWS_IN_MEGAWATTS = "flows-in-megawatts";

@Override
public String getFormat() {
return "JSON";
}

@Override
public void exportData(RaoResult raoResult, Crac crac, Set<Unit> flowUnits, OutputStream outputStream) {
if (flowUnits.isEmpty()) {
throw new OpenRaoException("At least one flow unit should be defined");
public Set<String> getRequiredProperties() {
return Set.of();
}

@Override
public Class<? extends CracCreationContext> getCracCreationContextClass() {
return JsonCracCreationContext.class;
}

@Override
public void exportData(RaoResult raoResult, CracCreationContext cracCreationContext, Properties properties, OutputStream outputStream) {
validateDataToExport(cracCreationContext, properties);
exportData(raoResult, cracCreationContext.getCrac(), properties, outputStream);
}

@Override
public void exportData(RaoResult raoResult, Crac crac, Properties properties, OutputStream outputStream) {
boolean flowsInAmperes = Boolean.parseBoolean(properties.getProperty(JSON_EXPORT_PROPERTIES_PREFIX + FLOWS_IN_AMPERES, "false"));
boolean flowsInMegawatts = Boolean.parseBoolean(properties.getProperty(JSON_EXPORT_PROPERTIES_PREFIX + FLOWS_IN_MEGAWATTS, "false"));
if (!flowsInAmperes && !flowsInMegawatts) {
throw new OpenRaoException("At least one flow unit should be used. Please provide %s and/or %s in the properties.".formatted(JSON_EXPORT_PROPERTIES_PREFIX + FLOWS_IN_AMPERES, JSON_EXPORT_PROPERTIES_PREFIX + FLOWS_IN_MEGAWATTS));
}
Set<Unit> flowUnits = new HashSet<>();
if (flowsInAmperes) {
flowUnits.add(Unit.AMPERE);
}
if (flowUnits.stream().anyMatch(unit -> !unit.equals(Unit.AMPERE) && !unit.equals(Unit.MEGAWATT))) {
// TODO : we can actually handle all units with PhysicalParameter.FLOW
// but we'll have to add export feature for %Imax
throw new OpenRaoException("Flow unit should be AMPERE and/or MEGAWATT");
if (flowsInMegawatts) {
flowUnits.add(Unit.MEGAWATT);
}
try {
ObjectMapper objectMapper = JsonUtil.createObjectMapper();
Expand Down
Loading

0 comments on commit 82aacb6

Please sign in to comment.