diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ee771938..00000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 79d7c43d..9754d5d8 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ hs_err_pid* # Helm /helm/charts/* **/.terraform/ + +.DS_Store \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/wispconverter/config/RedisConfig.java b/src/main/java/it/gov/pagopa/wispconverter/config/RedisConfig.java index 888557d0..f82cb60c 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/config/RedisConfig.java +++ b/src/main/java/it/gov/pagopa/wispconverter/config/RedisConfig.java @@ -1,7 +1,5 @@ package it.gov.pagopa.wispconverter.config; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; @@ -26,13 +24,6 @@ public class RedisConfig { @Value("${spring.redis.password}") private String password; - @Bean - public ObjectMapper registerObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules(); - objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); - return objectMapper; - } - @Bean public LettuceConnectionFactory registerRedisConnectionFactory() { RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(host, port); diff --git a/src/main/java/it/gov/pagopa/wispconverter/config/UnmarshallerConfig.java b/src/main/java/it/gov/pagopa/wispconverter/config/UnmarshallerConfig.java index 9e073a71..3dfdba86 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/config/UnmarshallerConfig.java +++ b/src/main/java/it/gov/pagopa/wispconverter/config/UnmarshallerConfig.java @@ -10,7 +10,6 @@ @Configuration public class UnmarshallerConfig { - @Bean @Scope("prototype") public DocumentBuilderFactory documentBuilderFactory() throws ParserConfigurationException { diff --git a/src/main/java/it/gov/pagopa/wispconverter/config/WebMvcConfig.java b/src/main/java/it/gov/pagopa/wispconverter/config/WebMvcConfig.java index f875884e..60f1c2a5 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/config/WebMvcConfig.java +++ b/src/main/java/it/gov/pagopa/wispconverter/config/WebMvcConfig.java @@ -2,25 +2,27 @@ import com.fasterxml.jackson.databind.ObjectMapper; import it.gov.pagopa.wispconverter.config.model.AppCors; +import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; -import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.Locale; @Configuration +@RequiredArgsConstructor public class WebMvcConfig implements WebMvcConfigurer { List locales = Arrays.asList(Locale.ENGLISH, Locale.ITALIAN); @@ -32,13 +34,13 @@ public class WebMvcConfig implements WebMvcConfigurer { @SneakyThrows @Override public void addCorsMappings(CorsRegistry registry) { - AppCors appCors = new ObjectMapper().readValue(corsConfiguration, - AppCors.class); + AppCors appCors = new ObjectMapper().readValue(corsConfiguration, AppCors.class); registry.addMapping("/**") .allowedOrigins(appCors.getOrigins()) .allowedMethods(appCors.getMethods()); } + @Bean public LocaleResolver localeResolver() { AcceptHeaderLocaleResolver acceptHeaderLocaleResolver = new AcceptHeaderLocaleResolver(); @@ -47,14 +49,15 @@ public LocaleResolver localeResolver() { return acceptHeaderLocaleResolver; } + @Bean - public MessageSource messageSource() { - ReloadableResourceBundleMessageSource messageSource = - new ReloadableResourceBundleMessageSource(); - messageSource.setBasename("classpath:messages"); - messageSource.setDefaultEncoding("UTF-8"); - messageSource.setUseCodeAsDefaultMessage(true); - return messageSource; + public ResourceBundleMessageSource messageSource() { + var resourceBundleMessageSource=new ResourceBundleMessageSource(); + resourceBundleMessageSource.setBasename("i18n/messages"); // directory with messages_XX.properties + resourceBundleMessageSource.setDefaultLocale(Locale.ENGLISH); + resourceBundleMessageSource.setDefaultEncoding(StandardCharsets.UTF_8.name()); + resourceBundleMessageSource.setAlwaysUseMessageFormat(true); + return resourceBundleMessageSource; } @Primary diff --git a/src/main/java/it/gov/pagopa/wispconverter/controller/RedirectController.java b/src/main/java/it/gov/pagopa/wispconverter/controller/RedirectController.java index 42bf3f3f..8062730e 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/controller/RedirectController.java +++ b/src/main/java/it/gov/pagopa/wispconverter/controller/RedirectController.java @@ -13,6 +13,7 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -36,7 +37,8 @@ public class RedirectController { }) @GetMapping public void redirect(@Parameter(description = "", example = "identificativoIntermediarioPA_sessionId") - @NotBlank(message = "{redirect.session-id.not-blank}") @RequestParam("sessionId") String sessionId, + @NotBlank(message = "{redirect.session-id.not-blank}") + @RequestParam("sessionId") String sessionId, HttpServletResponse response) throws IOException { ConversionResultDTO conversionResultDTO = converterService.convert(sessionId); response.sendRedirect(conversionResultDTO.getUri()); diff --git a/src/main/java/it/gov/pagopa/wispconverter/controller/advice/ErrorHandler.java b/src/main/java/it/gov/pagopa/wispconverter/controller/advice/ErrorHandler.java deleted file mode 100644 index 1f24ad4e..00000000 --- a/src/main/java/it/gov/pagopa/wispconverter/controller/advice/ErrorHandler.java +++ /dev/null @@ -1,139 +0,0 @@ -package it.gov.pagopa.wispconverter.controller.advice; - -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import it.gov.pagopa.wispconverter.controller.advice.model.ApiErrorResponse; -import it.gov.pagopa.wispconverter.exception.AppClientException; -import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; -import it.gov.pagopa.wispconverter.exception.AppException; -import it.gov.pagopa.wispconverter.util.AppErrorUtil; -import jakarta.validation.ConstraintViolationException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.tuple.Pair; -import org.springframework.http.*; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.MethodArgumentNotValidException; -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; - -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * All Exceptions are handled by this class - */ -@ControllerAdvice -@Slf4j -@RequiredArgsConstructor -public class ErrorHandler extends ResponseEntityExceptionHandler { - - private final AppErrorUtil appErrorUtil; - - @ApiResponses(value = { - @ApiResponse(responseCode = "500", description = "Internal Server Error", content = { - @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class), examples = {@ExampleObject( - """ - { - "errorId": "68ce8c6a-6d53-486c-97fe-79430d24fb7d", - "timestamp": "2023-10-09T08:01:39.421224Z", - "httpStatusCode": 500, - "httpStatusDescription": "Internal Server Error", - "appErrorCode": "WIC-0500", - "message": "An unexpected error has occurred. Please contact support" - } - """ - )}) - }), - @ApiResponse(responseCode = "400", description = "Bad Request", content = { - @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class), examples = {@ExampleObject( - """ - { - "timestamp": "2023-10-09T07:53:14.077792Z", - "httpStatusCode": 400, - "httpStatusDescription": "Bad Request", - "appErrorCode": "WIC-0400", - "message": "Bad request", - "errors": [ - { - "message": "Field error in ..." - } - ] - } - """ - )}) - }), - @ApiResponse(responseCode = "404", description = "Not found", content = { - @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class), examples = {@ExampleObject( - """ - { - "timestamp": "2023-10-09T07:53:43.367312Z", - "httpStatusCode": 404, - "httpStatusDescription": "Not Found", - "appErrorCode": "WIC-0404", - "message": "Request POST /api/v1/..... not found" - } - """ - )}) - }) - }) - @ExceptionHandler({AppException.class, AppClientException.class}) - public ResponseEntity handleAppException(AppException appEx) { - Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, null); - return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) - .body(httpStatusApiErrorResponsePair.getRight()); - } - - @Override - protected ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { - List errorMessages = ex.getBindingResult().getAllErrors().stream() - .map(oe -> ApiErrorResponse.ErrorMessage.builder().message(oe.toString()).build()) - .collect(Collectors.toList()); - AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.BAD_REQUEST); - Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, errorMessages); - return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) - .body(httpStatusApiErrorResponsePair.getRight()); - } - - @ExceptionHandler(Exception.class) - public ResponseEntity handleGenericException(Exception ex, WebRequest request) { - String errorId = UUID.randomUUID().toString(); - log.error(String.format("ExceptionHandler: ErrorId=[%s] %s", errorId, ex.getMessage()), ex); - - AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.ERROR); - // errorId viene usato solo per i casi di eccezioni non gestite - Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, errorId, null); - return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) - .body(httpStatusApiErrorResponsePair.getRight()); - } - - @ExceptionHandler(ConstraintViolationException.class) - public final ResponseEntity handleConstraintViolation(ConstraintViolationException ex, WebRequest request) { - List errorMessages = ex.getConstraintViolations().stream() - .map(oe -> ApiErrorResponse.ErrorMessage.builder().message(oe.getMessage()).build()) - .collect(Collectors.toList()); - AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.BAD_REQUEST); - Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, errorMessages); - return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) - .body(httpStatusApiErrorResponsePair.getRight()); - } - - @Override - protected ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { - List errorMessages = Stream.of(ex.getCause().getMessage()) - .map(oe -> ApiErrorResponse.ErrorMessage.builder().message(oe).build()) - .collect(Collectors.toList()); - AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.BAD_REQUEST); - Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, errorMessages); - return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) - .body(httpStatusApiErrorResponsePair.getRight()); - } - -} diff --git a/src/main/java/it/gov/pagopa/wispconverter/controller/advice/GlobalExceptionHandler.java b/src/main/java/it/gov/pagopa/wispconverter/controller/advice/GlobalExceptionHandler.java new file mode 100644 index 00000000..9faf0bff --- /dev/null +++ b/src/main/java/it/gov/pagopa/wispconverter/controller/advice/GlobalExceptionHandler.java @@ -0,0 +1,207 @@ +package it.gov.pagopa.wispconverter.controller.advice; + +import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; +import it.gov.pagopa.wispconverter.exception.AppException; +import it.gov.pagopa.wispconverter.util.Constants; +import it.gov.pagopa.wispconverter.util.aspect.LoggingAspect; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ProblemDetail; +import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.web.ErrorResponse; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; +import org.springframework.web.util.DefaultUriBuilderFactory; + +import java.net.URI; +import java.time.Instant; + +/** + * All Exceptions are handled by this class + */ +@RestControllerAdvice +@Slf4j +@RequiredArgsConstructor +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + + @Value("${error.code.uri}") + private String errorCodeUri; + private static final String ERROR_CODE_TITLE = "error-code.%s.title"; + private static final String ERROR_CODE_DETAIL = "error-code.%s.detail"; + + private final MessageSource messageSource; + + @ExceptionHandler(AppException.class) + public ErrorResponse handleAppException(AppException appEx) { + return forAppException(appEx); + } + + @ExceptionHandler(Exception.class) + public ErrorResponse handleGenericException(Exception ex) { + String operationId = MDC.get(LoggingAspect.OPERATION_ID); + log.error(String.format("GenericException: operation-id=[%s]", operationId!=null?operationId:"n/a"), ex); + return forAppException(new AppException(ex, AppErrorCodeMessageEnum.ERROR, ex.getMessage())); + } + + @Override + protected ResponseEntity handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatusCode statusCode, WebRequest request) { + if (body == null && ex instanceof ErrorResponse errorResponse) { + ProblemDetail problemDetail = errorResponse.updateAndGetBody(this.messageSource, LocaleContextHolder.getLocale()); + setExtraProperties(problemDetail); + body = problemDetail; + } + return super.handleExceptionInternal(ex, body, headers, statusCode, request); + } + + private ErrorResponse forAppException(AppException appEx){ + return ErrorResponse.builder(appEx, forAppErrorCodeMessageEnum(appEx.getError(), appEx.getMessage())) + .titleMessageCode(String.format(ERROR_CODE_TITLE, appEx.getError().name())) + .detailMessageCode(String.format(ERROR_CODE_DETAIL, appEx.getError().name())) + .detailMessageArguments(appEx.getArgs()) + .build(messageSource, LocaleContextHolder.getLocale()); + } + + private ProblemDetail forAppErrorCodeMessageEnum(AppErrorCodeMessageEnum error, @Nullable String detail) { + Assert.notNull(error, "AppErrorCodeMessageEnum is required"); + + ProblemDetail problemDetail = ProblemDetail.forStatus(error.getStatus()); + problemDetail.setType(getTypeFromErrorCode(getAppCode(error))); + problemDetail.setTitle(error.getTitle()); + problemDetail.setDetail(detail); + + problemDetail.setProperty("error-code", getAppCode(error)); + setExtraProperties(problemDetail); + + return problemDetail; + } + + private void setExtraProperties(ProblemDetail problemDetail){ + problemDetail.setProperty("timestamp", Instant.now()); + String operationId = MDC.get(LoggingAspect.OPERATION_ID); + if(operationId!=null){ + problemDetail.setProperty("operation-id", operationId); + } + } + private URI getTypeFromErrorCode(String errorCode) { + return new DefaultUriBuilderFactory() + .uriString(errorCodeUri) + .pathSegment(errorCode) + .build(); + } + + private String getAppCode(AppErrorCodeMessageEnum error){ + return String.format("%s-%s", Constants.SERVICE_CODE_APP, error.getCode()); + } + + +// +// @ApiResponses(value = { +// @ApiResponse(responseCode = "500", description = "Internal Server Error", content = { +// @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class), examples = {@ExampleObject( +// """ +// { +// "errorId": "68ce8c6a-6d53-486c-97fe-79430d24fb7d", +// "timestamp": "2023-10-09T08:01:39.421224Z", +// "httpStatusCode": 500, +// "httpStatusDescription": "Internal Server Error", +// "appErrorCode": "WIC-0500", +// "message": "An unexpected error has occurred. Please contact support" +// } +// """ +// )}) +// }), +// @ApiResponse(responseCode = "400", description = "Bad Request", content = { +// @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class), examples = {@ExampleObject( +// """ +// { +// "timestamp": "2023-10-09T07:53:14.077792Z", +// "httpStatusCode": 400, +// "httpStatusDescription": "Bad Request", +// "appErrorCode": "WIC-0400", +// "message": "Bad request", +// "errors": [ +// { +// "message": "Field error in ..." +// } +// ] +// } +// """ +// )}) +// }), +// @ApiResponse(responseCode = "404", description = "Not found", content = { +// @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class), examples = {@ExampleObject( +// """ +// { +// "timestamp": "2023-10-09T07:53:43.367312Z", +// "httpStatusCode": 404, +// "httpStatusDescription": "Not Found", +// "appErrorCode": "WIC-0404", +// "message": "Request POST /api/v1/..... not found" +// } +// """ +// )}) +// }) +// }) +// @ExceptionHandler({AppException.class, AppClientException.class}) +// public ResponseEntity handleAppException(AppException appEx) { +// Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, null); +// return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) +// .body(httpStatusApiErrorResponsePair.getRight()); +// } +// +// @Override +// protected ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { +// List errorMessages = ex.getBindingResult().getAllErrors().stream() +// .map(oe -> ApiErrorResponse.ErrorMessage.builder().message(oe.toString()).build()) +// .collect(Collectors.toList()); +// AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.BAD_REQUEST); +// Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, errorMessages); +// return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) +// .body(httpStatusApiErrorResponsePair.getRight()); +// } +// +// @ExceptionHandler(Exception.class) +// public ResponseEntity handleGenericException(Exception ex, WebRequest request) { +// String errorId = UUID.randomUUID().toString(); +// log.error(String.format("ExceptionHandler: ErrorId=[%s] %s", errorId, ex.getMessage()), ex); +// +// AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.ERROR); +// // errorId viene usato solo per i casi di eccezioni non gestite +// Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, errorId, null); +// return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) +// .body(httpStatusApiErrorResponsePair.getRight()); +// } +// +// @ExceptionHandler(ConstraintViolationException.class) +// public final ResponseEntity handleConstraintViolation(ConstraintViolationException ex, WebRequest request) { +// List errorMessages = ex.getConstraintViolations().stream() +// .map(oe -> ApiErrorResponse.ErrorMessage.builder().message(oe.getMessage()).build()) +// .collect(Collectors.toList()); +// AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.BAD_REQUEST); +// Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, errorMessages); +// return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) +// .body(httpStatusApiErrorResponsePair.getRight()); +// } +// +// @Override +// protected ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { +// List errorMessages = Stream.of(ex.getCause().getMessage()) +// .map(oe -> ApiErrorResponse.ErrorMessage.builder().message(oe).build()) +// .collect(Collectors.toList()); +// AppException appEx = new AppException(ex, AppErrorCodeMessageEnum.BAD_REQUEST); +// Pair httpStatusApiErrorResponsePair = appErrorUtil.buildApiErrorResponse(appEx, null, errorMessages); +// return ResponseEntity.status(httpStatusApiErrorResponsePair.getLeft()) +// .body(httpStatusApiErrorResponsePair.getRight()); +// } + +} diff --git a/src/main/java/it/gov/pagopa/wispconverter/controller/advice/model/ApiErrorResponse.java b/src/main/java/it/gov/pagopa/wispconverter/controller/advice/model/ApiErrorResponse.java deleted file mode 100644 index 9205a4c0..00000000 --- a/src/main/java/it/gov/pagopa/wispconverter/controller/advice/model/ApiErrorResponse.java +++ /dev/null @@ -1,65 +0,0 @@ -package it.gov.pagopa.wispconverter.controller.advice.model; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -import java.time.Instant; -import java.util.List; - -@Getter -@Builder -@JsonPropertyOrder({ - "errorId", - "timestamp", - "httpStatusCode", - "httpStatusDescription", - "appErrorCode", - "message", - "errors" -}) -@NoArgsConstructor -@AllArgsConstructor -public class ApiErrorResponse { - - @JsonInclude(JsonInclude.Include.NON_NULL) - @Schema(example = "50905466-1881-457b-b42f-fb7b2bfb1610", description = "This field exist only if status=500") - private String errorId; - - @Schema(example = "2023-10-05T11:22:57.494928Z", requiredMode = Schema.RequiredMode.REQUIRED) - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", timezone = "UTC") - private Instant timestamp; - - @Schema(example = "500", requiredMode = Schema.RequiredMode.REQUIRED) - private int httpStatusCode; - - @Schema(example = "Internal Server Error", requiredMode = Schema.RequiredMode.REQUIRED) - private String httpStatusDescription; - - @Schema(example = "WIC-0500", requiredMode = Schema.RequiredMode.REQUIRED) - private String appErrorCode; - - @Schema(example = "An unexpected error has occurred. Please contact support.", requiredMode = Schema.RequiredMode.REQUIRED) - private String message; - - @JsonInclude(JsonInclude.Include.NON_NULL) - private List errors; - - @Builder - @Getter - @Setter - @AllArgsConstructor - @NoArgsConstructor - @JsonPropertyOrder({"path", "message"}) - public static class ErrorMessage { - - @Schema(example = "object.field") - @JsonInclude(JsonInclude.Include.NON_NULL) - private String path; - - @Schema(example = "An unexpected error has occurred. Please contact support.", requiredMode = Schema.RequiredMode.REQUIRED) - private String message; - } -} diff --git a/src/main/java/it/gov/pagopa/wispconverter/exception/AppClientException.java b/src/main/java/it/gov/pagopa/wispconverter/exception/AppClientException.java deleted file mode 100644 index 174b09a1..00000000 --- a/src/main/java/it/gov/pagopa/wispconverter/exception/AppClientException.java +++ /dev/null @@ -1,16 +0,0 @@ -package it.gov.pagopa.wispconverter.exception; - -import lombok.Getter; - -import java.io.Serializable; - -@Getter -public class AppClientException extends AppException { - - private final int httpStatusCode; - - public AppClientException(int httpStatusCode, AppErrorCodeMessageEnum codeMessage, Serializable... args) { - super(codeMessage, args); - this.httpStatusCode = httpStatusCode; - } -} diff --git a/src/main/java/it/gov/pagopa/wispconverter/exception/AppErrorCodeMessageEnum.java b/src/main/java/it/gov/pagopa/wispconverter/exception/AppErrorCodeMessageEnum.java index c54cc0a0..fafabf9f 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/exception/AppErrorCodeMessageEnum.java +++ b/src/main/java/it/gov/pagopa/wispconverter/exception/AppErrorCodeMessageEnum.java @@ -2,30 +2,28 @@ import lombok.Getter; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; @Getter public enum AppErrorCodeMessageEnum { - UNKNOWN("0000", "UNKNOWN.error", HttpStatus.INTERNAL_SERVER_ERROR), - ERROR("0500", "system.error", HttpStatus.INTERNAL_SERVER_ERROR), - BAD_REQUEST("0400", "bad.request", HttpStatus.BAD_REQUEST), - - PARSING_("1000", "", HttpStatus.BAD_REQUEST), - PARSING_JAXB_EMPTY_NODE_ELEMENT("1001", "jaxb.node-element.empty", HttpStatus.BAD_REQUEST), - PARSING_JAXB_PARSE_ERROR("1002", "jaxb.parse", HttpStatus.BAD_REQUEST), - - PERSISTENCE_("2000", "", HttpStatus.BAD_REQUEST), - - CLIENT_("3000", "", HttpStatus.BAD_REQUEST), - + ERROR ( 500, "System error", "{0}", HttpStatus.INTERNAL_SERVER_ERROR), + PARSE_ERROR (1000, "Parse error", "Error while parsing: {0}", HttpStatus.BAD_REQUEST), + PRIMITIVE_NOT_VALID (1001, "Primitive not valid", "Primitive [{0}] not valid", HttpStatus.NOT_ACCEPTABLE), + RPT_NOT_FOUND (1002, "RPT not found", "RPT with sessionId [{0}] not found", HttpStatus.NOT_FOUND), + CLIENT_IUV_GENERATOR (1003, "IUVGeneratorClient error", "IUVGeneratorClient status [{0}] - {1}", HttpStatus.EXPECTATION_FAILED), + CLIENT_GPD (1004, "GPDClient error", "GPDClient status [{0}] - {1}", HttpStatus.EXPECTATION_FAILED), + CLIENT_DECOUPLER_CACHING(1005, "DecouplerCachingClient error", "DecouplerCachingClient status [{0}] - {1}",HttpStatus.EXPECTATION_FAILED), ; - private final String errorCode; - private final String errorMessageKey; - private final HttpStatus httpStatus; + private final Integer code; + private final String title; + private final String detail; + private final HttpStatusCode status; - AppErrorCodeMessageEnum(String errorCode, String errorMessageKey, HttpStatus httpStatus) { - this.errorCode = errorCode; - this.errorMessageKey = errorMessageKey; - this.httpStatus = httpStatus; + AppErrorCodeMessageEnum(Integer code, String title, String detail, HttpStatus status) { + this.code = code; + this.title = title; + this.detail = detail; + this.status = status; } } diff --git a/src/main/java/it/gov/pagopa/wispconverter/exception/AppException.java b/src/main/java/it/gov/pagopa/wispconverter/exception/AppException.java index 66533eea..36244c9c 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/exception/AppException.java +++ b/src/main/java/it/gov/pagopa/wispconverter/exception/AppException.java @@ -1,25 +1,40 @@ package it.gov.pagopa.wispconverter.exception; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; -import java.io.Serializable; +import java.text.MessageFormat; @Getter public class AppException extends RuntimeException { - private final transient AppErrorCodeMessageEnum codeMessage; - + private final AppErrorCodeMessageEnum error; private final transient Object[] args; +// private final String detail; + + public AppException(AppErrorCodeMessageEnum error, Object... args) { + super(composeMessage(error, getArgsOrNull(args))); + this.error = error; + this.args = getArgsOrNull(args); +// this.detail = composeMessage(error, getArgsOrNull(args)); + } - public AppException(Throwable cause, AppErrorCodeMessageEnum codeMessage, Serializable... args) { - super(cause); - this.codeMessage = codeMessage; - this.args = args.length > 0 ? args.clone() : null; + public AppException(Throwable cause, AppErrorCodeMessageEnum error, Object... args) { + super(composeMessage(error, getArgsOrNull(args)), cause); + this.error = error; + this.args = getArgsOrNull(args); +// this.detail = composeMessage(error, getArgsOrNull(args)); } - public AppException(AppErrorCodeMessageEnum codeMessage, Serializable... args) { - super(); - this.codeMessage = codeMessage; - this.args = args.length > 0 ? args.clone() : null; + private static Object[] getArgsOrNull(Object... args) { + return args.length > 0 ? args.clone() : null; } -} + + private static String composeMessage(AppErrorCodeMessageEnum error, Object[] args){ + if(error.getDetail() != null){ + return MessageFormat.format(error.getDetail(), args); + } + return null; + } + +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/wispconverter/service/CacheService.java b/src/main/java/it/gov/pagopa/wispconverter/service/CacheService.java index c86b31b4..45e14f36 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/service/CacheService.java +++ b/src/main/java/it/gov/pagopa/wispconverter/service/CacheService.java @@ -3,7 +3,6 @@ import feign.FeignException; import io.lettuce.core.RedisException; import it.gov.pagopa.wispconverter.client.decoupler.DecouplerCachingClient; -import it.gov.pagopa.wispconverter.exception.AppClientException; import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; import it.gov.pagopa.wispconverter.exception.AppException; import it.gov.pagopa.wispconverter.repository.CacheRepository; @@ -34,7 +33,6 @@ public class CacheService { public void storeRequestMappingInCache(List rptContentDTOs, String sessionId) { try { - rptContentDTOs.forEach(e -> { String idIntermediarioPA = e.getIdIntermediarioPA(); String noticeNumber = e.getNoticeNumber(); @@ -46,12 +44,8 @@ public void storeRequestMappingInCache(List rptContentDTOs, Strin String requestIDForRTHandling = String.format(CACHING_KEY_TEMPLATE, idIntermediarioPA, noticeNumber); this.cacheRepository.insert(requestIDForRTHandling, sessionId, this.requestIDMappingTTL); }); - - } catch (FeignException e) { - throw new AppClientException(e.status(), AppErrorCodeMessageEnum.CLIENT_); - } catch (RedisException e) { - throw new AppException(AppErrorCodeMessageEnum.PERSISTENCE_); + throw new AppException(e, AppErrorCodeMessageEnum.CLIENT_DECOUPLER_CACHING, e.status(), e.getMessage()); } } } diff --git a/src/main/java/it/gov/pagopa/wispconverter/service/ConverterService.java b/src/main/java/it/gov/pagopa/wispconverter/service/ConverterService.java index b3206759..1257d3d0 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/service/ConverterService.java +++ b/src/main/java/it/gov/pagopa/wispconverter/service/ConverterService.java @@ -1,7 +1,5 @@ package it.gov.pagopa.wispconverter.service; -import com.azure.cosmos.CosmosException; -import com.azure.spring.data.cosmos.exception.CosmosAccessException; import gov.telematici.pagamenti.ws.NodoInviaCarrelloRPT; import gov.telematici.pagamenti.ws.NodoInviaRPT; import gov.telematici.pagamenti.ws.ppthead.IntestazioneCarrelloPPT; @@ -90,12 +88,9 @@ private PaymentPosition mapRPTToDebtPosition(RPTRequestDTO rptRequestDTO, RPTCon } private RPTRequestEntity getRPTRequestEntity(String sessionId) { - try { - Optional optRPTReqEntity = this.rptRequestRepository.findById(sessionId); - return optRPTReqEntity.orElseThrow(() -> new AppException(AppErrorCodeMessageEnum.PERSISTENCE_)); - } catch (CosmosException | CosmosAccessException e) { - throw new AppException(AppErrorCodeMessageEnum.PERSISTENCE_); - } + Optional optRPTReqEntity = this.rptRequestRepository.findById(sessionId); + return optRPTReqEntity.orElseThrow(() -> new AppException(AppErrorCodeMessageEnum.RPT_NOT_FOUND, sessionId)); + // TODO RE } @@ -135,7 +130,7 @@ private List getRPTContentDTO(String primitive, String payload) t .build(); }).toList(); } - default -> throw new AppException(AppErrorCodeMessageEnum.PARSING_); + default -> throw new AppException(AppErrorCodeMessageEnum.PRIMITIVE_NOT_VALID, primitive); } } diff --git a/src/main/java/it/gov/pagopa/wispconverter/service/DebtPositionService.java b/src/main/java/it/gov/pagopa/wispconverter/service/DebtPositionService.java index d5e6d17c..59b544ac 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/service/DebtPositionService.java +++ b/src/main/java/it/gov/pagopa/wispconverter/service/DebtPositionService.java @@ -4,8 +4,8 @@ import it.gov.pagopa.wispconverter.client.gpd.GPDClient; import it.gov.pagopa.wispconverter.client.gpd.model.MultiplePaymentPosition; import it.gov.pagopa.wispconverter.client.gpd.model.PaymentPosition; -import it.gov.pagopa.wispconverter.exception.AppClientException; import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; +import it.gov.pagopa.wispconverter.exception.AppException; import it.gov.pagopa.wispconverter.service.mapper.DebtPositionMapper; import it.gov.pagopa.wispconverter.service.model.RPTContentDTO; import lombok.RequiredArgsConstructor; @@ -43,7 +43,7 @@ public void executeBulkCreation(List rptContentDTOs) { }); } catch (FeignException e) { - throw new AppClientException(e.status(), AppErrorCodeMessageEnum.CLIENT_); + throw new AppException(e, AppErrorCodeMessageEnum.CLIENT_GPD, e.status(), e.getMessage()); } } diff --git a/src/main/java/it/gov/pagopa/wispconverter/service/NAVGeneratorService.java b/src/main/java/it/gov/pagopa/wispconverter/service/NAVGeneratorService.java index 9e04c80e..23c16df2 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/service/NAVGeneratorService.java +++ b/src/main/java/it/gov/pagopa/wispconverter/service/NAVGeneratorService.java @@ -4,7 +4,6 @@ import it.gov.pagopa.wispconverter.client.iuvgenerator.IUVGeneratorClient; import it.gov.pagopa.wispconverter.client.iuvgenerator.model.IUVGeneratorRequest; import it.gov.pagopa.wispconverter.client.iuvgenerator.model.IUVGeneratorResponse; -import it.gov.pagopa.wispconverter.exception.AppClientException; import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; import it.gov.pagopa.wispconverter.exception.AppException; import lombok.RequiredArgsConstructor; @@ -35,13 +34,9 @@ public String getNAVCodeFromIUVGenerator(String creditorInstitutionCode) { String navCode; try { IUVGeneratorResponse response = this.iuvGeneratorClient.generate(creditorInstitutionCode, request); - if (response == null) { - throw new AppException(AppErrorCodeMessageEnum.CLIENT_); - } - navCode = response.getIuv(); + return response.getIuv(); } catch (FeignException e) { - throw new AppClientException(e.status(), AppErrorCodeMessageEnum.CLIENT_); + throw new AppException(e, AppErrorCodeMessageEnum.CLIENT_IUV_GENERATOR, e.status(), e.getMessage()); } - return navCode; } } diff --git a/src/main/java/it/gov/pagopa/wispconverter/util/AppErrorUtil.java b/src/main/java/it/gov/pagopa/wispconverter/util/AppErrorUtil.java index ef197eb6..4cd1f308 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/util/AppErrorUtil.java +++ b/src/main/java/it/gov/pagopa/wispconverter/util/AppErrorUtil.java @@ -1,38 +1,41 @@ -package it.gov.pagopa.wispconverter.util; - -import it.gov.pagopa.wispconverter.controller.advice.model.ApiErrorResponse; -import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; -import it.gov.pagopa.wispconverter.exception.AppException; -import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.tuple.Pair; -import org.springframework.context.MessageSource; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; - -import java.time.Instant; -import java.util.List; -import java.util.Locale; - -@Component -@RequiredArgsConstructor -public class AppErrorUtil { - private final MessageSource messageSource; - - public Pair buildApiErrorResponse(AppException appEx, String errorId, List errorMessageList) { - Locale locale = LocaleContextHolder.getLocale(); - AppErrorCodeMessageEnum codeMessage = appEx.getCodeMessage(); - HttpStatus status = codeMessage.getHttpStatus(); - String errorMessageKey = codeMessage.getErrorMessageKey(); - - return Pair.of(status, ApiErrorResponse.builder() - .errorId(errorId) - .timestamp(Instant.now()) - .httpStatusCode(status.value()) - .httpStatusDescription(status.getReasonPhrase()) - .appErrorCode(String.format("%s-%s", Constants.SERVICE_CODE_APP, codeMessage.getErrorCode())) - .message(messageSource.getMessage(errorMessageKey, appEx.getArgs(), locale)) - .errors(errorMessageList) - .build()); - } -} +//package it.gov.pagopa.wispconverter.util; +// +//import it.gov.pagopa.wispconverter.controller.advice.model.ApiErrorResponse; +//import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; +//import it.gov.pagopa.wispconverter.exception.AppException; +//import lombok.RequiredArgsConstructor; +//import org.apache.commons.lang3.tuple.Pair; +//import org.springframework.context.MessageSource; +//import org.springframework.context.i18n.LocaleContextHolder; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ProblemDetail; +//import org.springframework.stereotype.Component; +//import org.springframework.web.ErrorResponse; +// +//import java.time.Instant; +//import java.util.List; +//import java.util.Locale; +// +//@Component +//@RequiredArgsConstructor +//public class AppErrorUtil { +// private final MessageSource messageSource; +// +// public Pair buildApiErrorResponse(AppException appEx, String errorId, List errorMessageList) { +// Locale locale = LocaleContextHolder.getLocale(); +// AppErrorCodeMessageEnum codeMessage = appEx.getCodeMessage(); +// HttpStatus status = codeMessage.getHttpStatus(); +// String errorMessageKey = codeMessage.getErrorMessageKey(); +// +// return Pair.of(status, ApiErrorResponse.builder() +// .errorId(errorId) +// .timestamp(Instant.now()) +// .httpStatusCode(status.value()) +// .httpStatusDescription(status.getReasonPhrase()) +// .appErrorCode(String.format("%s-%s", Constants.SERVICE_CODE_APP, codeMessage.getErrorCode())) +// .message(messageSource.getMessage(errorMessageKey, appEx.getArgs(), locale)) +// .errors(errorMessageList) +// .build()); +// } +// +//} diff --git a/src/main/java/it/gov/pagopa/wispconverter/util/JaxbElementUtil.java b/src/main/java/it/gov/pagopa/wispconverter/util/JaxbElementUtil.java index b078e6f8..aa0111ae 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/util/JaxbElementUtil.java +++ b/src/main/java/it/gov/pagopa/wispconverter/util/JaxbElementUtil.java @@ -45,12 +45,11 @@ private Element convertToElement(InputSource is, String nameSpaceUri, String loc Document doc = db.parse(is); NodeList nodeList = doc.getElementsByTagNameNS(nameSpaceUri, localName); if (nodeList.getLength() == 0) { - throw new AppException(AppErrorCodeMessageEnum.PARSING_JAXB_EMPTY_NODE_ELEMENT, 0); + throw new AppException(AppErrorCodeMessageEnum.PARSE_ERROR, "NodeList must be > 0"); } return (Element) nodeList.item(0); } catch (ParserConfigurationException | IOException | SAXException e) { - log.error("Errore durante il parsing", e); - throw new AppException(e, AppErrorCodeMessageEnum.PARSING_JAXB_PARSE_ERROR, e.getMessage()); + throw new AppException(e, AppErrorCodeMessageEnum.PARSE_ERROR, e.getMessage()); } } @@ -61,8 +60,7 @@ public T convertToBean(Element element, Class targetType) { JAXBElement jaxbElement = unmarshaller.unmarshal(element, targetType); return jaxbElement.getValue(); } catch (JAXBException e) { - log.error("Errore durante unmarshal", e); - throw new AppException(AppErrorCodeMessageEnum.PARSING_, e, e.getMessage()); + throw new AppException(e, AppErrorCodeMessageEnum.PARSE_ERROR, e.getMessage()); } } @@ -79,12 +77,12 @@ public Element convertToRPTElement(byte[] source) { public T getSoapHeader(Envelope envelope, Class targetType) { Header header = envelope.getHeader(); if (header == null) { - throw new AppException(AppErrorCodeMessageEnum.PARSING_, "header is null"); + throw new AppException(AppErrorCodeMessageEnum.PARSE_ERROR, "header is null"); } List list = header.getAny(); if (list == null || list.isEmpty()) { - throw new AppException(AppErrorCodeMessageEnum.PARSING_, "headerValue is null or is empty"); + throw new AppException(AppErrorCodeMessageEnum.PARSE_ERROR, "headerValue is null or is empty"); } Element element = (Element) list.get(0); return convertToBean(element, targetType); @@ -93,12 +91,12 @@ public T getSoapHeader(Envelope envelope, Class targetType) { public T getSoapBody(Envelope envelope, Class targetType) { Body body = envelope.getBody(); if (body == null) { - throw new AppException(AppErrorCodeMessageEnum.PARSING_, "body is null"); + throw new AppException(AppErrorCodeMessageEnum.PARSE_ERROR, "body is null"); } List list = body.getAny(); if (list == null || list.isEmpty()) { - throw new AppException(AppErrorCodeMessageEnum.PARSING_, "bodyValue is null or is empty"); + throw new AppException(AppErrorCodeMessageEnum.PARSE_ERROR, "bodyValue is null or is empty"); } Element element = (Element) list.get(0); return convertToBean(element, targetType); diff --git a/src/main/java/it/gov/pagopa/wispconverter/util/aspect/LoggingAspect.java b/src/main/java/it/gov/pagopa/wispconverter/util/aspect/LoggingAspect.java index c3fe6265..2a2612d5 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/util/aspect/LoggingAspect.java +++ b/src/main/java/it/gov/pagopa/wispconverter/util/aspect/LoggingAspect.java @@ -1,23 +1,19 @@ package it.gov.pagopa.wispconverter.util.aspect; -import it.gov.pagopa.wispconverter.controller.advice.model.ApiErrorResponse; -import it.gov.pagopa.wispconverter.exception.AppErrorCodeMessageEnum; import jakarta.annotation.PostConstruct; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.AfterReturning; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.CodeSignature; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +import org.springframework.web.ErrorResponse; import java.util.HashMap; import java.util.Map; @@ -57,16 +53,20 @@ public class LoggingAspect { @Value("${info.properties.environment}") private String environment; - private static String getDetail(ResponseEntity result) { - if (result != null && result.getBody() != null && result.getBody().getMessage() != null) { - return result.getBody().getMessage(); - } else return AppErrorCodeMessageEnum.UNKNOWN.getErrorCode(); + private static String getDetail(ResponseEntity result) { + String detail; + if (result != null && result.getBody() != null && result.getBody().getBody().getDetail() != null) { + return result.getBody().getBody().getDetail(); + } + return null; } - private static String getTitle(ResponseEntity result) { - if (result != null && result.getBody() != null && result.getBody().getAppErrorCode() != null) { - return result.getBody().getAppErrorCode(); - } else return AppErrorCodeMessageEnum.UNKNOWN.getErrorCode(); + private static String getTitle(ResponseEntity result) { + String title; + if (result != null && result.getBody() != null && result.getBody().getBody().getTitle() != null) { + return result.getBody().getBody().getTitle(); + } + return null; } public static String getExecutionTime() { @@ -140,7 +140,7 @@ public Object logApiInvocation(ProceedingJoinPoint joinPoint) throws Throwable { } @AfterReturning(value = "execution(* *..exception.ErrorHandler.*(..))", returning = "result") - public void trowingApiInvocation(JoinPoint joinPoint, ResponseEntity result) { + public void trowingApiInvocation(JoinPoint joinPoint, ResponseEntity result) { MDC.put(STATUS, "KO"); MDC.put(CODE, String.valueOf(result.getStatusCode().value())); MDC.put(RESPONSE_TIME, getExecutionTime()); diff --git a/src/main/java/it/gov/pagopa/wispconverter/util/aspect/ResponseValidator.java b/src/main/java/it/gov/pagopa/wispconverter/util/aspect/ResponseValidator.java index 3373102d..e7049034 100644 --- a/src/main/java/it/gov/pagopa/wispconverter/util/aspect/ResponseValidator.java +++ b/src/main/java/it/gov/pagopa/wispconverter/util/aspect/ResponseValidator.java @@ -45,7 +45,7 @@ private void validateResponse(ResponseEntity response) { sb.append(error.getPropertyPath()).append(" ").append(error.getMessage()).append(". "); } var msg = StringUtils.chop(sb.toString()); - throw new AppException(AppErrorCodeMessageEnum.ERROR, "Invalid response", msg); + throw new AppException(AppErrorCodeMessageEnum.ERROR, msg); } } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 06ec121a..0fd3c566 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -5,6 +5,9 @@ info.application.version=@project.version@ info.application.description=@project.description@ info.properties.environment=${ENV:azure} +## mange all error +#spring.mvc.throw-exception-if-no-handler-found=true + # Actuator management.endpoints.web.exposure.include=health,info management.endpoints.jmx.exposure.include=health,info @@ -61,3 +64,5 @@ client.decoupler-caching.subscription-key=${CLIENT_DECOUPLERCACHING_SUBKEY:none} wisp-converter.aux-digit=3 wisp-converter.segregation-code=48 wisp-converter.cached-requestid-mapping.ttl.minutes=${CACHED_REQUESTID_MAPPING_TTL_MINUTES:1440} + +error.code.uri=${ERROR_CODE_URI:https://pagopa.gov/error-code} diff --git a/src/main/resources/i18n/messages_en.properties b/src/main/resources/i18n/messages_en.properties new file mode 100644 index 00000000..b3ef1a20 --- /dev/null +++ b/src/main/resources/i18n/messages_en.properties @@ -0,0 +1,22 @@ +error-code.ERROR.title=System error +error-code.ERROR.detail=An unexpected error has occurred. Please contact support + +error-code.PARSE_ERROR.title=Parse error +error-code.PARSE_ERROR.detail=Error while parsing: {0} + +error-code.PRIMITIVE_NOT_VALID.title=Primitive not valid +error-code.PRIMITIVE_NOT_VALID.detail=Primitive [{0}] not valid + +error-code.RPT_NOT_FOUND.title=RPT not found +error-code.RPT_NOT_FOUND.detail=RPT with sessionId [{0}] not found + +error-code.CLIENT_IUV_GENERATOR.title=IUVGeneratorClient error +error-code.CLIENT_IUV_GENERATOR.detail=IUVGeneratorClient status [{0}] - {1} + +error-code.CLIENT_GPD.title=GPDClient error +error-code.CLIENT_GPD.detail=GPDClient status [{0}] - {1} + +error-code.CLIENT_DECOUPLER_CACHING.title=DecouplerCachingClient error +error-code.CLIENT_DECOUPLER_CACHING.detail=DecouplerCachingClient status [{0}] - {1} + + diff --git a/src/main/resources/i18n/messages_it.properties b/src/main/resources/i18n/messages_it.properties new file mode 100644 index 00000000..e4c8bd1f --- /dev/null +++ b/src/main/resources/i18n/messages_it.properties @@ -0,0 +1,20 @@ +error-code.ERROR.title=Errore del sistema +error-code.ERROR.detail=Si è verificato un errore imprevisto. Si prega di contattare l'assistenza + +error-code.PARSE_ERROR.title=Errore di lettura +error-code.PARSE_ERROR.detail=Errore durante la lettura: {0} + +error-code.PRIMITIVE_NOT_VALID.title=Primitiva non valida +error-code.PRIMITIVE_NOT_VALID.detail=Primitiva [{0}] non valida + +error-code.RPT_NOT_FOUND.title=RPT non trovata +error-code.RPT_NOT_FOUND.detail=RPT con sessionId [{0}] non trovata + +error-code.CLIENT_IUV_GENERATOR.title=Errore IUVGeneratorClient +error-code.CLIENT_IUV_GENERATOR.detail=IUVGeneratorClient status [{0}] - {1} + +error-code.CLIENT_GPD.title=Errore GPDClient +error-code.CLIENT_GPD.detail=GPDClient status [{0}] - {1} + +error-code.CLIENT_DECOUPLER_CACHING.title=Errore DecouplerCachingClient +error-code.CLIENT_DECOUPLER_CACHING.detail=DecouplerCachingClient status [{0}] - {1} \ No newline at end of file diff --git a/src/main/resources/messages/messages_en.properties b/src/main/resources/messages/messages_en.properties deleted file mode 100644 index 01039953..00000000 --- a/src/main/resources/messages/messages_en.properties +++ /dev/null @@ -1,5 +0,0 @@ -system.error=An unexpected error has occurred. Please contact support -bad.request=Bad request -jaxb.node-element.empty=JAXB conversion error. Found {0} node -jaxb.parse=JAXB parsing error. {0} -redirect.session-id.not-blank=SessionID passed in request must be not-blank. \ No newline at end of file diff --git a/src/main/resources/messages/messages_it.properties b/src/main/resources/messages/messages_it.properties deleted file mode 100644 index f4e4dbf2..00000000 --- a/src/main/resources/messages/messages_it.properties +++ /dev/null @@ -1,5 +0,0 @@ -system.error=Si è verificato un errore imprevisto. Si prega di contattare l'assistenza -bad.request=Richiesta errata -jaxb.node-element.empty=Errore di conversione JAXB. Trovati {0} nodi -jaxb.parse=Errore di parsing JAXB. {0} -redirect.session-id.not-blank=Il SessionID passato nella richiesta deve essere una stringa non vuota. \ No newline at end of file