Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Simulation - Database - Rework on model's parameter definitions #65

Merged
merged 22 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
edcc34a
Dynamic Simulation - Rework on model's parameters database
thangqp Jun 5, 2023
79e65a9
Remove all related rework on model's parameters
thangqp Jun 5, 2023
f6b46d3
Correct test data
thangqp Jun 5, 2023
2f97670
Grain test coverage
thangqp Jun 6, 2023
d400ed1
Grain test coverage
thangqp Jun 6, 2023
5a629b9
Grain test coverage
thangqp Jun 6, 2023
05644ef
Grain test coverage
thangqp Jun 6, 2023
3ba4b7f
re-factorisation script SQL for parameter definitions
thangqp Jun 6, 2023
00da132
Merge branch 'main' into dynamic_simulation_rework_on_model_parameter…
thangqp Jun 6, 2023
f75ecb9
Revert many-to-many relationship in order to make Hibernate persist p…
thangqp Jun 8, 2023
f7f1e65
ESlint
thangqp Jun 8, 2023
c2f15fd
Correct clean DB order
thangqp Jun 8, 2023
d4611dc
Truncate related tabled to rerun script SQL IEEE14
thangqp Jun 9, 2023
60f44cc
Replace truncate by delete to avoid foreign key check problem
thangqp Jun 9, 2023
d77ad06
Remove cleanup associations when delete a variable set due to the cha…
thangqp Jun 14, 2023
9fb1492
rectify model service
thangqp Jun 14, 2023
16be766
Merge branch 'main' into dynamic_simulation_rework_on_model_parameter…
thangqp Jun 15, 2023
d762c45
Merge branch 'main' into dynamic_simulation_rework_on_model_parameter…
thangqp Jun 22, 2023
717aae5
Add a required delete a table in liquibase
thangqp Jun 22, 2023
acc557d
Remove DELETE data in liquibase
thangqp Jul 6, 2023
e71b485
Revert "Remove DELETE data in liquibase"
thangqp Jul 6, 2023
468cd8f
Add re-entrant condition in liquibase
thangqp Jul 6, 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
@@ -0,0 +1,14 @@
package org.gridsuite.mapping.server;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.client.HttpClientErrorException;

@ControllerAdvice
public class RestResponseEntityExceptionHandler {
@ExceptionHandler(HttpClientErrorException.class)
protected ResponseEntity<Object> handleHttpClientErrorException(HttpClientErrorException exception) {
return ResponseEntity.status(exception.getStatusCode()).body(exception.getStatusText());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,6 @@ public ResponseEntity<ParametersSetsGroup> saveSimpleParametersSet(@PathVariable
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.saveParametersSetsGroup(modelName, setsGroup, false));
}

@GetMapping(value = "/{modelName}/parameters/definitions/")
@Operation(summary = "get parameters definitions for a given model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "parameters definitions of the model")})
public ResponseEntity<List<ModelParameterDefinition>> getParametersDefinitionsFromModelName(@PathVariable("modelName") String modelName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getParametersDefinitionsFromModelName(modelName));
}

@GetMapping(value = "/")
@Operation(summary = "get models names")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "names of all models")})
public ResponseEntity<List<SimpleModel>> getModels() {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getModels());
}

@PostMapping(value = "/")
@Operation(summary = "Post a model")
@ApiResponses(value = {
Expand All @@ -92,7 +76,81 @@ public ResponseEntity<ParametersSetsGroup> deleteSet(@PathVariable("modelName")
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.deleteSet(modelName, groupName, groupType, setName));
}

@GetMapping(value = "/")
@Operation(summary = "get models names")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "names of all models")})
public ResponseEntity<List<SimpleModel>> getModels() {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getModels());
}

// --- BEGIN parameter definition-related endpoints --- //
@GetMapping(value = "/{modelName}/parameters/definitions")
@Operation(summary = "get parameters definitions for a given model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "parameter definitions of the model")})
public ResponseEntity<List<ModelParameterDefinition>> getParameterDefinitionsFromModel(@PathVariable("modelName") String modelName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getParameterDefinitionsFromModel(modelName));
}

@PostMapping(value = "/{modelName}/parameters/definitions")
@Operation(summary = "Add new parameter definitions to model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "saved model")})
public ResponseEntity<Model> addNewParameterDefinitionsToModel(@PathVariable("modelName") String modelName, @RequestBody List<ModelParameterDefinition> parameterDefinitions) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.addNewParameterDefinitionsToModel(modelName, parameterDefinitions));
}

@PatchMapping(value = "/{modelName}/parameters/definitions/add")
@Operation(summary = "Add existing parameter definitions to model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "saved model")})
public ResponseEntity<Model> addExistingParameterDefinitionsToModel(@PathVariable("modelName") String modelName, @RequestBody List<String> parameterDefinitionNames) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.addExistingParameterDefinitionsToModel(modelName, parameterDefinitionNames));
}

@PatchMapping(value = "/{modelName}/parameters/definitions/remove")
@Operation(summary = "Remove existing parameter definitions from model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "saved model")})
public ResponseEntity<Model> removeExistingParameterDefinitionsFromModel(@PathVariable("modelName") String modelName, @RequestBody List<String> parameterDefinitionNames) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.removeExistingParameterDefinitionsFromModel(modelName, parameterDefinitionNames));
}

@PatchMapping(value = "/{modelName}/parameters/definitions/remove-all")
@Operation(summary = "Reset empty parameter definitions on model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "saved model")})
public ResponseEntity<Model> removeAllParameterDefinitionsFromModel(@PathVariable("modelName") String modelName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.removeAllParameterDefinitionsOnModel(modelName));
}

@PostMapping(value = "/parameters/definitions")
@Operation(summary = "Save new parameter definitions")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Saved parameter definitions")})
public ResponseEntity<List<ModelParameterDefinition>> saveNewParameterDefinitions(@RequestBody List<ModelParameterDefinition> parameterDefinitions) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.saveNewParameterDefinitions(parameterDefinitions));
}

@DeleteMapping(value = "/parameters/definitions")
@Operation(summary = "Delete parameter definitions")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Deleted parameter definitions")})
public ResponseEntity<List<String>> deleteParameterDefinitions(@RequestBody List<String> parameterDefinitionNames) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.deleteParameterDefinitions(parameterDefinitionNames));
}
// --- END parameter definition-related endpoints --- //

// --- BEGIN variable-related endpoints --- //
@GetMapping(value = "/{modelName}/variables")
@Operation(summary = "get variable definitions for a given model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "variable definitions of the model")})
public ResponseEntity<List<ModelVariableDefinition>> getVariablesFromModel(@PathVariable("modelName") String modelName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getVariableDefinitionsFromModel(modelName));
}

@PostMapping(value = "/{modelName}/variables")
@Operation(summary = "Add new variable definitions to model")
@ApiResponses(value = {
Expand All @@ -113,18 +171,26 @@ public ResponseEntity<Model> addExistingVariablesToModel(@PathVariable("modelNam
@Operation(summary = "Remove existing variable definitions from model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "saved model")})
public ResponseEntity<Model> removeExistingVariablesToModel(@PathVariable("modelName") String modelName, @RequestBody List<String> variableDefinitionNames) {
public ResponseEntity<Model> removeExistingVariablesFromModel(@PathVariable("modelName") String modelName, @RequestBody List<String> variableDefinitionNames) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.removeExistingVariableDefinitionsFromModel(modelName, variableDefinitionNames));
}

@PatchMapping(value = "/{modelName}/variables/remove-all")
@Operation(summary = "Reset empty variable definitions on model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "saved model")})
public ResponseEntity<Model> removeAllVariablesToModel(@PathVariable("modelName") String modelName) {
public ResponseEntity<Model> removeAllVariablesOnModel(@PathVariable("modelName") String modelName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.removeAllVariableDefinitionsOnModel(modelName));
}

@GetMapping(value = "/variables-sets/{variableSetName}/variables")
@Operation(summary = "Add variable definitions from variables set")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "variable definitions of variables set")})
public ResponseEntity<List<ModelVariableDefinition>> getVariablesFromVariablesSet(@PathVariable("variableSetName") String variableSetName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getVariableDefinitionsFromVariablesSet(variableSetName));
}

@PostMapping(value = "/variables-sets/{variableSetName}/variables")
@Operation(summary = "Add new variable definitions to variables set")
@ApiResponses(value = {
Expand All @@ -149,6 +215,14 @@ public ResponseEntity<VariablesSet> removeAllVariableDefinitionOnVariablesSet(@P
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.removeAllVariableDefinitionOnVariablesSet(variableSetName));
}

@GetMapping(value = "/{modelName}/variables-sets")
@Operation(summary = "get variable sets for a given model")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "variable sets of the model")})
public ResponseEntity<List<VariablesSet>> getVariablesSetsFromModel(@PathVariable("modelName") String modelName) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(modelService.getVariablesSetsFromModel(modelName));
}

@PostMapping(value = "/{modelName}/variables-sets")
@Operation(summary = "Add new variables set to model")
@ApiResponses(value = {
Expand Down
61 changes: 47 additions & 14 deletions src/main/java/org/gridsuite/mapping/server/model/ModelEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,59 +9,92 @@
import lombok.*;
import org.gridsuite.mapping.server.dto.models.Model;
import org.gridsuite.mapping.server.utils.EquipmentType;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import static javax.persistence.TemporalType.TIMESTAMP;

/**
* @author Mathieu Scalbert <mathieu.scalbert at rte-france.com>
*/
@Getter
@Setter
@Table(name = "models")
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ModelEntity extends AbstractManuallyAssignedIdentifierEntity<String> implements Serializable {
@Getter
@Setter
@Entity
@Table(name = "models")
public class ModelEntity implements Serializable {

// Could be replaced with UUID, but we lose the ease of use of names
@Id
@EqualsAndHashCode.Include
@Column(name = "model_name")
private String modelName;

@Column(name = "equipment_type")
private EquipmentType equipmentType;

@OneToMany(targetEntity = ModelParameterDefinitionEntity.class, mappedBy = "model", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ModelParameterDefinitionEntity> parameterDefinitions = new ArrayList<>(0);
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
@JoinTable(
name = "models_model_parameter_definitions",
joinColumns = {@JoinColumn(name = "model_name")},
inverseJoinColumns = {@JoinColumn(name = "parameter_definition_name", referencedColumnName = "name")}
)
private Set<ModelParameterDefinitionEntity> parameterDefinitions = new LinkedHashSet<>(0);

@OneToMany(targetEntity = ModelSetsGroupEntity.class, mappedBy = "model", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ModelSetsGroupEntity> setsGroups = new ArrayList<>(0);

@ManyToMany(targetEntity = ModelVariableDefinitionEntity.class, mappedBy = "models", cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
// must exclude CascadeType.REMOVE to avoid unexpected cascade on delete a ModelVariableDefinitionEntity
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
@JoinTable(
name = "models_model_variable_definitions",
joinColumns = {@JoinColumn(name = "model_name")},
inverseJoinColumns = {@JoinColumn(name = "variable_definition_name")}
)
private Set<ModelVariableDefinitionEntity> variableDefinitions = new LinkedHashSet<>(0);

@ManyToMany(targetEntity = ModelVariableSetEntity.class, mappedBy = "models", cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
private Set<ModelVariableSetEntity> variableSets = new LinkedHashSet<>(0);

@Override
public String getId() {
return modelName;
}

public ModelEntity(Model modelToConvert) {
modelName = modelToConvert.getModelName();
equipmentType = modelToConvert.getEquipmentType();
parameterDefinitions = modelToConvert.getParameterDefinitions() != null ? modelToConvert.getParameterDefinitions().stream().map(parameterDefinition -> new ModelParameterDefinitionEntity(parameterDefinition.getName(), modelToConvert.getModelName(), parameterDefinition.getType(), parameterDefinition.getOrigin(), parameterDefinition.getOriginName(), parameterDefinition.getFixedValue(), this)).collect(Collectors.toList()) : null;
parameterDefinitions = modelToConvert.getParameterDefinitions() != null ? modelToConvert.getParameterDefinitions().stream().map(parameterDefinition -> new ModelParameterDefinitionEntity(this, parameterDefinition)).collect(Collectors.toSet()) : null;
setsGroups = modelToConvert.getSetsGroups() != null ? modelToConvert.getSetsGroups().stream().map(group -> new ModelSetsGroupEntity(this, group)).collect(Collectors.toList()) : null;
variableDefinitions = modelToConvert.getVariableDefinitions() != null ? modelToConvert.getVariableDefinitions().stream().map(variableDefinition -> new ModelVariableDefinitionEntity(this, null, variableDefinition)).collect(Collectors.toCollection(LinkedHashSet::new)) : null;
variableSets = modelToConvert.getVariablesSets() != null ? modelToConvert.getVariablesSets().stream().map(variablesSet -> new ModelVariableSetEntity(this, variablesSet)).collect(Collectors.toCollection(LinkedHashSet::new)) : null;
}

@CreatedDate
@Temporal(TIMESTAMP)
@Column(name = "created_date", updatable = false)
private Date createdDate;

@LastModifiedDate
@Temporal(TIMESTAMP)
@Column(name = "updated_date")
private Date updatedDate;

// --- utils methods --- //

public void addParameterDefinitions(Collection<ModelParameterDefinitionEntity> parameterDefinitions) {
parameterDefinitions.forEach(parameterDefinition -> parameterDefinition.getModels().add(this));
this.parameterDefinitions.addAll(parameterDefinitions);
}

public void removeParameterDefinitions(Collection<ModelParameterDefinitionEntity> parameterDefinitions) {
parameterDefinitions.forEach(parameterDefinition -> parameterDefinition.getModels().remove(this));
this.parameterDefinitions.removeAll(parameterDefinitions);
}

public void addVariableDefinitions(Collection<ModelVariableDefinitionEntity> variableDefinitions) {
variableDefinitions.forEach(variableDefinition -> variableDefinition.getModels().add(this));
this.variableDefinitions.addAll(variableDefinitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,39 @@
*/
package org.gridsuite.mapping.server.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;
import org.gridsuite.mapping.server.dto.models.ModelParameterDefinition;
import org.gridsuite.mapping.server.utils.ParameterOrigin;
import org.gridsuite.mapping.server.utils.ParameterType;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import static javax.persistence.TemporalType.TIMESTAMP;

/**
* @author Mathieu Scalbert <mathieu.scalbert at rte-france.com>
*/
@Inheritance
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "model_parameter_definitions", indexes = {@Index(name = "model_parameter_definitions_model_name_index", columnList = "model_name")})
@IdClass(ModelParameterDefinitionId.class)
@Table(name = "model_parameter_definitions")
public class ModelParameterDefinitionEntity implements Serializable {

@Id
@EqualsAndHashCode.Include
@Column(name = "name")
private String name;

@Id
@Column(name = "model_name")
private String modelName;

@Column(name = "type")
@Enumerated
private ParameterType type;
Expand All @@ -51,8 +53,24 @@ public class ModelParameterDefinitionEntity implements Serializable {
@Column(name = "fixed_value")
private String fixedValue;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "model_name", foreignKey = @ForeignKey(name = "model_parameter_definition_fk"))
@MapsId("modelName")
private ModelEntity model;
@ManyToMany(
mappedBy = "parameterDefinitions",
cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}
)
private Set<ModelEntity> models;

public ModelParameterDefinitionEntity(ModelEntity model, ModelParameterDefinition parameterDefinition) {
this(parameterDefinition.getName(), parameterDefinition.getType(), parameterDefinition.getOrigin(), parameterDefinition.getOriginName(), parameterDefinition.getFixedValue(),
model != null ? new LinkedHashSet<>(List.of(model)) : new LinkedHashSet<>(), null, null);
}

@CreatedDate
@Temporal(TIMESTAMP)
@Column(name = "created_date", updatable = false)
private Date createdDate;

@LastModifiedDate
@Temporal(TIMESTAMP)
@Column(name = "updated_date")
private Date updatedDate;
}
Loading