From b5ef6994fa12b75304a7eda635e7eee7a38876d0 Mon Sep 17 00:00:00 2001 From: benrejebmoh Date: Mon, 15 Dec 2025 10:23:29 +0100 Subject: [PATCH 1/5] migration to the new error management system Signed-off-by: benrejebmoh --- pom.xml | 2 +- .../geodata/server/GeoDataException.java | 44 ------ .../geodata/server/GeoDataService.java | 91 +++++------ .../RestResponseEntityExceptionHandler.java | 37 ----- .../geodata/server/GeoDataControllerTest.java | 141 ++++++++++-------- .../geodata/server/GeoDataServiceTest.java | 2 +- .../geodata/server/ServerNameProvider.java | 28 ++++ src/test/resources/application-default.yml | 2 + 8 files changed, 150 insertions(+), 197 deletions(-) delete mode 100644 src/main/java/org/gridsuite/geodata/server/GeoDataException.java delete mode 100644 src/main/java/org/gridsuite/geodata/server/RestResponseEntityExceptionHandler.java create mode 100644 src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java diff --git a/pom.xml b/pom.xml index 3b118956..2ada0c88 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ - 44.1.0 + 46.0.0 org.gridsuite.geodata.server gridsuite org.gridsuite:geo-data-server diff --git a/src/main/java/org/gridsuite/geodata/server/GeoDataException.java b/src/main/java/org/gridsuite/geodata/server/GeoDataException.java deleted file mode 100644 index 1fb102df..00000000 --- a/src/main/java/org/gridsuite/geodata/server/GeoDataException.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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/. - */ -package org.gridsuite.geodata.server; - -import org.springframework.http.HttpStatus; - -import java.util.Objects; - -/** - * @author Franck Lecuyer - */ -public class GeoDataException extends RuntimeException { - - public enum Type { - PARSING_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), - FAILED_LINES_LOADING(HttpStatus.INTERNAL_SERVER_ERROR), - FAILED_SUBSTATIONS_LOADING(HttpStatus.INTERNAL_SERVER_ERROR); - - public final HttpStatus status; - - HttpStatus getStatus() { - return status; - } - - Type(HttpStatus status) { - this.status = status; - } - } - - private final Type type; - - public GeoDataException(Type type, Exception cause) { - super(Objects.requireNonNull(type.name()) + " : " + ((cause.getMessage() == null) ? cause.getClass().getName() : cause.getMessage()), cause); - this.type = type; - } - - Type getType() { - return type; - } -} diff --git a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java index ebd8c998..2ee87a7b 100644 --- a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java +++ b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java @@ -38,8 +38,6 @@ import java.util.stream.Stream; import static java.lang.Math.round; -import static org.gridsuite.geodata.server.GeoDataException.Type.FAILED_LINES_LOADING; -import static org.gridsuite.geodata.server.GeoDataException.Type.FAILED_SUBSTATIONS_LOADING; /** * @author Chamseddine Benhamed @@ -91,8 +89,8 @@ private Map readSubstationGeoDataFromDb(Set List substationEntities = countries.isEmpty() ? substationRepository.findAll() : substationRepository.findByCountryIn(toCountryIds(countries)); Map substationsGeoDataDB = substationEntities.stream() - .map(SubstationEntity::toGeoData) - .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); + .map(SubstationEntity::toGeoData) + .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); LOGGER.info("{} substations read from DB in {} ms", substationsGeoDataDB.size(), stopWatch.getTime(TimeUnit.MILLISECONDS)); @@ -110,8 +108,8 @@ List getSubstationsByCountries(Network network, Set // filter substation by countries List substations = network.getSubstationStream() - .filter(s -> countries.isEmpty() || s.getCountry().filter(countries::contains).isPresent()) - .toList(); + .filter(s -> countries.isEmpty() || s.getCountry().filter(countries::contains).isPresent()) + .toList(); // split substations with a known position and the others Map substationsGeoData = new HashMap<>(); @@ -138,11 +136,11 @@ List getSubstationsByCountries(Network network, Set // let's sort this map by values first : max neighbors having known GPS coords Map> sortedNeighbours = neighbours - .entrySet() - .stream() - .filter(e -> !substationsGeoData.containsKey(e.getKey())) - .sorted((e1, e2) -> neighboursComparator(network, e1.getValue(), e2.getValue())) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); + .entrySet() + .stream() + .filter(e -> !substationsGeoData.containsKey(e.getKey())) + .sorted((e1, e2) -> neighboursComparator(network, e1.getValue(), e2.getValue())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); calculateMissingGeoData(network, sortedNeighbours, substationsGeoData, substationsToCalculate); calculateDefaultSubstationsGeoData(substationsGeoData, sortedNeighbours); @@ -181,8 +179,8 @@ private void prepareGeoDataForComputation(Network network, Map neighboursToBeTreated = new HashSet<>(neighbours); while (!neighboursToBeTreated.isEmpty()) { Map foundGeoData = substationRepository.findByIdIn(neighboursToBeTreated).stream() - .map(SubstationEntity::toGeoData) - .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); + .map(SubstationEntity::toGeoData) + .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); geoDataForComputation.putAll(foundGeoData); @@ -246,8 +244,8 @@ private DefaultSubstationGeoParameter calculateDefaultSubstationGeoDataRecursive if (sortedNeighbours.get(substationToProcess) != null) { Set neighbours = sortedNeighbours.get(substationToProcess).stream() - .filter(remainingSubstations::contains) - .collect(Collectors.toSet()); + .filter(remainingSubstations::contains) + .collect(Collectors.toSet()); for (String neighbour : neighbours) { substationsGeoData.get(neighbour).setCoordinate(geoParameters.getCurrentCoordinate()); @@ -262,7 +260,7 @@ private DefaultSubstationGeoParameter calculateDefaultSubstationGeoDataRecursive private static int neighboursComparator(Network network, Set neighbors1, Set neighbors2) { return neighbors2.stream().map(s -> network.getSubstation(s).getExtension(SubstationPosition.class)).filter(Objects::nonNull).collect(Collectors.toSet()).size() - - neighbors1.stream().map(s -> network.getSubstation(s).getExtension(SubstationPosition.class)).filter(Objects::nonNull).collect(Collectors.toSet()).size(); + neighbors1.stream().map(s -> network.getSubstation(s).getExtension(SubstationPosition.class)).filter(Objects::nonNull).collect(Collectors.toSet()).size(); } enum Step { @@ -295,7 +293,7 @@ private void step(Step step, Network network, Map> sortedNei Map, Double> calculatedSubstationsOffset = new HashMap<>(); for (int iteration = 0; iteration < maxIterations; iteration++) { int calculated = 0; - for (Iterator it = substationsToCalculate.iterator(); it.hasNext();) { + for (Iterator it = substationsToCalculate.iterator(); it.hasNext(); ) { String substationId = it.next(); Set neighbours = sortedNeighbours.get(substationId); double neighborhoodOffset = calculatedSubstationsOffset.get(neighbours) != null ? nextNeighborhoodOffset(calculatedSubstationsOffset.get(neighbours)) : 0; @@ -312,7 +310,7 @@ private void step(Step step, Network network, Map> sortedNei } } LOGGER.info("Step {}, iteration {}, {} substation's coordinates have been calculated, {} remains unknown", - step == Step.ONE ? 1 : 2, iteration, calculated, substationsToCalculate.size()); + step == Step.ONE ? 1 : 2, iteration, calculated, substationsToCalculate.size()); if (calculated == 0) { break; } @@ -337,11 +335,11 @@ private static Coordinate getAverageCoordinate(List neighbour } private SubstationGeoData calculateCentroidGeoData(Substation substation, Set neighbours, Step step, - Map substationsGeoData, double neighborhoodOffset) { + Map substationsGeoData, double neighborhoodOffset) { // get neighbours geo data List neighboursGeoData = neighbours.stream().map(substationsGeoData::get) - .filter(Objects::nonNull) - .toList(); + .filter(Objects::nonNull) + .toList(); String substationCountry = substation.getNullableCountry() != null ? substation.getNullableCountry().name() : null; SubstationGeoData defaultSubstationGeoData = defaultSubstationsGeoData.get(substationCountry); @@ -350,7 +348,7 @@ private SubstationGeoData calculateCentroidGeoData(Substation substation, Set 1) { // if no neighbour found in the same country, locate the substation to a default position in its country if (neighboursGeoData.stream().noneMatch(n -> Objects.equals(n.getCountry(), substation.getNullableCountry())) && - defaultSubstationGeoData != null) { + defaultSubstationGeoData != null) { neighboursGeoData = Collections.singletonList(defaultSubstationGeoData); } coordinate = getAverageCoordinate(neighboursGeoData, neighborhoodOffset); @@ -429,7 +427,7 @@ void saveLines(List linesGeoData) { } lineRepository.saveAll(linesEntities); } catch (JsonProcessingException e) { - throw new GeoDataException(GeoDataException.Type.PARSING_ERROR, e); + throw new RuntimeException("Parsing error", e); } } @@ -454,8 +452,8 @@ private LineGeoData getLineGeoDataWithEndSubstations(Map li // need to return the line in the network order without the substations if (substation1GeoData == null || substation2GeoData == null) { LOGGER.error("line {} has substations with unknown gps positions({}={}, {}={})", lineId, - substation1.getId(), substation1GeoData, - substation2.getId(), substation2GeoData); + substation1.getId(), substation1GeoData, + substation2.getId(), substation2GeoData); return null; } @@ -506,14 +504,14 @@ List getLinesByCountries(Network network, Set countries) { // read lines from DB Map> mapSubstationsByLine = - Streams.concat(network.getLineStream(), network.getTieLineStream(), network.getHvdcLineStream()) - .collect(Collectors.toMap(Identifiable::getId, this::getSubstations)); + Streams.concat(network.getLineStream(), network.getTieLineStream(), network.getHvdcLineStream()) + .collect(Collectors.toMap(Identifiable::getId, this::getSubstations)); Map linesGeoDataDb = lineRepository.findAllById(mapSubstationsByLine.keySet()).stream().collect(Collectors.toMap(LineEntity::getId, this::toDto)); // we also want the destination substation (so we add the neighbouring country) Set countryAndNextTo = mapSubstationsByLine.entrySet().stream().flatMap(entry -> - Stream.of(entry.getValue().getLeft(), entry.getValue().getRight()).map(Substation::getNullableCountry).filter(Objects::nonNull)).collect(Collectors.toSet()); + Stream.of(entry.getValue().getLeft(), entry.getValue().getRight()).map(Substation::getNullableCountry).filter(Objects::nonNull)).collect(Collectors.toSet()); Map substationGeoDataDb = getSubstationMapByCountries(network, countryAndNextTo); List geoData = new ArrayList<>(); @@ -546,34 +544,27 @@ private Pair getSubstations(Identifiable identifiable public CompletableFuture> getSubstationsData(Network network, Set countrySet, List substationIds) { return geoDataExecutionService.supplyAsync(() -> { - try { - if (substationIds != null) { - if (!countrySet.isEmpty()) { - LOGGER.warn("Countries will not be taken into account to filter substation position."); - } - return getSubstationsByIds(network, new HashSet<>(substationIds)); - } else { - return getSubstationsByCountries(network, countrySet); + if (substationIds != null) { + if (!countrySet.isEmpty()) { + LOGGER.warn("Countries will not be taken into account to filter substation position."); } - } catch (Exception e) { - throw new GeoDataException(FAILED_SUBSTATIONS_LOADING, e); + return getSubstationsByIds(network, new HashSet<>(substationIds)); + } else { + return getSubstationsByCountries(network, countrySet); } }); } public CompletableFuture> getLinesData(Network network, Set countrySet, List lineIds) { return geoDataExecutionService.supplyAsync(() -> { - try { - if (lineIds != null) { - if (!countrySet.isEmpty()) { - LOGGER.warn("Countries will not be taken into account to filter line position."); - } - return getLinesByIds(network, new HashSet<>(lineIds)); - } else { - return getLinesByCountries(network, countrySet); + + if (lineIds != null) { + if (!countrySet.isEmpty()) { + LOGGER.warn("Countries will not be taken into account to filter line position."); } - } catch (Exception e) { - throw new GeoDataException(FAILED_LINES_LOADING, e); + return getLinesByIds(network, new HashSet<>(lineIds)); + } else { + return getLinesByCountries(network, countrySet); } }); } @@ -605,7 +596,7 @@ List getLinesByIds(Network network, Set linesIds) { List lineGeoData = lines.stream().map(line -> getLineGeoDataWithEndSubstations(linesGeoDataDb, substationGeoDataDb, line.getId(), line.getTerminal1().getVoltageLevel().getSubstation().orElseThrow(), line.getTerminal2().getVoltageLevel().getSubstation().orElseThrow())) - .filter(Objects::nonNull).toList(); + .filter(Objects::nonNull).toList(); LOGGER.info("{} lines read from DB in {} ms", linesGeoDataDb.size(), stopWatch.getTime(TimeUnit.MILLISECONDS)); return lineGeoData; @@ -618,7 +609,7 @@ public LineGeoData toDto(LineEntity lineEntity) { toDto(lineEntity.getCoordinates()) ); } catch (JsonProcessingException e) { - throw new GeoDataException(GeoDataException.Type.PARSING_ERROR, e); + throw new RuntimeException("Parsing error", e); } } diff --git a/src/main/java/org/gridsuite/geodata/server/RestResponseEntityExceptionHandler.java b/src/main/java/org/gridsuite/geodata/server/RestResponseEntityExceptionHandler.java deleted file mode 100644 index ea2d53db..00000000 --- a/src/main/java/org/gridsuite/geodata/server/RestResponseEntityExceptionHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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/. - */ -package org.gridsuite.geodata.server; - -import com.powsybl.commons.PowsyblException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; - -/** - * @author Franck Lecuyer - */ -@ControllerAdvice -public class RestResponseEntityExceptionHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(RestResponseEntityExceptionHandler.class); - - @ExceptionHandler(value = {GeoDataException.class, PowsyblException.class}) - protected ResponseEntity handleException(Exception exception) { - if (LOGGER.isErrorEnabled()) { - LOGGER.error(exception.getMessage(), exception); - } - if (exception instanceof GeoDataException) { - GeoDataException geoDataException = (GeoDataException) exception; - return ResponseEntity - .status(geoDataException.getType().getStatus()) - .body(geoDataException.getMessage()); - } - return ResponseEntity.internalServerError().body(exception.getMessage()); - } -} diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java index d9cca9ce..a4f242dc 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java @@ -16,6 +16,7 @@ import com.powsybl.network.store.client.NetworkStoreService; import com.powsybl.network.store.client.PreloadingStrategy; import com.powsybl.network.store.client.RestClientImpl; +import com.powsybl.ws.commons.error.BaseExceptionHandler; import org.gridsuite.geodata.server.dto.LineGeoData; import org.gridsuite.geodata.server.dto.SubstationGeoData; import org.gridsuite.geodata.server.repositories.LineRepository; @@ -23,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.context.annotation.Import; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -37,6 +39,8 @@ import static com.powsybl.network.store.model.NetworkStoreApi.VERSION; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.springframework.http.MediaType.APPLICATION_JSON; @@ -47,6 +51,7 @@ * @author Chamseddine Benhamed */ @WebMvcTest(GeoDataController.class) +@Import(BaseExceptionHandler.class) class GeoDataControllerTest { @Autowired @@ -100,115 +105,123 @@ void test() throws Exception { mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + WRONG_VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(content().string("Variant '" + WRONG_VARIANT_ID + "' not found")) - .andExpect(status().isInternalServerError()); + .andExpect(status().isInternalServerError()) + .andExpect(result -> { + Throwable ex = result.getResolvedException(); + assertNotNull(ex); + assertEquals("Variant '" + WRONG_VARIANT_ID + "' not found", ex.getMessage()); + }); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + WRONG_VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(content().string("Variant '" + WRONG_VARIANT_ID + "' not found")) - .andExpect(status().isInternalServerError()); + .andExpect(status().isInternalServerError()) + .andExpect(result -> { + Throwable ex = result.getResolvedException(); + assertNotNull(ex); + assertEquals("Variant '" + WRONG_VARIANT_ID + "' not found", ex.getMessage()); + }); String substationJson = objectMapper.writeValueAsString(Collections.singleton( - SubstationGeoData.builder() - .id("testID") - .country(Country.FR) - .coordinate(new Coordinate(1, 1)) - .build())); + SubstationGeoData.builder() + .id("testID") + .country(Country.FR) + .coordinate(new Coordinate(1, 1)) + .build())); mvc.perform(post("/" + VERSION + "/substations") .contentType(APPLICATION_JSON) .content(substationJson)) - .andExpect(status().isOk()); + .andExpect(status().isOk()); mvc.perform(post("/" + VERSION + "/lines") .contentType(APPLICATION_JSON) .content(objectMapper.writeValueAsString(Collections.singleton( - LineGeoData.builder() - .country1(Country.FR) - .country2(Country.BE) - .substationStart("subFR") - .substationEnd("subBE") - .coordinates(new ArrayList<>()) - .build())))) - .andExpect(status().isOk()); + LineGeoData.builder() + .country1(Country.FR) + .country2(Country.BE) + .substationStart("subFR") + .substationEnd("subBE") + .coordinates(new ArrayList<>()) + .build())))) + .andExpect(status().isOk()); mvc.perform(post("/" + VERSION + "/substations") .contentType(APPLICATION_JSON) .content(toString(GEO_DATA_SUBSTATIONS))) - .andExpect(status().isOk()); + .andExpect(status().isOk()); mvc.perform(post("/" + VERSION + "/lines") .contentType(APPLICATION_JSON) .content(toString(GEO_DATA_LINES))) - .andExpect(status().isOk()); + .andExpect(status().isOk()); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID + "&country=" + Country.FR) - .contentType(APPLICATION_JSON) - .content("[\"P1\", \"P2\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"P1\", \"P2\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) - .contentType(APPLICATION_JSON) - .content("[\"P1\", \"P2\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"P1\", \"P2\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID + "&country=" + Country.FR) - .contentType(APPLICATION_JSON) - .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) - .contentType(APPLICATION_JSON) - .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); } @Test @@ -217,12 +230,12 @@ void testGetLinesError() throws Exception { Network testNetwork = EurostagTutorialExample1Factory.create(); given(service.getNetwork(networkUuid)).willReturn(testNetwork); given(service.getNetwork(networkUuid, PreloadingStrategy.COLLECTION)).willReturn(testNetwork); - given(lineRepository.findAllById(any())).willThrow(new GeoDataException(GeoDataException.Type.PARSING_ERROR, new RuntimeException("Error parsing"))); + given(lineRepository.findAllById(any())).willThrow(new RuntimeException("Parsing error")); MvcResult mvcResult = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid) - .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()) - .andReturn(); + .contentType(APPLICATION_JSON)) + .andExpect(request().asyncStarted()) + .andReturn(); mvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isInternalServerError()); } diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java index df61aa8d..0ac84c3b 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java @@ -521,7 +521,7 @@ void testLineCoordinatesError() { .substationEnd("substation2") .build(), true, "coordinates_error"); - assertThrows(GeoDataException.class, () -> + assertThrows(RuntimeException.class, () -> geoDataService.toDto(lineEntity)); } diff --git a/src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java b/src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java new file mode 100644 index 00000000..d61a29b6 --- /dev/null +++ b/src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2025, 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.geodata.server; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author Mohamed Ben-rejeb {@literal } + */ +@Component +public class ServerNameProvider implements com.powsybl.ws.commons.error.ServerNameProvider { + + private final String name; + + public ServerNameProvider(@Value("${spring.application.name:geo-data-server}") String name) { + this.name = name; + } + + @Override + public String serverName() { + return name; + } +} diff --git a/src/test/resources/application-default.yml b/src/test/resources/application-default.yml index f88b2240..cc561e93 100644 --- a/src/test/resources/application-default.yml +++ b/src/test/resources/application-default.yml @@ -1,4 +1,6 @@ spring: + application: + name: geo-data-server jpa: database: H2 properties: From cfcec2a7854a975674a18c8c00891c9630d88fd4 Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Thu, 8 Jan 2026 10:07:15 +0100 Subject: [PATCH 2/5] fix: don't use RuntimeException --- .../java/org/gridsuite/geodata/server/GeoDataService.java | 5 +++-- .../org/gridsuite/geodata/server/GeoDataControllerTest.java | 3 ++- .../org/gridsuite/geodata/server/GeoDataServiceTest.java | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java index 2ee87a7b..c57fc4b4 100644 --- a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java +++ b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java @@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.io.UncheckedIOException; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.CompletableFuture; @@ -427,7 +428,7 @@ void saveLines(List linesGeoData) { } lineRepository.saveAll(linesEntities); } catch (JsonProcessingException e) { - throw new RuntimeException("Parsing error", e); + throw new UncheckedIOException("Parsing error", e); } } @@ -609,7 +610,7 @@ public LineGeoData toDto(LineEntity lineEntity) { toDto(lineEntity.getCoordinates()) ); } catch (JsonProcessingException e) { - throw new RuntimeException("Parsing error", e); + throw new UncheckedIOException("Parsing error", e); } } diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java index a4f242dc..9940384f 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java @@ -31,6 +31,7 @@ import org.springframework.test.web.servlet.ResultActions; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; @@ -230,7 +231,7 @@ void testGetLinesError() throws Exception { Network testNetwork = EurostagTutorialExample1Factory.create(); given(service.getNetwork(networkUuid)).willReturn(testNetwork); given(service.getNetwork(networkUuid, PreloadingStrategy.COLLECTION)).willReturn(testNetwork); - given(lineRepository.findAllById(any())).willThrow(new RuntimeException("Parsing error")); + given(lineRepository.findAllById(any())).willThrow(new UncheckedIOException("Parsing error", new IOException("IO"))); MvcResult mvcResult = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid) .contentType(APPLICATION_JSON)) diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java index 0ac84c3b..c21b195d 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import java.io.UncheckedIOException; import java.util.*; import static org.junit.jupiter.api.Assertions.*; @@ -521,7 +522,7 @@ void testLineCoordinatesError() { .substationEnd("substation2") .build(), true, "coordinates_error"); - assertThrows(RuntimeException.class, () -> + assertThrows(UncheckedIOException.class, () -> geoDataService.toDto(lineEntity)); } From 29c0f1788a034e52f9d717c8aeb28f8b2e1495b7 Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Thu, 8 Jan 2026 10:15:08 +0100 Subject: [PATCH 3/5] revert: remove formatting diffs --- .../geodata/server/GeoDataService.java | 53 ++++--- .../geodata/server/GeoDataControllerTest.java | 135 +++++++++--------- 2 files changed, 90 insertions(+), 98 deletions(-) diff --git a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java index c57fc4b4..4c272b66 100644 --- a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java +++ b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java @@ -90,8 +90,8 @@ private Map readSubstationGeoDataFromDb(Set List substationEntities = countries.isEmpty() ? substationRepository.findAll() : substationRepository.findByCountryIn(toCountryIds(countries)); Map substationsGeoDataDB = substationEntities.stream() - .map(SubstationEntity::toGeoData) - .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); + .map(SubstationEntity::toGeoData) + .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); LOGGER.info("{} substations read from DB in {} ms", substationsGeoDataDB.size(), stopWatch.getTime(TimeUnit.MILLISECONDS)); @@ -109,8 +109,8 @@ List getSubstationsByCountries(Network network, Set // filter substation by countries List substations = network.getSubstationStream() - .filter(s -> countries.isEmpty() || s.getCountry().filter(countries::contains).isPresent()) - .toList(); + .filter(s -> countries.isEmpty() || s.getCountry().filter(countries::contains).isPresent()) + .toList(); // split substations with a known position and the others Map substationsGeoData = new HashMap<>(); @@ -137,11 +137,11 @@ List getSubstationsByCountries(Network network, Set // let's sort this map by values first : max neighbors having known GPS coords Map> sortedNeighbours = neighbours - .entrySet() - .stream() - .filter(e -> !substationsGeoData.containsKey(e.getKey())) - .sorted((e1, e2) -> neighboursComparator(network, e1.getValue(), e2.getValue())) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); + .entrySet() + .stream() + .filter(e -> !substationsGeoData.containsKey(e.getKey())) + .sorted((e1, e2) -> neighboursComparator(network, e1.getValue(), e2.getValue())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); calculateMissingGeoData(network, sortedNeighbours, substationsGeoData, substationsToCalculate); calculateDefaultSubstationsGeoData(substationsGeoData, sortedNeighbours); @@ -180,8 +180,8 @@ private void prepareGeoDataForComputation(Network network, Map neighboursToBeTreated = new HashSet<>(neighbours); while (!neighboursToBeTreated.isEmpty()) { Map foundGeoData = substationRepository.findByIdIn(neighboursToBeTreated).stream() - .map(SubstationEntity::toGeoData) - .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); + .map(SubstationEntity::toGeoData) + .collect(Collectors.toMap(SubstationGeoData::getId, Function.identity())); geoDataForComputation.putAll(foundGeoData); @@ -245,8 +245,8 @@ private DefaultSubstationGeoParameter calculateDefaultSubstationGeoDataRecursive if (sortedNeighbours.get(substationToProcess) != null) { Set neighbours = sortedNeighbours.get(substationToProcess).stream() - .filter(remainingSubstations::contains) - .collect(Collectors.toSet()); + .filter(remainingSubstations::contains) + .collect(Collectors.toSet()); for (String neighbour : neighbours) { substationsGeoData.get(neighbour).setCoordinate(geoParameters.getCurrentCoordinate()); @@ -261,7 +261,7 @@ private DefaultSubstationGeoParameter calculateDefaultSubstationGeoDataRecursive private static int neighboursComparator(Network network, Set neighbors1, Set neighbors2) { return neighbors2.stream().map(s -> network.getSubstation(s).getExtension(SubstationPosition.class)).filter(Objects::nonNull).collect(Collectors.toSet()).size() - - neighbors1.stream().map(s -> network.getSubstation(s).getExtension(SubstationPosition.class)).filter(Objects::nonNull).collect(Collectors.toSet()).size(); + neighbors1.stream().map(s -> network.getSubstation(s).getExtension(SubstationPosition.class)).filter(Objects::nonNull).collect(Collectors.toSet()).size(); } enum Step { @@ -294,7 +294,7 @@ private void step(Step step, Network network, Map> sortedNei Map, Double> calculatedSubstationsOffset = new HashMap<>(); for (int iteration = 0; iteration < maxIterations; iteration++) { int calculated = 0; - for (Iterator it = substationsToCalculate.iterator(); it.hasNext(); ) { + for (Iterator it = substationsToCalculate.iterator(); it.hasNext();) { String substationId = it.next(); Set neighbours = sortedNeighbours.get(substationId); double neighborhoodOffset = calculatedSubstationsOffset.get(neighbours) != null ? nextNeighborhoodOffset(calculatedSubstationsOffset.get(neighbours)) : 0; @@ -311,7 +311,7 @@ private void step(Step step, Network network, Map> sortedNei } } LOGGER.info("Step {}, iteration {}, {} substation's coordinates have been calculated, {} remains unknown", - step == Step.ONE ? 1 : 2, iteration, calculated, substationsToCalculate.size()); + step == Step.ONE ? 1 : 2, iteration, calculated, substationsToCalculate.size()); if (calculated == 0) { break; } @@ -336,11 +336,11 @@ private static Coordinate getAverageCoordinate(List neighbour } private SubstationGeoData calculateCentroidGeoData(Substation substation, Set neighbours, Step step, - Map substationsGeoData, double neighborhoodOffset) { + Map substationsGeoData, double neighborhoodOffset) { // get neighbours geo data List neighboursGeoData = neighbours.stream().map(substationsGeoData::get) - .filter(Objects::nonNull) - .toList(); + .filter(Objects::nonNull) + .toList(); String substationCountry = substation.getNullableCountry() != null ? substation.getNullableCountry().name() : null; SubstationGeoData defaultSubstationGeoData = defaultSubstationsGeoData.get(substationCountry); @@ -349,7 +349,7 @@ private SubstationGeoData calculateCentroidGeoData(Substation substation, Set 1) { // if no neighbour found in the same country, locate the substation to a default position in its country if (neighboursGeoData.stream().noneMatch(n -> Objects.equals(n.getCountry(), substation.getNullableCountry())) && - defaultSubstationGeoData != null) { + defaultSubstationGeoData != null) { neighboursGeoData = Collections.singletonList(defaultSubstationGeoData); } coordinate = getAverageCoordinate(neighboursGeoData, neighborhoodOffset); @@ -453,8 +453,8 @@ private LineGeoData getLineGeoDataWithEndSubstations(Map li // need to return the line in the network order without the substations if (substation1GeoData == null || substation2GeoData == null) { LOGGER.error("line {} has substations with unknown gps positions({}={}, {}={})", lineId, - substation1.getId(), substation1GeoData, - substation2.getId(), substation2GeoData); + substation1.getId(), substation1GeoData, + substation2.getId(), substation2GeoData); return null; } @@ -505,14 +505,14 @@ List getLinesByCountries(Network network, Set countries) { // read lines from DB Map> mapSubstationsByLine = - Streams.concat(network.getLineStream(), network.getTieLineStream(), network.getHvdcLineStream()) - .collect(Collectors.toMap(Identifiable::getId, this::getSubstations)); + Streams.concat(network.getLineStream(), network.getTieLineStream(), network.getHvdcLineStream()) + .collect(Collectors.toMap(Identifiable::getId, this::getSubstations)); Map linesGeoDataDb = lineRepository.findAllById(mapSubstationsByLine.keySet()).stream().collect(Collectors.toMap(LineEntity::getId, this::toDto)); // we also want the destination substation (so we add the neighbouring country) Set countryAndNextTo = mapSubstationsByLine.entrySet().stream().flatMap(entry -> - Stream.of(entry.getValue().getLeft(), entry.getValue().getRight()).map(Substation::getNullableCountry).filter(Objects::nonNull)).collect(Collectors.toSet()); + Stream.of(entry.getValue().getLeft(), entry.getValue().getRight()).map(Substation::getNullableCountry).filter(Objects::nonNull)).collect(Collectors.toSet()); Map substationGeoDataDb = getSubstationMapByCountries(network, countryAndNextTo); List geoData = new ArrayList<>(); @@ -558,7 +558,6 @@ public CompletableFuture> getSubstationsData(Network net public CompletableFuture> getLinesData(Network network, Set countrySet, List lineIds) { return geoDataExecutionService.supplyAsync(() -> { - if (lineIds != null) { if (!countrySet.isEmpty()) { LOGGER.warn("Countries will not be taken into account to filter line position."); @@ -597,7 +596,7 @@ List getLinesByIds(Network network, Set linesIds) { List lineGeoData = lines.stream().map(line -> getLineGeoDataWithEndSubstations(linesGeoDataDb, substationGeoDataDb, line.getId(), line.getTerminal1().getVoltageLevel().getSubstation().orElseThrow(), line.getTerminal2().getVoltageLevel().getSubstation().orElseThrow())) - .filter(Objects::nonNull).toList(); + .filter(Objects::nonNull).toList(); LOGGER.info("{} lines read from DB in {} ms", linesGeoDataDb.size(), stopWatch.getTime(TimeUnit.MILLISECONDS)); return lineGeoData; diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java index 9940384f..616266bd 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java @@ -21,6 +21,7 @@ import org.gridsuite.geodata.server.dto.SubstationGeoData; import org.gridsuite.geodata.server.repositories.LineRepository; import org.gridsuite.geodata.server.repositories.SubstationRepository; +import org.hamcrest.core.StringContains; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -106,123 +107,115 @@ void test() throws Exception { mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + WRONG_VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(status().isInternalServerError()) - .andExpect(result -> { - Throwable ex = result.getResolvedException(); - assertNotNull(ex); - assertEquals("Variant '" + WRONG_VARIANT_ID + "' not found", ex.getMessage()); - }); + .andExpect(content().string(StringContains.containsString("Variant '" + WRONG_VARIANT_ID + "' not found"))) + .andExpect(status().isInternalServerError()); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()); + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + WRONG_VARIANT_ID) .contentType(APPLICATION_JSON)) - .andExpect(status().isInternalServerError()) - .andExpect(result -> { - Throwable ex = result.getResolvedException(); - assertNotNull(ex); - assertEquals("Variant '" + WRONG_VARIANT_ID + "' not found", ex.getMessage()); - }); + .andExpect(content().string(StringContains.containsString("Variant '" + WRONG_VARIANT_ID + "' not found"))) + .andExpect(status().isInternalServerError()); String substationJson = objectMapper.writeValueAsString(Collections.singleton( - SubstationGeoData.builder() - .id("testID") - .country(Country.FR) - .coordinate(new Coordinate(1, 1)) - .build())); + SubstationGeoData.builder() + .id("testID") + .country(Country.FR) + .coordinate(new Coordinate(1, 1)) + .build())); mvc.perform(post("/" + VERSION + "/substations") .contentType(APPLICATION_JSON) .content(substationJson)) - .andExpect(status().isOk()); + .andExpect(status().isOk()); mvc.perform(post("/" + VERSION + "/lines") .contentType(APPLICATION_JSON) .content(objectMapper.writeValueAsString(Collections.singleton( - LineGeoData.builder() - .country1(Country.FR) - .country2(Country.BE) - .substationStart("subFR") - .substationEnd("subBE") - .coordinates(new ArrayList<>()) - .build())))) - .andExpect(status().isOk()); + LineGeoData.builder() + .country1(Country.FR) + .country2(Country.BE) + .substationStart("subFR") + .substationEnd("subBE") + .coordinates(new ArrayList<>()) + .build())))) + .andExpect(status().isOk()); mvc.perform(post("/" + VERSION + "/substations") .contentType(APPLICATION_JSON) .content(toString(GEO_DATA_SUBSTATIONS))) - .andExpect(status().isOk()); + .andExpect(status().isOk()); mvc.perform(post("/" + VERSION + "/lines") .contentType(APPLICATION_JSON) .content(toString(GEO_DATA_LINES))) - .andExpect(status().isOk()); + .andExpect(status().isOk()); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID + "&country=" + Country.FR) - .contentType(APPLICATION_JSON) - .content("[\"P1\", \"P2\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"P1\", \"P2\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/substations/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) - .contentType(APPLICATION_JSON) - .content("[\"P1\", \"P2\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"P1\", \"P2\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID + "&country=" + Country.FR) - .contentType(APPLICATION_JSON) - .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); mockMvcResultActions = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid + "&variantId=" + VARIANT_ID) - .contentType(APPLICATION_JSON) - .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) - .andExpect(request().asyncStarted()); + .contentType(APPLICATION_JSON) + .content("[\"NHV1_NHV2_2\", \"NHV1_NHV2_1\"]")) + .andExpect(request().asyncStarted()); mvc.perform(asyncDispatch(mockMvcResultActions.andReturn())) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(0))); + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(0))); } @Test @@ -234,9 +227,9 @@ void testGetLinesError() throws Exception { given(lineRepository.findAllById(any())).willThrow(new UncheckedIOException("Parsing error", new IOException("IO"))); MvcResult mvcResult = mvc.perform(post("/" + VERSION + "/lines/infos?networkUuid=" + networkUuid) - .contentType(APPLICATION_JSON)) - .andExpect(request().asyncStarted()) - .andReturn(); + .contentType(APPLICATION_JSON)) + .andExpect(request().asyncStarted()) + .andReturn(); mvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isInternalServerError()); } From 49fe2234756428bc9aea0192acc11986598b1ecc Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Thu, 8 Jan 2026 10:15:20 +0100 Subject: [PATCH 4/5] fix: simplify server name --- ...eProvider.java => GeoDataServerNameProvider.java} | 12 +++--------- src/test/resources/application-default.yml | 2 -- 2 files changed, 3 insertions(+), 11 deletions(-) rename src/test/java/org/gridsuite/geodata/server/{ServerNameProvider.java => GeoDataServerNameProvider.java} (60%) diff --git a/src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java b/src/test/java/org/gridsuite/geodata/server/GeoDataServerNameProvider.java similarity index 60% rename from src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java rename to src/test/java/org/gridsuite/geodata/server/GeoDataServerNameProvider.java index d61a29b6..d2fde17c 100644 --- a/src/test/java/org/gridsuite/geodata/server/ServerNameProvider.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataServerNameProvider.java @@ -6,23 +6,17 @@ */ package org.gridsuite.geodata.server; -import org.springframework.beans.factory.annotation.Value; +import com.powsybl.ws.commons.error.ServerNameProvider; import org.springframework.stereotype.Component; /** * @author Mohamed Ben-rejeb {@literal } */ @Component -public class ServerNameProvider implements com.powsybl.ws.commons.error.ServerNameProvider { - - private final String name; - - public ServerNameProvider(@Value("${spring.application.name:geo-data-server}") String name) { - this.name = name; - } +public class GeoDataServerNameProvider implements ServerNameProvider { @Override public String serverName() { - return name; + return "geo-data-server"; } } diff --git a/src/test/resources/application-default.yml b/src/test/resources/application-default.yml index cc561e93..f88b2240 100644 --- a/src/test/resources/application-default.yml +++ b/src/test/resources/application-default.yml @@ -1,6 +1,4 @@ spring: - application: - name: geo-data-server jpa: database: H2 properties: From ac1e30eee5a8ea2460aa29bcdee1284828122116 Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Thu, 8 Jan 2026 10:21:50 +0100 Subject: [PATCH 5/5] fix: imports Signed-off-by: Joris Mancini --- .../org/gridsuite/geodata/server/GeoDataControllerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java index 616266bd..81288d4c 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataControllerTest.java @@ -41,8 +41,6 @@ import static com.powsybl.network.store.model.NetworkStoreApi.VERSION; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.springframework.http.MediaType.APPLICATION_JSON;