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

Remove webflux #85

Merged
merged 17 commits into from
Oct 20, 2023
8 changes: 2 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,6 @@
<groupId>com.powsybl</groupId>
<artifactId>powsybl-ws-commons</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
Expand All @@ -152,11 +148,11 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>

<!-- Runtime dependencies -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package org.gridsuite.securityanalysis.server;

/**
* Copyright (c) 2020, RTE (http://www.rte-france.com)
* 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.securityanalysis.server;

import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -15,27 +16,37 @@
import com.powsybl.security.json.SecurityAnalysisJsonModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
@Configuration
public class WebFluxConfig implements WebFluxConfigurer {
public class RestTemplateConfig {

@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();

//find and replace Jackson message converter with our own
for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) {
final HttpMessageConverter<?> httpMessageConverter = restTemplate.getMessageConverters().get(i);
if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) {
restTemplate.getMessageConverters().set(i, mappingJackson2HttpMessageConverter());
}
}

return restTemplate;
}

@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
var objectMapper = objectMapper();
configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper));
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper));
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper());
return converter;
}

public static ObjectMapper createObjectMapper() {
var objectMapper = Jackson2ObjectMapperBuilder.json().build();
private ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
objectMapper.registerModule(new ContingencyJsonModule());
objectMapper.registerModule(new SecurityAnalysisJsonModule());
objectMapper.registerModule(new LoadFlowParametersJsonModule());
Expand All @@ -48,4 +59,6 @@ public static ObjectMapper createObjectMapper() {
public ObjectMapper objectMapper() {
return createObjectMapper();
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.reactive.config.EnableWebFlux;

/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
*/
@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
@SpringBootApplication
@EnableWebFlux
@ComponentScan(basePackageClasses = {SecurityAnalysisApplication.class, NetworkStoreService.class})
public class SecurityAnalysisApplication {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.gridsuite.securityanalysis.server.dto.SubjectLimitViolationToContingencyDTO;
import org.gridsuite.securityanalysis.server.dto.ContingencyToSubjectLimitViolationDTO;
import org.gridsuite.securityanalysis.server.dto.SubjectLimitViolationResultDTO;
import org.gridsuite.securityanalysis.server.dto.ContingencyResultDTO;
import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisParametersInfos;
import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisStatus;
import org.gridsuite.securityanalysis.server.service.SecurityAnalysisRunContext;
Expand All @@ -25,7 +25,6 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -61,7 +60,7 @@ private static List<UUID> getNonNullOtherNetworkUuids(List<UUID> otherNetworkUui
description = "The security analysis has been performed",
content = {@Content(mediaType = APPLICATION_JSON_VALUE,
schema = @Schema(implementation = SecurityAnalysisResult.class))})})
public ResponseEntity<Mono<SecurityAnalysisResult>> run(@Parameter(description = "Network UUID") @PathVariable("networkUuid") UUID networkUuid,
public ResponseEntity<SecurityAnalysisResult> run(@Parameter(description = "Network UUID") @PathVariable("networkUuid") UUID networkUuid,
@Parameter(description = "Variant Id") @RequestParam(name = "variantId", required = false) String variantId,
@Parameter(description = "Other networks UUID (to merge with main one))") @RequestParam(name = "networkUuid", required = false) List<UUID> otherNetworkUuids,
@Parameter(description = "Contingency list name") @RequestParam(name = "contingencyListName", required = false) List<String> contigencyListNames,
Expand All @@ -71,7 +70,7 @@ public ResponseEntity<Mono<SecurityAnalysisResult>> run(@Parameter(description =
@RequestBody(required = false) SecurityAnalysisParametersInfos parameters) {
String providerToUse = provider != null ? provider : service.getDefaultProvider();
List<UUID> nonNullOtherNetworkUuids = getNonNullOtherNetworkUuids(otherNetworkUuids);
Mono<SecurityAnalysisResult> result = workerService.run(new SecurityAnalysisRunContext(networkUuid, variantId, nonNullOtherNetworkUuids, contigencyListNames, null, providerToUse, parameters, reportUuid, reporterId));
SecurityAnalysisResult result = workerService.run(new SecurityAnalysisRunContext(networkUuid, variantId, nonNullOtherNetworkUuids, contigencyListNames, null, providerToUse, parameters, reportUuid, reporterId));
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result);
}

Expand All @@ -81,7 +80,7 @@ public ResponseEntity<Mono<SecurityAnalysisResult>> run(@Parameter(description =
description = "The security analysis has been performed and results have been saved to database",
content = {@Content(mediaType = APPLICATION_JSON_VALUE,
schema = @Schema(implementation = SecurityAnalysisResult.class))})})
public ResponseEntity<Mono<UUID>> runAndSave(@Parameter(description = "Network UUID") @PathVariable("networkUuid") UUID networkUuid,
public ResponseEntity<UUID> runAndSave(@Parameter(description = "Network UUID") @PathVariable("networkUuid") UUID networkUuid,
@Parameter(description = "Variant Id") @RequestParam(name = "variantId", required = false) String variantId,
@Parameter(description = "Other networks UUID (to merge with main one))") @RequestParam(name = "networkUuid", required = false) List<UUID> otherNetworkUuids,
@Parameter(description = "Contingency list name") @RequestParam(name = "contingencyListName", required = false) List<String> contigencyListNames,
Expand All @@ -92,81 +91,85 @@ public ResponseEntity<Mono<UUID>> runAndSave(@Parameter(description = "Network U
@RequestBody(required = false) SecurityAnalysisParametersInfos parameters) {
String providerToUse = provider != null ? provider : service.getDefaultProvider();
List<UUID> nonNullOtherNetworkUuids = getNonNullOtherNetworkUuids(otherNetworkUuids);
Mono<UUID> resultUuid = service.runAndSaveResult(new SecurityAnalysisRunContext(networkUuid, variantId, nonNullOtherNetworkUuids, contigencyListNames, receiver, providerToUse, parameters, reportUuid, reporterId));
UUID resultUuid = service.runAndSaveResult(new SecurityAnalysisRunContext(networkUuid, variantId, nonNullOtherNetworkUuids, contigencyListNames, receiver, providerToUse, parameters, reportUuid, reporterId));
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(resultUuid);
}

@GetMapping(value = "/results/{resultUuid}/n-result", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get a security analysis result from the database - N result")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"),
@ApiResponse(responseCode = "404", description = "Security analysis result has not been found")})
public Mono<ResponseEntity<PreContingencyResult>> getNResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
public ResponseEntity<PreContingencyResult> getNResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
PreContingencyResult result = service.getNResult(resultUuid);

Mono<PreContingencyResult> result = service.getNResult(resultUuid);
return result.map(r -> ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(r))
.defaultIfEmpty(ResponseEntity.notFound().build());
return result != null
? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result)
: ResponseEntity.notFound().build();
}

@GetMapping(value = "/results/{resultUuid}/nmk-contingencies-result", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get a security analysis result from the database - NMK contingencies result")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"),
@ApiResponse(responseCode = "404", description = "Security analysis result has not been found")})
public Mono<ResponseEntity<List<ContingencyToSubjectLimitViolationDTO>>> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
public ResponseEntity<List<ContingencyResultDTO>> getNmKContingenciesResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
List<ContingencyResultDTO> result = service.getNmKContingenciesResult(resultUuid);

Mono<List<ContingencyToSubjectLimitViolationDTO>> result = service.getNmKContingenciesResult(resultUuid);
return result.map(r -> ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(r))
.defaultIfEmpty(ResponseEntity.notFound().build());
return result != null
? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result)
: ResponseEntity.notFound().build();
}

@GetMapping(value = "/results/{resultUuid}/nmk-constraints-result", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get a security analysis result from the database - NMK contingencies result")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result"),
@ApiResponse(responseCode = "404", description = "Security analysis result has not been found")})
public Mono<ResponseEntity<List<SubjectLimitViolationToContingencyDTO>>> getNmKConstraintsResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
public ResponseEntity<List<SubjectLimitViolationResultDTO>> getNmKConstraintsResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {

Mono<List<SubjectLimitViolationToContingencyDTO>> result = service.getNmKConstraintsResult(resultUuid);
return result.map(r -> ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(r))
.defaultIfEmpty(ResponseEntity.notFound().build());
List<SubjectLimitViolationResultDTO> result = service.getNmKConstraintsResult(resultUuid);
return result != null
? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result)
: ResponseEntity.notFound().build();
}

@DeleteMapping(value = "/results/{resultUuid}", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Delete a security analysis result from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis result has been deleted")})
public ResponseEntity<Mono<Void>> deleteResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
Mono<Void> result = service.deleteResult(resultUuid);
return ResponseEntity.ok().body(result);
public ResponseEntity<Void> deleteResult(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
service.deleteResult(resultUuid);
return ResponseEntity.ok().build();
}

@DeleteMapping(value = "/results", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Delete all security analysis results from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "All security analysis results have been deleted")})
public ResponseEntity<Mono<Void>> deleteResults() {
Mono<Void> result = service.deleteResults();
return ResponseEntity.ok().body(result);
public ResponseEntity<Void> deleteResults() {
service.deleteResults();
return ResponseEntity.ok().build();
}

@GetMapping(value = "/results/{resultUuid}/status", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get the security analysis status from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis status")})
public ResponseEntity<Mono<SecurityAnalysisStatus>> getStatus(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
Mono<SecurityAnalysisStatus> result = service.getStatus(resultUuid);
public ResponseEntity<SecurityAnalysisStatus> getStatus(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
SecurityAnalysisStatus result = service.getStatus(resultUuid);
return ResponseEntity.ok().body(result);
}

@PutMapping(value = "/results/invalidate-status", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Invalidate the security analysis status from the database")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis status has been invalidated")})
public ResponseEntity<Mono<Void>> invalidateStatus(@Parameter(description = "Result uuids") @RequestParam(name = "resultUuid") List<UUID> resultUuids) {
return ResponseEntity.ok().body(service.setStatus(resultUuids, SecurityAnalysisStatus.NOT_DONE));
public ResponseEntity<Void> invalidateStatus(@Parameter(description = "Result uuids") @RequestParam(name = "resultUuid") List<UUID> resultUuids) {
service.setStatus(resultUuids, SecurityAnalysisStatus.NOT_DONE);
return ResponseEntity.ok().build();
}

@PutMapping(value = "/results/{resultUuid}/stop", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Stop a security analysis computation")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The security analysis has been stopped")})
public ResponseEntity<Mono<Void>> stop(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid,
public ResponseEntity<Void> stop(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid,
@Parameter(description = "Result receiver") @RequestParam(name = "receiver", required = false) String receiver) {
Mono<Void> result = service.stop(resultUuid, receiver);
return ResponseEntity.ok().body(result);
service.stop(resultUuid, receiver);
return ResponseEntity.ok().build();
}

@GetMapping(value = "/providers", produces = APPLICATION_JSON_VALUE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.gridsuite.securityanalysis.server.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.gridsuite.securityanalysis.server.entities.ContingencyEntity;

import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
public class ContingencyDTO {
private String contingencyId;
private String computationStatus;
private List<ContingencyElementDTO> elements;

public static ContingencyDTO toDto(ContingencyEntity contingency) {
return ContingencyDTO.builder()
.contingencyId(contingency.getContingencyId())
.computationStatus(contingency.getStatus())
.elements(contingency.getContingencyElements().stream().map(ContingencyElementDTO::toDto).collect(Collectors.toList()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.contingency.ContingencyElementType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.gridsuite.securityanalysis.server.entities.ContingencyElementEmbeddable;
Expand All @@ -16,13 +17,17 @@
*/

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ContingencyElementDTO {
private String id;
private ContingencyElementType elementType;

public static ContingencyElementDTO toDto(ContingencyElementEmbeddable contingencyElement) {
return new ContingencyElementDTO(contingencyElement.getElementId(), contingencyElement.getElementType());
return ContingencyElementDTO.builder()
.id(contingencyElement.getElementId())
.elementType(contingencyElement.getElementType())
.build();
}
}
Loading