JsonActionAndOperatorStrategyTest.java
/**
* Copyright (c) 2022, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.security.json;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.powsybl.action.json.ActionJsonModule;
import com.powsybl.commons.test.AbstractSerDeTest;
import com.powsybl.commons.test.ComparisonUtils;
import com.powsybl.contingency.ContingencyContext;
import com.powsybl.action.*;
import com.powsybl.security.condition.AllViolationCondition;
import com.powsybl.security.condition.AnyViolationCondition;
import com.powsybl.security.condition.TrueCondition;
import com.powsybl.security.strategy.OperatorStrategy;
import com.powsybl.security.strategy.OperatorStrategyList;
import com.powsybl.security.strategy.ConditionalActions;
import org.junit.jupiter.api.Test;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static com.powsybl.security.LimitViolationType.*;
/**
* @author Etienne Lesot {@literal <etienne.lesot@rte-france.com>}
*/
class JsonActionAndOperatorStrategyTest extends AbstractSerDeTest {
@Test
void operatorStrategyReadV10() throws IOException {
OperatorStrategyList operatorStrategies = OperatorStrategyList.read(getClass().getResourceAsStream("/OperatorStrategyFileTestV1.0.json"));
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
operatorStrategies.write(bos);
ComparisonUtils.assertTxtEquals(getClass().getResourceAsStream("/OperatorStrategyFileTest.json"), new ByteArrayInputStream(bos.toByteArray()));
}
}
@Test
void operatorStrategyRoundTrip() throws IOException {
List<OperatorStrategy> operatorStrategies = new ArrayList<>();
operatorStrategies.add(new OperatorStrategy("id1", ContingencyContext.specificContingency("contingencyId1"),
List.of(new ConditionalActions("stage1", new TrueCondition(), List.of("actionId1", "actionId2", "actionId3")))));
operatorStrategies.add(new OperatorStrategy("id2", ContingencyContext.specificContingency("contingencyId2"),
List.of(new ConditionalActions("stage1", new AnyViolationCondition(), List.of("actionId4")))));
operatorStrategies.add(new OperatorStrategy("id3", ContingencyContext.specificContingency("contingencyId1"),
List.of(new ConditionalActions("stage1", new AnyViolationCondition(Collections.singleton(CURRENT)),
List.of("actionId1", "actionId3")))));
operatorStrategies.add(new OperatorStrategy("id4", ContingencyContext.specificContingency("contingencyId3"),
List.of(new ConditionalActions("stage1", new AnyViolationCondition(Collections.singleton(LOW_VOLTAGE)),
List.of("actionId1", "actionId2", "actionId4")))));
operatorStrategies.add(new OperatorStrategy("id5", ContingencyContext.specificContingency("contingencyId4"),
List.of(new ConditionalActions("stage1", new AllViolationCondition(List.of("violation1", "violation2"),
Collections.singleton(HIGH_VOLTAGE)),
List.of("actionId1", "actionId5")))));
operatorStrategies.add(new OperatorStrategy("id6", ContingencyContext.specificContingency("contingencyId5"),
List.of(new ConditionalActions("stage1", new AllViolationCondition(List.of("violation1", "violation2")),
List.of("actionId3")))));
OperatorStrategyList operatorStrategyList = new OperatorStrategyList(operatorStrategies);
roundTripTest(operatorStrategyList, OperatorStrategyList::write, OperatorStrategyList::read, "/OperatorStrategyFileTest.json");
}
@JsonTypeName(DummyAction.NAME)
static class DummyAction extends AbstractAction {
static final String NAME = "dummy-action";
@JsonCreator
protected DummyAction(@JsonProperty("id") String id) {
super(id);
}
@JsonProperty(value = "type", access = JsonProperty.Access.READ_ONLY)
@Override
public String getType() {
return NAME;
}
}
@JsonTypeName(DummyAction.NAME)
static class DummyActionBuilder implements ActionBuilder<DummyActionBuilder> {
String id;
@Override
@JsonProperty(value = "type", access = JsonProperty.Access.READ_ONLY)
public String getType() {
return DummyAction.NAME;
}
@Override
public DummyActionBuilder withId(String id) {
this.id = id;
return this;
}
@Override
public String getId() {
return this.id;
}
@Override
public DummyActionBuilder withNetworkElementId(String elementId) {
return null;
}
@Override
public Action build() {
return new DummyAction(id);
}
}
@Test
void testJsonPlugins() throws JsonProcessingException {
Module jsonModule = new SimpleModule()
.registerSubtypes(DummyAction.class, DummyActionBuilder.class);
SecurityAnalysisJsonPlugin plugin = () -> List.of(jsonModule);
ObjectMapper mapper = new ObjectMapper()
.registerModule(new SecurityAnalysisJsonModule(List.of(plugin)))
.registerModule(new ActionJsonModule());
DummyAction action = new DummyAction("hello");
ActionList actions = new ActionList(List.of(action));
String serialized = mapper.writeValueAsString(actions);
ActionList parsed = mapper.readValue(serialized, ActionList.class);
assertEquals(1, parsed.getActions().size());
Action parsedAction = parsed.getActions().get(0);
assertInstanceOf(DummyAction.class, parsedAction);
assertEquals("hello", parsedAction.getId());
}
}