Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c36aa8a
Dynamic simulation - TapChangerBlocking model for automaton
thangqp May 5, 2023
c1f55fd
Add name, uMeasurements, transformers to AutomatonEntity and provide …
thangqp May 10, 2023
a4f216a
restore watchedElement as a common field for all families of automaton
thangqp May 11, 2023
ee5e874
remove unused import
thangqp May 11, 2023
f217f35
push down watchedElement to CurrentLimitAutomaton
thangqp May 11, 2023
b4ecb6c
ESlint
thangqp May 11, 2023
fdb03f8
correct staticId position in exported groovy
thangqp May 12, 2023
c189ce1
More unit test on MappingControllerTest
thangqp May 12, 2023
5c60eff
More unit test on ScriptControllerTest
thangqp May 12, 2023
36ec79a
Enhance getId implementation of AutomatonIdProviderImpl
thangqp May 12, 2023
5b82f2a
Persist all properties of automaton to table properties
thangqp May 15, 2023
d7bf00b
Merge from main
thangqp May 17, 2023
cfc826a
Correct SQL
thangqp May 17, 2023
7e27d32
Plugins mechanism implementation for DTO
thangqp May 17, 2023
6937e72
Eslint
thangqp May 17, 2023
c1582fd
Refactoring plugin mechanism
thangqp May 21, 2023
c62a98f
Eslint
thangqp May 21, 2023
38d76b5
Use annotation to implement pluggable types
thangqp May 22, 2023
4517000
rename package plugins to extensions
thangqp May 22, 2023
6d7d087
Use annotation to separate mapping dto <-> entity
thangqp May 30, 2023
db7e595
Code clean
thangqp May 30, 2023
6817569
eliminate java reflection
thangqp Jun 14, 2023
91f482f
merge from main
thangqp Jun 14, 2023
eb215ea
TapChangerBlocking to TapChangerBlockingAutomaton
thangqp Jun 16, 2023
b013fb1
adapt "uMeasurements" to "uMeasurement" currently in dynawaltz 1.14.0
thangqp Jun 16, 2023
2aab8ff
uMeasurements => uMeasurement
thangqp Jun 20, 2023
b5d5f9f
automaton dto is now completed independent to automaton entity
thangqp Jun 20, 2023
9e55fa1
make implementation of automaton more tolerant to the lack of data in…
thangqp Jun 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,4 @@ private MappingConstants() {
// Loads
public static final String LOAD_TYPE_PROPERTY = "loadType";

public static final String CURRENT_LIMIT_MODEL_CLASS = "CurrentLimitAutomaton";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.mapping.server.common.extensions;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;

import javax.annotation.PostConstruct;
import java.util.*;

/**
* @author Thang PHAM <quyet-thang.pham at rte-france.com>
*/
public abstract class AbstractSubtypesRegister<D, E> implements SubtypesRegister<D, E> {

private final ObjectMapper objectMapper;

protected AbstractSubtypesRegister(ObjectMapper objectMapper) {
super();
this.objectMapper = objectMapper;
}

@PostConstruct
protected void registerSubtypes() {

// collect subtypes
List<NamedType> subtypes = new ArrayList<>();
getSubtypes().forEach((k, v) -> subtypes.add(new NamedType(v, k)));

// Register subtypes with the ObjectMapper
objectMapper.getSubtypeResolver().registerSubtypes(subtypes.toArray(new NamedType[0]));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.mapping.server.common.extensions;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
* @author Thang PHAM <quyet-thang.pham at rte-france.com>
*/
public interface SubtypesRegister<D, E> {
Map<String, Class<?>> getSubtypes();

D fromEntity(E entity) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException;

E toEntity(D dto) throws IllegalAccessException;
}
28 changes: 24 additions & 4 deletions src/main/java/org/gridsuite/mapping/server/dto/InputMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.gridsuite.mapping.server.dto.automata.AbstractAutomaton;
import org.gridsuite.mapping.server.dto.automata.extensions.AutomatonSubtypesRegister;
import org.gridsuite.mapping.server.model.AutomatonEntity;
import org.gridsuite.mapping.server.model.MappingEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;

import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -21,6 +26,7 @@
@Data
@Schema(description = "Mapping")
@AllArgsConstructor
@NoArgsConstructor
public class InputMapping implements Mapping {
@Schema(description = "Name")
private String name;
Expand All @@ -34,19 +40,33 @@ public class InputMapping implements Mapping {
@Schema(description = "Mapping should control its parameters")
private boolean controlledParameters;

public MappingEntity convertMappingToEntity() {
public MappingEntity convertMappingToEntity(AutomatonSubtypesRegister automatonSubtypesRegister) {
MappingEntity convertedMapping = new MappingEntity();
convertedMapping.setName(name);
convertedMapping.setControlledParameters(controlledParameters);
convertedMapping.setRules(rules.stream().map(rule -> rule.convertRuleToEntity(convertedMapping)).collect(Collectors.toList()));
convertedMapping.setAutomata(automata.stream().map(automaton -> automaton.convertAutomatonToEntity(convertedMapping)).collect(Collectors.toList()));
convertedMapping.setAutomata(automata.stream().map(automaton -> {
try {
AutomatonEntity automatonEntity = automatonSubtypesRegister.toEntity(automaton);
automatonEntity.setMapping(convertedMapping);
return automatonEntity;
} catch (Exception e) {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, e.getMessage());
}
}).collect(Collectors.toList()));
return convertedMapping;
}

public InputMapping(MappingEntity mappingEntity) {
public InputMapping(MappingEntity mappingEntity, AutomatonSubtypesRegister automatonSubtypesRegister) {
name = mappingEntity.getName();
controlledParameters = mappingEntity.isControlledParameters();
rules = mappingEntity.getRules().stream().map(Rule::new).collect(Collectors.toList());
automata = mappingEntity.getAutomata().stream().map(AbstractAutomaton::instantiateFromEntity).collect(Collectors.toList());
automata = mappingEntity.getAutomata().stream().map(automaton -> {
try {
return automatonSubtypesRegister.fromEntity(automaton);
} catch (Exception e) {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, e.getMessage());
}
}).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,25 @@
*/
package org.gridsuite.mapping.server.dto.automata;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.gridsuite.mapping.server.model.AutomatonEntity;
import org.gridsuite.mapping.server.model.MappingEntity;
import lombok.NoArgsConstructor;

import org.gridsuite.mapping.server.utils.AutomatonFamily;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;

import java.util.ArrayList;
import java.util.List;

/**
* @author Mathieu Scalbert <mathieu.scalbert at rte-france.com>
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "family", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = CurrentLimitAutomaton.class, name = "CURRENT_LIMIT")})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "model", visible = true)
@JsonSubTypes({ })
@Data
@NoArgsConstructor
public abstract class AbstractAutomaton {
@Schema(description = "Automaton family")
@JsonProperty
Expand All @@ -37,19 +36,18 @@ public abstract class AbstractAutomaton {
@Schema(description = "Mapped Parameters Set Group ID")
private String setGroup;

@Schema(description = "Element watched by the automaton")
private String watchedElement;
@JsonIgnore
public abstract String getExportedId();

@JsonIgnore
public abstract String getExportedClassName();

@JsonIgnore
public abstract List<BasicProperty> getExportedProperties();

public abstract ArrayList<BasicProperty> convertToBasicProperties();
public abstract List<BasicProperty> toProperties();

public abstract AutomatonEntity convertAutomatonToEntity(MappingEntity parentMapping);
public abstract void fromProperties(List<BasicProperty> properties);

public static AbstractAutomaton instantiateFromEntity(AutomatonEntity automatonEntity) {
if (automatonEntity.getFamily() == AutomatonFamily.CURRENT_LIMIT) {
return new CurrentLimitAutomaton(automatonEntity);
} else {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import lombok.AllArgsConstructor;
import lombok.Data;
import org.gridsuite.mapping.server.utils.PropertyType;

@Data
@AllArgsConstructor
public class BasicProperty {
private String name;

private String value;

private PropertyType type;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright (c) 2023, 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 org.gridsuite.mapping.server.dto.automata;

import com.google.auto.service.AutoService;
import org.gridsuite.mapping.server.dto.automata.extensions.AutomatonSubtypes;
import org.gridsuite.mapping.server.dto.automata.extensions.AutomatonSubtypesExtension;

/**
* @author Thang PHAM <quyet-thang.pham at rte-france.com>
*/
@AutomatonSubtypes({
@AutomatonSubtypes.Type(value = CurrentLimitAutomaton.class, name = CurrentLimitAutomaton.MODEL_CLASS),
@AutomatonSubtypes.Type(value = TapChangerBlockingAutomaton.class, name = TapChangerBlockingAutomaton.MODEL_CLASS)
})
@AutoService(AutomatonSubtypesExtension.class)
public class CommonAutomatonSubtypesExtension implements AutomatonSubtypesExtension {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
*/
package org.gridsuite.mapping.server.dto.automata;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.gridsuite.mapping.server.model.AutomatonEntity;
import org.gridsuite.mapping.server.model.AutomatonPropertyEntity;
import org.gridsuite.mapping.server.model.MappingEntity;
import org.gridsuite.mapping.server.utils.PropertyType;

import java.util.ArrayList;
import java.util.Optional;
import java.util.UUID;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author Mathieu Scalbert <mathieu.scalbert at rte-france.com>
Expand All @@ -25,44 +25,54 @@
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class CurrentLimitAutomaton extends AbstractAutomaton {

public static final String MODEL_CLASS = "CurrentLimitAutomaton";

public static final String PROPERTY_WATCHED_ELEMENT = "watchedElement";
public static final String PROPERTY_SIDE = "side";
public static final String PROPERTY_STATIC_ID = "staticId";

@Schema(description = "Element watched by the automaton")
@JsonProperty(PROPERTY_WATCHED_ELEMENT)
private String watchedElement;

@Schema(description = "Side of the automaton")
@JsonProperty(PROPERTY_SIDE)
private String side;

public ArrayList<BasicProperty> convertToBasicProperties() {
ArrayList<BasicProperty> propertiesList = new ArrayList<>();
propertiesList.add(new BasicProperty("side", side));
return propertiesList;
@Override
public String getExportedId() {
return String.format("%s_%s", this.getModel(), watchedElement);
}

@Override
public String getExportedClassName() {
return MODEL_CLASS;
}

@Override
public ArrayList<BasicProperty> getExportedProperties() {
ArrayList<BasicProperty> properties = new ArrayList<>();
properties.add(new BasicProperty(PROPERTY_STATIC_ID, "\"" + watchedElement + "\"", PropertyType.STRING));
properties.add(new BasicProperty(PROPERTY_SIDE, side, PropertyType.STRING));

return properties;
}

public CurrentLimitAutomaton(AutomatonEntity automatonEntity) {
this.setFamily(automatonEntity.getFamily());
this.setModel(automatonEntity.getModel());
this.setSetGroup(automatonEntity.getSetGroup());
this.setWatchedElement(automatonEntity.getWatchedElement());
// TODO Create generic function for all properties
Optional<AutomatonPropertyEntity> foundSideProperty = automatonEntity.getProperties().stream().filter(property -> property.getName().equals("side")).findAny();
if (foundSideProperty.isPresent()) {
side = foundSideProperty.get().getValue();
}
@Override
public List<BasicProperty> toProperties() {
ArrayList<BasicProperty> properties = new ArrayList<>();
properties.add(new BasicProperty(PROPERTY_WATCHED_ELEMENT, watchedElement, PropertyType.STRING));
properties.add(new BasicProperty(PROPERTY_SIDE, side, PropertyType.STRING));
return properties;
}

public AutomatonEntity convertAutomatonToEntity(MappingEntity parentMapping) {
UUID createdId = UUID.randomUUID();
AutomatonEntity convertedAutomaton = new AutomatonEntity();
convertedAutomaton.setAutomatonId(createdId);
convertedAutomaton.setFamily(this.getFamily());
convertedAutomaton.setModel(this.getModel());
convertedAutomaton.setSetGroup(this.getSetGroup());
convertedAutomaton.setWatchedElement(this.getWatchedElement());
convertedAutomaton.setMapping(parentMapping);
ArrayList<AutomatonPropertyEntity> convertedProperties = new ArrayList<>();
AutomatonPropertyEntity convertedProperty = new AutomatonPropertyEntity();
convertedProperty.setAutomatonId(createdId);
convertedProperty.setName("side");
convertedProperty.setValue(this.getSide());
convertedProperty.setType(PropertyType.STRING);
convertedProperties.add(convertedProperty);
convertedAutomaton.setProperties(convertedProperties);
return convertedAutomaton;
@Override
public void fromProperties(List<BasicProperty> properties) {
Map<String, BasicProperty> propertiesMap = properties.stream()
.collect(Collectors.toMap(BasicProperty::getName, elem -> elem));
this.watchedElement = propertiesMap.get(PROPERTY_WATCHED_ELEMENT) != null ? propertiesMap.get(PROPERTY_WATCHED_ELEMENT).getValue() : null;
this.side = propertiesMap.get(PROPERTY_SIDE) != null ? propertiesMap.get(PROPERTY_SIDE).getValue() : null;
}
}

Expand Down
Loading