Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: P4PU-289 added custom exception for pull payment #41

Merged
merged 7 commits into from
Jul 31, 2024
33 changes: 27 additions & 6 deletions openapi/pagopa-arc-be.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,17 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/TransactionsListDTO'
'400':
description: "Invalid Request"
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDTO'
example:
error: invalid_amount
error_description: "Invalid amount format"
'401':
description: "Wrong or missing function key"
'429':
description: "Too many Requests"
'500':
description: "Service unavailable"
content:
Expand All @@ -140,6 +147,15 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/TransactionDetailsDTO'
'400':
description: "Invalid Request"
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDTO'
example:
error: invalid_amount
error_description: "Invalid amount format"
'401':
description: "Wrong or missing function key"
'404':
Expand All @@ -151,8 +167,6 @@ paths:
example:
error: "transaction_not_found_error"
error_description: "string"
'429':
description: "Too many Requests"
'500':
description: "Service unavailable"
content:
Expand Down Expand Up @@ -191,8 +205,6 @@ paths:
example:
error: "receipt_not_found_error"
error_description: "string"
'429':
description: "Too many Requests"
'500':
description: "Service unavailable"
content:
Expand Down Expand Up @@ -237,6 +249,15 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/PaymentNoticesListDTO'
'400':
description: "Invalid Request"
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDTO'
example:
error: invalid_request
error_description: "One or more inputs provided during the request from pull payment are invalid"
'401':
description: "Wrong or missing function key"
'500':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import it.gov.pagopa.arc.exception.custom.BizEventsInvocationException;
import it.gov.pagopa.arc.exception.custom.BizEventsReceiptNotFoundException;
import it.gov.pagopa.arc.exception.custom.BizEventsTransactionNotFoundException;
import it.gov.pagopa.arc.utils.Utilities;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
Expand Down Expand Up @@ -45,6 +46,7 @@ public BizEventsTransactionsListDTO getTransactionsList(String fiscalCode, int s
e.status(),
e.getMessage());
}else {
Utilities.logExceptionDetails(e);
throw new BizEventsInvocationException(ERROR_MESSAGE_INVOCATION_EXCEPTION);
}
}
Expand All @@ -60,6 +62,7 @@ public BizEventsTransactionDetailsDTO getTransactionDetails(String fiscalCode, S
if(e.status() == HttpStatus.NOT_FOUND.value()){
throw new BizEventsTransactionNotFoundException("An error occurred handling request from biz-Events to retrieve transaction with transaction id [%s] for the current user".formatted(transactionId));
}
Utilities.logExceptionDetails(e);
throw new BizEventsInvocationException(ERROR_MESSAGE_INVOCATION_EXCEPTION);
}
return bizEventsTransactionDetailsDTO;
Expand All @@ -74,6 +77,7 @@ public Resource getTransactionReceipt(String fiscalCode, String transactionId) {
if (e.status() == HttpStatus.NOT_FOUND.value()){
throw new BizEventsReceiptNotFoundException("An error occurred handling request from biz-Events to retrieve transaction receipt with transaction id [%s] for the current user".formatted(transactionId));
}
Utilities.logExceptionDetails(e);
throw new BizEventsInvocationException(ERROR_MESSAGE_INVOCATION_EXCEPTION);
}
return transactionReceipt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import feign.FeignException;
import it.gov.pagopa.arc.connector.pullpayment.dto.PullPaymentNoticeDTO;
import it.gov.pagopa.arc.exception.custom.PullPaymentInvalidRequestException;
import it.gov.pagopa.arc.exception.custom.PullPaymentInvocationException;
import it.gov.pagopa.arc.utils.Utilities;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -35,9 +38,11 @@ public List<PullPaymentNoticeDTO> getPaymentNotices(String fiscalCode, LocalDate
e.getClass(),
e.status(),
e.getMessage());
} else if(e.status() == HttpStatus.BAD_REQUEST.value()) {
throw new PullPaymentInvalidRequestException("One or more inputs provided during the request from pull payment are invalid");
}else{
//replace this exception with Custom exception
throw new RuntimeException("An error occurred handling request from pull payment service;");
Utilities.logExceptionDetails(e);
throw new PullPaymentInvocationException("An error occurred handling request from pull payment service");
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ public ResponseEntity<ErrorDTO> handleBizEventsInvalidDateException(RuntimeExcep
return handleArcErrorException(ex, request, HttpStatus.BAD_REQUEST, ErrorDTO.ErrorEnum.INVALID_DATE);
}

@ExceptionHandler(PullPaymentInvalidRequestException.class)
public ResponseEntity<ErrorDTO> handlePullPaymentInvalidRequestException(RuntimeException ex, HttpServletRequest request){
return handleArcErrorException(ex, request, HttpStatus.BAD_REQUEST, ErrorDTO.ErrorEnum.INVALID_REQUEST);
}

@ExceptionHandler(PullPaymentInvocationException.class)
public ResponseEntity<ErrorDTO> handlePullPaymentInvocationException(RuntimeException ex, HttpServletRequest request){
return handleArcErrorException(ex, request, HttpStatus.INTERNAL_SERVER_ERROR, ErrorDTO.ErrorEnum.GENERIC_ERROR);
}

private static ResponseEntity<ErrorDTO> handleArcErrorException(RuntimeException ex, HttpServletRequest request, HttpStatus httpStatus, ErrorDTO.ErrorEnum errorEnum) {
String message = ex.getMessage();
log.info("A {} occurred handling request {}: HttpStatus {} - {}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package it.gov.pagopa.arc.exception.custom;

import lombok.Getter;

@Getter
public class PullPaymentInvalidRequestException extends RuntimeException{
public PullPaymentInvalidRequestException(String message){super(message);}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package it.gov.pagopa.arc.exception.custom;

import lombok.Getter;

@Getter
public class PullPaymentInvocationException extends RuntimeException{

public PullPaymentInvocationException(String message){super(message);}
}
11 changes: 11 additions & 0 deletions src/main/java/it/gov/pagopa/arc/utils/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import it.gov.pagopa.arc.exception.custom.BizEventsInvalidAmountException;
import it.gov.pagopa.arc.exception.custom.BizEventsInvalidDateException;
import lombok.extern.slf4j.Slf4j;

import java.text.NumberFormat;
import java.text.ParseException;
Expand All @@ -11,6 +12,7 @@
import java.time.format.DateTimeParseException;
import java.util.Locale;

@Slf4j
public class Utilities {
private Utilities(){}

Expand Down Expand Up @@ -40,4 +42,13 @@ public static ZonedDateTime dateStringToZonedDateTime(String dateString){
throw new BizEventsInvalidDateException("Invalid date format");
}
}

/**
* To log the full error stack
*
* @param ex exception to log
*/
public static void logExceptionDetails(RuntimeException ex){
log.error("Exception occurred: {} - {}", ex.getClass().getSimpleName(), ex.getMessage(), ex);
}
}
56 changes: 56 additions & 0 deletions src/test/java/it/gov/pagopa/arc/config/WireMockConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package it.gov.pagopa.arc.config;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.test.context.support.TestPropertySourceUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class WireMockConfig {
public static final String WIREMOCK_TEST_PROP2BASEPATH_MAP_PREFIX = "wireMock-test.prop2basePath.";
private static final Map<String,String> propertiesMap = new HashMap<>();

public static class WireMockInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
WireMockServer wireMockServer = new WireMockServer(new WireMockConfiguration().usingFilesUnderClasspath("src/test/resources/stub").dynamicPort());
wireMockServer.start();

applicationContext.getBeanFactory().registerSingleton("wireMockServer", wireMockServer);
applicationContext.addApplicationListener(
applicationEvent -> {
if (applicationEvent instanceof ContextClosedEvent) {
wireMockServer.stop();
}
});

applicationContext.getEnvironment().getPropertySources().stream()
.filter(propertySource -> propertySource instanceof EnumerablePropertySource)
.map(propertySource -> (EnumerablePropertySource<?>) propertySource)
.flatMap(propertySource -> Arrays.stream(propertySource.getPropertyNames()))
.forEach(key -> {
if (key.startsWith(WIREMOCK_TEST_PROP2BASEPATH_MAP_PREFIX)) {
propertiesMap.put(key.substring(WIREMOCK_TEST_PROP2BASEPATH_MAP_PREFIX.length()), applicationContext.getEnvironment().getProperty(key));
}
});

for (Map.Entry<String, String> entry : propertiesMap.entrySet()) {
setWireMockBaseMockedServicePath(applicationContext,wireMockServer.baseUrl(),entry);
}

}
}

private static void setWireMockBaseMockedServicePath(ConfigurableApplicationContext applicationContext, String serverWireMock,Map.Entry<String, String> entry){
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,String.format("%s=%s/%s",entry.getKey(),serverWireMock,entry.getValue()));
}
}
Loading