Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 1 addition & 11 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<parent>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-parent-ws</artifactId>
<version>12</version>
<version>13</version>
<relativePath/>
</parent>

Expand Down Expand Up @@ -145,16 +145,6 @@
<artifactId>powsybl-config-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
48 changes: 13 additions & 35 deletions src/main/java/org/gridsuite/explore/server/RestTemplateConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,28 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponentModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

/**
* @author Etienne Homer <etienne.homer at rte-france.com>
*/
@Configuration
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;
}

public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper());
return converter;
}

private ObjectMapper createObjectMapper() {
var objectMapper = Jackson2ObjectMapperBuilder.json().build();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.registerModule(new JsonComponentModule());
return objectMapper;
}

/**
* we alter the {@link ObjectMapper} generated by Spring using SpringBoot system
* @return json customizer
* @see org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration JacksonAutoConfiguration
* @see org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration HttpMessageConvertersAutoConfiguration
* @see org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration RestTemplateAutoConfiguration
*/
@Bean
public ObjectMapper objectMapper() {
return createObjectMapper();
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
//also from .config: spring.jackson.serialization.write-dates-as-timestamps=false
return builder -> builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
//.findModulesViaServiceLoader(true)
.modulesToInstall(new JsonComponentModule());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.gridsuite.explore.server.ExploreException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
Expand All @@ -26,21 +27,16 @@
import java.util.UUID;
import java.util.stream.Collectors;

import static org.gridsuite.explore.server.ExploreException.Type.*;
import static org.gridsuite.explore.server.ExploreException.Type.INCORRECT_CASE_FILE;

@Service
public class CaseService implements IDirectoryElementsService {
private static final String CASE_SERVER_API_VERSION = "v1";

private static final String DELIMITER = "/";
private final RestTemplate restTemplate;
private String caseServerBaseUri;

@Autowired
public CaseService(@Value("${powsybl.services.case-server.base-uri:http://case-server/}") String studyServerBaseUri,
RestTemplate restTemplate) {
this.caseServerBaseUri = studyServerBaseUri;
this.restTemplate = restTemplate;
RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.rootUri(studyServerBaseUri + "/v1").build();
}

private static ExploreException wrapRemoteError(String response, HttpStatus statusCode) {
Expand All @@ -51,11 +47,7 @@ private static ExploreException wrapRemoteError(String response, HttpStatus stat
}
}

public void setBaseUri(String actionsServerBaseUri) {
this.caseServerBaseUri = actionsServerBaseUri;
}

UUID importCase(MultipartFile multipartFile) {
public UUID importCase(MultipartFile multipartFile) {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
UUID caseUuid;
HttpHeaders headers = new HttpHeaders();
Expand All @@ -64,11 +56,9 @@ UUID importCase(MultipartFile multipartFile) {
Objects.requireNonNull(multipartFile.getOriginalFilename());
body.add("file", multipartFile.getResource());
}
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(
body, headers);
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(body, headers);
try {
caseUuid = restTemplate.postForObject(caseServerBaseUri + "/" + CASE_SERVER_API_VERSION + "/cases", request,
UUID.class);
caseUuid = restTemplate.postForObject("/cases", request, UUID.class);
} catch (HttpStatusCodeException e) {
if (e.getStatusCode().equals(HttpStatus.UNPROCESSABLE_ENTITY)) {
throw new ExploreException(INCORRECT_CASE_FILE, e.getMessage());
Expand All @@ -78,35 +68,33 @@ UUID importCase(MultipartFile multipartFile) {
return caseUuid;
}

UUID duplicateCase(UUID sourceCaseUuid) {
String path = UriComponentsBuilder.fromPath(DELIMITER + CASE_SERVER_API_VERSION + "/cases")
public UUID duplicateCase(UUID sourceCaseUuid) {
String path = UriComponentsBuilder.fromPath("/cases")
.queryParam("duplicateFrom", sourceCaseUuid)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return restTemplate.exchange(caseServerBaseUri + path, HttpMethod.POST, new HttpEntity<>(headers), UUID.class)
return restTemplate.exchange(path, HttpMethod.POST, new HttpEntity<>(headers), UUID.class)
.getBody();
}

@Override
public void delete(UUID id, String userId) {
String path = UriComponentsBuilder.fromPath(DELIMITER + CASE_SERVER_API_VERSION + "/cases/{id}")
String path = UriComponentsBuilder.fromPath("/cases/{id}")
.buildAndExpand(id)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.add(HEADER_USER_ID, userId);
restTemplate.exchange(caseServerBaseUri + path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class);
restTemplate.exchange(path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class);
}

@Override
public List<Map<String, Object>> getMetadata(List<UUID> casesUuids) {
var ids = casesUuids.stream().map(UUID::toString).collect(Collectors.joining(","));
String path = UriComponentsBuilder
.fromPath(DELIMITER + CASE_SERVER_API_VERSION + "/cases/metadata" + "?ids=" + ids)
.buildAndExpand()
String path = UriComponentsBuilder.fromPath("/cases/metadata")
.queryParam("ids", ids)
.toUriString();
return restTemplate.exchange(caseServerBaseUri + path, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Map<String, Object>>>() {
}).getBody();
return restTemplate.exchange(path, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Map<String, Object>>>() { }).getBody();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
package org.gridsuite.explore.server.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand All @@ -23,133 +27,116 @@
*/
@Service
public class ContingencyListService implements IDirectoryElementsService {
private static final String ACTIONS_API_VERSION = "v1";
private static final String DELIMITER = "/";
private static final String HEADER_USER_ID = "userId";
private static final String HEADER_DUPLICATE_FROM = "duplicateFrom";
private String actionsServerBaseUri;
private final RestTemplate restTemplate;

@Autowired
public ContingencyListService(RestTemplate restTemplate, RemoteServicesProperties remoteServicesProperties) {
this.actionsServerBaseUri = remoteServicesProperties.getServiceUri("actions-server");
this.restTemplate = restTemplate;
}

public void setActionsServerBaseUri(String actionsServerBaseUri) {
this.actionsServerBaseUri = actionsServerBaseUri;
public ContingencyListService(RestTemplateBuilder restTemplateBuilder, RemoteServicesProperties remoteServicesProperties) {
this.restTemplate = restTemplateBuilder.rootUri(remoteServicesProperties.getServiceUri("actions-server") + "/v1").build();
}

@Override
public void delete(UUID id, String userId) {
String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + "/contingency-lists/{id}")
String path = UriComponentsBuilder.fromPath("/contingency-lists/{id}")
.buildAndExpand(id)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.add(HEADER_USER_ID, userId);
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class);
restTemplate.exchange(path, HttpMethod.DELETE, new HttpEntity<>(headers), Void.class);
}

public void insertScriptContingencyList(UUID id, String content) {
String path = UriComponentsBuilder
.fromPath(DELIMITER + ACTIONS_API_VERSION + "/script-contingency-lists?id={id}")
.buildAndExpand(id)
String path = UriComponentsBuilder.fromPath("/script-contingency-lists")
.queryParam("id", id)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> httpEntity = new HttpEntity<>(content, headers);
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, httpEntity, Void.class);
restTemplate.exchange(path, HttpMethod.POST, httpEntity, Void.class);
}

public void insertScriptContingencyList(UUID sourceListId, UUID id) {
String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + "/script-contingency-lists")
String path = UriComponentsBuilder.fromPath("/script-contingency-lists")
.queryParam(HEADER_DUPLICATE_FROM, sourceListId)
.queryParam("id", id)
.toUriString();
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, null, Void.class);
restTemplate.exchange(path, HttpMethod.POST, null, Void.class);
}

public void insertFormContingencyList(UUID id, String content) {
String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + "/form-contingency-lists?id={id}")
.buildAndExpand(id)
String path = UriComponentsBuilder.fromPath("/form-contingency-lists")
.queryParam("id", id)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> httpEntity = new HttpEntity<>(content, headers);
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, httpEntity, Void.class);
restTemplate.exchange(path, HttpMethod.POST, httpEntity, Void.class);
}

public void insertIdentifierContingencyList(UUID id, String content) {
String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + "/identifier-contingency-lists?id={id}")
.buildAndExpand(id)
String path = UriComponentsBuilder.fromPath("/identifier-contingency-lists")
.queryParam("id", id)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> httpEntity = new HttpEntity<>(content, headers);
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, httpEntity, Void.class);
restTemplate.exchange(path, HttpMethod.POST, httpEntity, Void.class);
}

public void insertFormContingencyList(UUID sourceListId, UUID id) {
String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + "/form-contingency-lists")
String path = UriComponentsBuilder.fromPath("/form-contingency-lists")
.queryParam(HEADER_DUPLICATE_FROM, sourceListId)
.queryParam("id", id)
.toUriString();
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, null, Void.class);
restTemplate.exchange(path, HttpMethod.POST, null, Void.class);
}

public void insertIdentifierContingencyList(UUID sourceListId, UUID id) {
String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + "/identifier-contingency-lists")
String path = UriComponentsBuilder.fromPath("/identifier-contingency-lists")
.queryParam(HEADER_DUPLICATE_FROM, sourceListId)
.queryParam("id", id)
.toUriString();
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, null, Void.class);
restTemplate.exchange(path, HttpMethod.POST, null, Void.class);
}

public void newScriptFromFormContingencyList(UUID id, UUID newId) {
String path = UriComponentsBuilder
.fromPath(DELIMITER + ACTIONS_API_VERSION + "/form-contingency-lists/{id}/new-script?newId={newId}")
.buildAndExpand(id, newId)
String path = UriComponentsBuilder.fromPath("/form-contingency-lists/{id}/new-script")
.queryParam("newId", newId)
.buildAndExpand(id)
.toUriString();
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, null, Void.class);
restTemplate.exchange(path, HttpMethod.POST, null, Void.class);
}

public void replaceFormContingencyListWithScript(UUID id, String userId) {
String path = UriComponentsBuilder
.fromPath(DELIMITER + ACTIONS_API_VERSION + "/form-contingency-lists/{id}/replace-with-script")
String path = UriComponentsBuilder.fromPath("/form-contingency-lists/{id}/replace-with-script")
.buildAndExpand(id)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.set(HEADER_USER_ID, userId);
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.POST, new HttpEntity<>(headers), Void.class);
restTemplate.exchange(path, HttpMethod.POST, new HttpEntity<>(headers), Void.class);
}

@Override
public List<Map<String, Object>> getMetadata(List<UUID> contingencyListsUuids) {
var ids = contingencyListsUuids.stream().map(UUID::toString).collect(Collectors.joining(","));
String path = UriComponentsBuilder
.fromPath(DELIMITER + ACTIONS_API_VERSION + "/contingency-lists/metadata" + "?ids=" + ids)
.buildAndExpand()
String path = UriComponentsBuilder.fromPath("/contingency-lists/metadata")
.queryParam("ids", ids)
.toUriString();
return restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Map<String, Object>>>() {
}).getBody();
return restTemplate.exchange(path, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Map<String, Object>>>() { }).getBody();
}

public void updateContingencyList(UUID id, String content, String userId, String element) {

String path = UriComponentsBuilder.fromPath(DELIMITER + ACTIONS_API_VERSION + element)
String path = UriComponentsBuilder.fromPath(element)
.buildAndExpand(id)
.toUriString();
restTemplate.exchange(actionsServerBaseUri + path, HttpMethod.PUT, getHttpEntityWithUserHeader(userId, content), Void.class);

restTemplate.exchange(path, HttpMethod.PUT, getHttpEntityWithUserHeader(userId, content), Void.class);
}

private HttpEntity<String> getHttpEntityWithUserHeader(String userId, String content) {

HttpHeaders headers = new HttpHeaders();
headers.set(HEADER_USER_ID, userId);
headers.setContentType(MediaType.APPLICATION_JSON);

return new HttpEntity<>(content, headers);
}
}
Loading