From eb55a259f49a9993b23a3b1a593fced22e49d391 Mon Sep 17 00:00:00 2001 From: Eric Degenetais Date: Thu, 16 May 2024 19:32:09 +0200 Subject: [PATCH 1/3] First, create an error model to make parsing simpler, and map unpexpected errors to it. Added benefit : less inforamtion leak about the server. --- .../controller/handlers/ErrorReport.java | 33 +++++++++++++ .../handlers/UnexpectedExceptionHandler.java | 47 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/ErrorReport.java create mode 100644 psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/UnexpectedExceptionHandler.java diff --git a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/ErrorReport.java b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/ErrorReport.java new file mode 100644 index 0000000..c95f5a2 --- /dev/null +++ b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/ErrorReport.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2022-2024 Agence du Numérique en Santé (ANS) (https://esante.gouv.fr) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package fr.ans.psc.toggle.controller.handlers; + +import java.util.Date; + +/** + * Error report objet used to report errors to rest clients. + * + * @author edegenetais + */ +public class ErrorReport { + public final Date timestamp=new Date(); + public final String error; + + public ErrorReport(String error) { + this.error = error; + } + +} diff --git a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/UnexpectedExceptionHandler.java b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/UnexpectedExceptionHandler.java new file mode 100644 index 0000000..9e8b9b4 --- /dev/null +++ b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/UnexpectedExceptionHandler.java @@ -0,0 +1,47 @@ +/* + * Copyright © 2022-2024 Agence du Numérique en Santé (ANS) (https://esante.gouv.fr) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package fr.ans.psc.toggle.controller.handlers; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +/** + * This default exception handler filters out server inner detail. + * + * @author edegenetais + */ +@ControllerAdvice +@Controller +@Order(Ordered.LOWEST_PRECEDENCE) +public class UnexpectedExceptionHandler extends ResponseEntityExceptionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(UnexpectedExceptionHandler.class); + + @ExceptionHandler(value = Throwable.class) + public final ResponseEntity handleAllExceptions(Throwable ex, WebRequest request) { + LOGGER.error("Unexpected error", ex); + return new ResponseEntity<>(new ErrorReport("Internal Server Error"), HttpStatus.INTERNAL_SERVER_ERROR); + } +} From b25d275010db909d5f5a54a14fc664761e8df542 Mon Sep 17 00:00:00 2001 From: Eric Degenetais Date: Thu, 16 May 2024 19:33:23 +0200 Subject: [PATCH 2/3] Reporting toggle file parsing problems as 400 bad request to make diagnosis easier. --- .../DataProcessingExceptionHandler.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/DataProcessingExceptionHandler.java diff --git a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/DataProcessingExceptionHandler.java b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/DataProcessingExceptionHandler.java new file mode 100644 index 0000000..8f53605 --- /dev/null +++ b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/DataProcessingExceptionHandler.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2022-2024 Agence du Numérique en Santé (ANS) (https://esante.gouv.fr) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package fr.ans.psc.toggle.controller.handlers; + +import fr.ans.psc.toggle.exception.ToggleFileParsingException; +import org.junit.jupiter.params.shadow.com.univocity.parsers.common.DataProcessingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +/** + * This handler overrides the default error handling behavior to report toggle file parsing errors. + * + * @author edegenetais + */ +@ControllerAdvice +@Controller +@Order(Ordered.HIGHEST_PRECEDENCE) +public class DataProcessingExceptionHandler extends ResponseEntityExceptionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(DataProcessingExceptionHandler.class); + + @ExceptionHandler(value = DataProcessingException.class) + public final ResponseEntity handleAllExceptions( + DataProcessingException ex, WebRequest request) { + LOGGER.error("Invalid toggle file", ex); + return new ResponseEntity<>(new ErrorReport(ex.getMessage()), HttpStatus.BAD_REQUEST); + } +} From f33d49510cc595680f3268540951e549da2e5b50 Mon Sep 17 00:00:00 2001 From: Eric Degenetais Date: Thu, 16 May 2024 19:34:42 +0200 Subject: [PATCH 3/3] Detecting invalid source/destination codes and report them as 400 bas_request. --- .../toggle/controller/ToggleController.java | 14 +++++- .../InvalidParameterExceptionHandler.java | 48 +++++++++++++++++++ .../exception/InvalidParameterException.java | 28 +++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/InvalidParameterExceptionHandler.java create mode 100644 psc-toggle-manager/src/main/java/fr/ans/psc/toggle/exception/InvalidParameterException.java diff --git a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/ToggleController.java b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/ToggleController.java index 3a96a14..f8b42ad 100644 --- a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/ToggleController.java +++ b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/ToggleController.java @@ -15,6 +15,7 @@ */ package fr.ans.psc.toggle.controller; +import fr.ans.psc.toggle.exception.InvalidParameterException; import fr.ans.psc.toggle.model.PsIdType; import fr.ans.psc.toggle.service.ToggleService; import lombok.extern.slf4j.Slf4j; @@ -42,9 +43,20 @@ public ToggleController(ToggleService toggleService) { @PostMapping(value = "/toggle", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public ResponseEntity toggleRegistrySource(@RequestParam("from") String from, @RequestParam("to") String to, @RequestParam("toggleFile") MultipartFile mpFile) { - toggleService.toggle(mpFile, PsIdType.valueOf(from.toUpperCase()), PsIdType.valueOf(to.toUpperCase())); + + final PsIdType sourceIdType = decodeIdType(from, "from"); + final PsIdType destinationIdType = decodeIdType(to, "to"); + toggleService.toggle(mpFile, sourceIdType, destinationIdType); return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + private PsIdType decodeIdType(String name, final String parmName) { + try { + return PsIdType.valueOf(name.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new InvalidParameterException(parmName + ": " + e.getMessage(), e); + } + } } diff --git a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/InvalidParameterExceptionHandler.java b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/InvalidParameterExceptionHandler.java new file mode 100644 index 0000000..c230cb2 --- /dev/null +++ b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/controller/handlers/InvalidParameterExceptionHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright © 2022-2024 Agence du Numérique en Santé (ANS) (https://esante.gouv.fr) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package fr.ans.psc.toggle.controller.handlers; + +import fr.ans.psc.toggle.exception.InvalidParameterException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +/** + * This handler overrides the default error handling behavior to report invalid endpoint parameters. + * + * @author edegenetais + */ +@ControllerAdvice +@Controller +@Order(Ordered.HIGHEST_PRECEDENCE) +public class InvalidParameterExceptionHandler extends ResponseEntityExceptionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(InvalidParameterException.class); + + @ExceptionHandler(value = InvalidParameterException.class) + public final ResponseEntity handleAllExceptions(InvalidParameterException ex, WebRequest request) { + LOGGER.error("Invalid REST call parameters", ex); + return new ResponseEntity<>(new ErrorReport(ex.getMessage()), HttpStatus.BAD_REQUEST); + } +} diff --git a/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/exception/InvalidParameterException.java b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/exception/InvalidParameterException.java new file mode 100644 index 0000000..aa5d51f --- /dev/null +++ b/psc-toggle-manager/src/main/java/fr/ans/psc/toggle/exception/InvalidParameterException.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2022-2024 Agence du Numérique en Santé (ANS) (https://esante.gouv.fr) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package fr.ans.psc.toggle.exception; + +/** + * + * @author edegenetais + */ +public class InvalidParameterException extends RuntimeException{ + + public InvalidParameterException(String string, Throwable thrwbl) { + super(string, thrwbl); + } + +}