From 83603b5d4fe4e766eb2748195487a6154465c036 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 10:39:36 +0200 Subject: [PATCH 01/19] [PPANTT-81] feat: Introduced service for creditor institution newVerify Rest calls --- .../options/clients/ApiConfigCacheClient.java | 2 +- .../CreditorInstitutionRestClient.java | 30 ++++++ ...reditorInstitutionRestClientInterface.java | 21 +++++ .../consumers/ConfigCacheUpdatesConsumer.java | 3 +- .../options/exception/AppErrorException.java | 15 +++ .../exception/PaymentOptionsException.java | 50 ++++++++++ .../exception/mapper/ExceptionMapper.java | 76 +++++++++++++++ .../options/models/ConfigCacheData.java | 2 +- .../payment/options/models/ErrorResponse.java | 31 +++++++ .../cache}/BrokerCreditorInstitution.java | 6 +- .../clients/cache}/ConfigDataV1.java | 2 +- .../clients/cache}/Connection.java | 2 +- .../clients/cache}/CreditorInstitution.java | 2 +- .../cache}/CreditorInstitutionAddress.java | 2 +- .../model => models/clients/cache}/Proxy.java | 5 +- .../clients/cache}/Redirect.java | 5 +- .../clients/cache}/Service.java | 5 +- .../clients/cache}/Station.java | 11 ++- .../cache}/StationCreditorInstitution.java | 2 +- .../clients/cache}/Timeouts.java | 2 +- .../PaymentOptionsRequest.java | 24 +++++ .../PaymentOptionsResponse.java | 5 + .../clients/creditorInstitution/QrCode.java | 19 ++++ .../models/enums/AppErrorCodeEnum.java | 30 ++++++ .../models/{ => events}/CacheUpdateEvent.java | 2 +- .../options/services/ConfigCacheService.java | 5 +- .../services/CreditorInstitutionService.java | 92 +++++++++++++++++++ .../ConfigCacheUpdatesConsumerTest.java | 2 +- .../services/ConfigCacheServiceTest.java | 5 +- 29 files changed, 419 insertions(+), 39 deletions(-) create mode 100644 src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/exception/PaymentOptionsException.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/BrokerCreditorInstitution.java (72%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/ConfigDataV1.java (98%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/Connection.java (94%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/CreditorInstitution.java (93%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/CreditorInstitutionAddress.java (91%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/Proxy.java (73%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/Redirect.java (85%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/Service.java (73%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/Station.java (84%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/StationCreditorInstitution.java (94%) rename src/main/java/it/gov/pagopa/payment/options/{clients/model => models/clients/cache}/Timeouts.java (89%) create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/enums/AppErrorCodeEnum.java rename src/main/java/it/gov/pagopa/payment/options/models/{ => events}/CacheUpdateEvent.java (85%) create mode 100644 src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/ApiConfigCacheClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/ApiConfigCacheClient.java index aadc946..0f87393 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/ApiConfigCacheClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/ApiConfigCacheClient.java @@ -1,6 +1,6 @@ package it.gov.pagopa.payment.options.clients; -import it.gov.pagopa.payment.options.clients.model.ConfigDataV1; +import it.gov.pagopa.payment.options.models.clients.cache.ConfigDataV1; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java new file mode 100644 index 0000000..c57cada --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -0,0 +1,30 @@ +package it.gov.pagopa.payment.options.clients; + +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsRequest; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import jakarta.enterprise.context.ApplicationScoped; +import org.eclipse.microprofile.rest.client.RestClientBuilder; +import java.net.MalformedURLException; +import java.net.URL; + +@ApplicationScoped +public class CreditorInstitutionRestClient { + + public PaymentOptionsResponse callEcPaymentOptionsVerify( + String endpoint, String proxyHost, Long proxyPort, + String targetHost, Long targetPort, String targetPath, + PaymentOptionsRequest request) throws MalformedURLException { + + RestClientBuilder builder = + RestClientBuilder.newBuilder().baseUrl(new URL(endpoint)); + if (proxyHost != null && proxyPort != null) { + builder = builder.proxyAddress(proxyHost, proxyPort.intValue()); + } + CreditorInstitutionRestClientInterface ecRestClientInterface = builder.build( + CreditorInstitutionRestClientInterface.class); + return ecRestClientInterface.verifyPaymentOptions( + request, targetHost, targetPort.intValue(), targetPath); + + } + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java new file mode 100644 index 0000000..d555009 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java @@ -0,0 +1,21 @@ +package it.gov.pagopa.payment.options.clients; + +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsRequest; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam; + +@Path("") +public interface CreditorInstitutionRestClientInterface { + + @POST + @ClientHeaderParam(name = "Ocp-Apim-Subscription-Key", value = "${EcRestClient.ocpSubKey}") + PaymentOptionsResponse verifyPaymentOptions(PaymentOptionsRequest paymentOptionsRequest, + @HeaderParam("X-Host-Url") String hostUrl, + @HeaderParam("X-Host-Port") Integer hostPort, + @HeaderParam("X-Host-Path") String hostPath + ); + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumer.java b/src/main/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumer.java index 113ccb3..f421e5e 100644 --- a/src/main/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumer.java +++ b/src/main/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumer.java @@ -1,10 +1,9 @@ package it.gov.pagopa.payment.options.consumers; -import it.gov.pagopa.payment.options.models.CacheUpdateEvent; +import it.gov.pagopa.payment.options.models.events.CacheUpdateEvent; import it.gov.pagopa.payment.options.services.ConfigCacheService; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import jakarta.transaction.Transactional; import org.eclipse.microprofile.reactive.messaging.Incoming; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java b/src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java new file mode 100644 index 0000000..c3d6ae4 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java @@ -0,0 +1,15 @@ +package it.gov.pagopa.payment.options.exception; + +import lombok.Getter; + +/** + * Base exception for Payment Options exceptions + */ +@Getter +public class AppErrorException extends RuntimeException { + + public AppErrorException(Throwable error) { + super(error); + } + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/PaymentOptionsException.java b/src/main/java/it/gov/pagopa/payment/options/exception/PaymentOptionsException.java new file mode 100644 index 0000000..fec917e --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/exception/PaymentOptionsException.java @@ -0,0 +1,50 @@ +package it.gov.pagopa.payment.options.exception; + +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; +import jakarta.ws.rs.core.Response; +import lombok.Getter; +import java.util.Objects; + +/** + * Base exception for PaymentOptions exceptions + */ +@Getter +public class PaymentOptionsException extends RuntimeException { + + /** + * Error code of this exception + * -- GETTER -- + * Returns error code + * + * @return Error code of this exception + */ + private final AppErrorCodeEnum errorCode; + + /** + * Constructs new exception with provided error code and message + * + * @param errorCode Error code + * @param message Detail message + */ + public PaymentOptionsException(AppErrorCodeEnum errorCode, String message) { + super(message); + this.errorCode = Objects.requireNonNull(errorCode); + } + + /** + * Constructs new exception with provided error code, message and cause + * + * @param errorCode Error code + * @param message Detail message + * @param cause Exception causing the constructed one + */ + public PaymentOptionsException(AppErrorCodeEnum errorCode, String message, Throwable cause) { + super(message, cause); + this.errorCode = Objects.requireNonNull(errorCode); + } + + public static Response.Status getHttpStatus(PaymentOptionsException e) { + return e.getErrorCode().getStatus(); + } + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java new file mode 100644 index 0000000..0ce0897 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java @@ -0,0 +1,76 @@ +package it.gov.pagopa.payment.options.exception.mapper; + +import io.smallrye.mutiny.CompositeException; +import it.gov.pagopa.payment.options.exception.PaymentOptionsException; +import it.gov.pagopa.payment.options.models.ErrorResponse; +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.core.Response; +import org.jboss.resteasy.reactive.server.ServerExceptionMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +import static it.gov.pagopa.payment.options.exception.PaymentOptionsException.getHttpStatus; +import static org.jboss.resteasy.reactive.RestResponse.Status.BAD_REQUEST; +import static org.jboss.resteasy.reactive.RestResponse.StatusCode.INTERNAL_SERVER_ERROR; + +public class ExceptionMapper { + + Logger logger = LoggerFactory.getLogger(ExceptionMapper.class); + + private ErrorResponse buildErrorResponse(Response.Status status, AppErrorCodeEnum errorCode, String message) { + return ErrorResponse.builder() + .title(status.getReasonPhrase()) + .status(status.getStatusCode()) + .detail(message) + .instance(errorCode.getErrorCode()) + .build(); + } + + @ServerExceptionMapper + public Response mapCompositeException(CompositeException exception) { + logger.error(exception.getMessage(), exception); + Exception composedException; + List causes = exception.getCauses(); + composedException = (Exception) causes.get(causes.size() - 1); + + if(composedException instanceof NotFoundException ex) { + return mapNotFoundException(ex); + } else if(composedException instanceof PaymentOptionsException paymentNoticeException) { + return mapPaymentNoticeException(paymentNoticeException); + } else { + return mapGenericException(exception); + } + + } + + @ServerExceptionMapper + public Response mapNotFoundException(NotFoundException exception) { + logger.error(exception.getMessage(), exception); + return Response.status(BAD_REQUEST).entity( + buildErrorResponse(Response.Status.BAD_REQUEST, AppErrorCodeEnum.ERRORE_SINTASSI_INPUT, + "Invalid parameters on request")).build(); + } + + @ServerExceptionMapper + public Response mapPaymentNoticeException(PaymentOptionsException exception) { + logger.error(exception.getMessage(), exception); + Response.Status status = getHttpStatus(exception); + return Response.status(status).entity(buildErrorResponse(status, + exception.getErrorCode(), exception.getMessage())).build(); + } + + @ServerExceptionMapper + public Response mapGenericException(Exception exception) { + logger.error(exception.getMessage(), exception); + return Response.status(INTERNAL_SERVER_ERROR) + .entity(buildErrorResponse( + Response.Status.INTERNAL_SERVER_ERROR, + AppErrorCodeEnum.SYSTEM_ERROR, + "Unexpected Error")) + .build(); + } + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/ConfigCacheData.java b/src/main/java/it/gov/pagopa/payment/options/models/ConfigCacheData.java index 1f0e417..f60d3cb 100644 --- a/src/main/java/it/gov/pagopa/payment/options/models/ConfigCacheData.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/ConfigCacheData.java @@ -1,6 +1,6 @@ package it.gov.pagopa.payment.options.models; -import it.gov.pagopa.payment.options.clients.model.ConfigDataV1; +import it.gov.pagopa.payment.options.models.clients.cache.ConfigDataV1; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java b/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java new file mode 100644 index 0000000..7135299 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java @@ -0,0 +1,31 @@ +package it.gov.pagopa.payment.options.models; + +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.Builder; +import lombok.Getter; +import lombok.extern.jackson.Jacksonized; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +/** + * Model class for the error response + */ +@Getter +@Builder +@Jacksonized +@JsonPropertyOrder({"title", "status", "detail", "instance"}) +@RegisterForReflection +public class ErrorResponse { + + @Schema(example = "Internal Server Error") + private String title; + + @Schema(example = "500") + private int status; + + @Schema(example = "An unexpected error has occurred. Please contact support.") + private String detail; + + @Schema(example = "PN-500") + private String instance; +} diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/BrokerCreditorInstitution.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/BrokerCreditorInstitution.java similarity index 72% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/BrokerCreditorInstitution.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/BrokerCreditorInstitution.java index 81773d1..4fca621 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/BrokerCreditorInstitution.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/BrokerCreditorInstitution.java @@ -1,15 +1,11 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.util.Objects; /** * BrokerCreditorInstitution diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/ConfigDataV1.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/ConfigDataV1.java similarity index 98% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/ConfigDataV1.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/ConfigDataV1.java index 3bcf1a6..393ff6f 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/ConfigDataV1.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/ConfigDataV1.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/Connection.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Connection.java similarity index 94% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/Connection.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Connection.java index aa328aa..4b095e0 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/Connection.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Connection.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/CreditorInstitution.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/CreditorInstitution.java similarity index 93% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/CreditorInstitution.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/CreditorInstitution.java index 8150858..062d0c9 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/CreditorInstitution.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/CreditorInstitution.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/CreditorInstitutionAddress.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/CreditorInstitutionAddress.java similarity index 91% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/CreditorInstitutionAddress.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/CreditorInstitutionAddress.java index 5761204..04355b1 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/CreditorInstitutionAddress.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/CreditorInstitutionAddress.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/Proxy.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Proxy.java similarity index 73% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/Proxy.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Proxy.java index 1ae507a..c32bede 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/Proxy.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Proxy.java @@ -1,9 +1,6 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/Redirect.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Redirect.java similarity index 85% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/Redirect.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Redirect.java index 543aa29..bbfaf88 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/Redirect.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Redirect.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; @@ -8,9 +8,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; /** * Redirect diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/Service.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Service.java similarity index 73% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/Service.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Service.java index 7d3b03a..6a436e3 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/Service.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Service.java @@ -1,9 +1,6 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/Station.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java similarity index 84% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/Station.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java index a1de3ef..90ffb9d 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/Station.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java @@ -1,9 +1,6 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -71,4 +68,10 @@ public class Station { @JsonProperty("flag_standin") private Boolean flagStandin = null; + @JsonProperty("verify_payment_option_enabled") + private Boolean verifyPaymentOptionEnabled = false; + + @JsonProperty("verify_payment_option_endpoint") + private String verifyPaymentOptionEndpoint; + } diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/StationCreditorInstitution.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/StationCreditorInstitution.java similarity index 94% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/StationCreditorInstitution.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/StationCreditorInstitution.java index 56e19fe..3af11c5 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/StationCreditorInstitution.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/StationCreditorInstitution.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/model/Timeouts.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Timeouts.java similarity index 89% rename from src/main/java/it/gov/pagopa/payment/options/clients/model/Timeouts.java rename to src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Timeouts.java index 796636e..c1fdf04 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/model/Timeouts.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Timeouts.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.clients.model; +package it.gov.pagopa.payment.options.models.clients.cache; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java new file mode 100644 index 0000000..1c9cf04 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java @@ -0,0 +1,24 @@ +package it.gov.pagopa.payment.options.models.clients.creditorInstitution; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PaymentOptionsRequest { + + private String idPSP; + + private String idBrokerPSP; + + private String idChannel; + + private QrCode qrCode; + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java new file mode 100644 index 0000000..3446850 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java @@ -0,0 +1,5 @@ +package it.gov.pagopa.payment.options.models.clients.creditorInstitution; + +public class PaymentOptionsResponse { + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java new file mode 100644 index 0000000..fef885d --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java @@ -0,0 +1,19 @@ +package it.gov.pagopa.payment.options.models.clients.creditorInstitution; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class QrCode { + + private String fiscalCode; + private String noticeNumber; + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/enums/AppErrorCodeEnum.java b/src/main/java/it/gov/pagopa/payment/options/models/enums/AppErrorCodeEnum.java new file mode 100644 index 0000000..e34974c --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/enums/AppErrorCodeEnum.java @@ -0,0 +1,30 @@ +package it.gov.pagopa.payment.options.models.enums; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +import lombok.Getter; + +/** + * Enumeration for application error codes and messages + */ +@Getter +public enum AppErrorCodeEnum { + + ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE(Status.SERVICE_UNAVAILABLE, "ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE", "Required station is currently unavailable through the provided config params"), + ODP_SEMANTICA(Response.Status.BAD_REQUEST, "ODP_SINTASSI", "Bad request error on input syntax"), + ODP_SINTASSI(Response.Status.BAD_REQUEST, "ODP_SEMANTICA", "Bad request error due to semantic error withing the verify flow"), + ODP_SYSTEM_ERROR(Response.Status.INTERNAL_SERVER_ERROR, "ODP_SYSTEM_ERROR", "Unexpected system Error"), + + PA_SYSTEM_ERROR(Response.Status.INTERNAL_SERVER_ERROR, "PA_SYSTEM_ERROR", "Unexpected error on EC system call"); + + + private final Response.Status status; + private final String errorCode; + private final String errorMessage; + + AppErrorCodeEnum(Response.Status status, String errorCode, String errorMessage) { + this.status = status; + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/CacheUpdateEvent.java b/src/main/java/it/gov/pagopa/payment/options/models/events/CacheUpdateEvent.java similarity index 85% rename from src/main/java/it/gov/pagopa/payment/options/models/CacheUpdateEvent.java rename to src/main/java/it/gov/pagopa/payment/options/models/events/CacheUpdateEvent.java index 5eb2ff4..b884f63 100644 --- a/src/main/java/it/gov/pagopa/payment/options/models/CacheUpdateEvent.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/events/CacheUpdateEvent.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payment.options.models; +package it.gov.pagopa.payment.options.models.events; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/it/gov/pagopa/payment/options/services/ConfigCacheService.java b/src/main/java/it/gov/pagopa/payment/options/services/ConfigCacheService.java index 7da79d6..a2870af 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/ConfigCacheService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/ConfigCacheService.java @@ -2,9 +2,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import it.gov.pagopa.payment.options.clients.ApiConfigCacheClient; -import it.gov.pagopa.payment.options.clients.model.ConfigDataV1; -import it.gov.pagopa.payment.options.consumers.ConfigCacheUpdatesConsumer; -import it.gov.pagopa.payment.options.models.CacheUpdateEvent; +import it.gov.pagopa.payment.options.models.clients.cache.ConfigDataV1; +import it.gov.pagopa.payment.options.models.events.CacheUpdateEvent; import it.gov.pagopa.payment.options.models.ConfigCacheData; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java new file mode 100644 index 0000000..7562683 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -0,0 +1,92 @@ +package it.gov.pagopa.payment.options.services; + +import it.gov.pagopa.payment.options.clients.CreditorInstitutionRestClient; +import it.gov.pagopa.payment.options.exception.PaymentOptionsException; +import it.gov.pagopa.payment.options.models.clients.cache.Connection.ProtocolEnum; +import it.gov.pagopa.payment.options.models.clients.cache.Station; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsRequest; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.QrCode; +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.net.MalformedURLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class CreditorInstitutionService { + + private final Logger logger = LoggerFactory.getLogger(CreditorInstitutionService.class); + + String APIM_FORWARDER_ENDPOINT = ""; + + static String PAYMENT_OPTIONS_SERVICE_SUFFIX = "/payment-options"; + + @Inject + CreditorInstitutionRestClient creditorInstitutionRestClient; + + public PaymentOptionsResponse getPaymentOptions( + String idPsp, String idBrokerPsp, String idChannel, + String noticeNumber, String fiscalCode, Station station) { + + if (station.getConnection().getIp() == null || + !station.getConnection().getIp().contains(APIM_FORWARDER_ENDPOINT)) { + throw new PaymentOptionsException(AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, + "Station not configured to pass through the APIM Forwarder"); + } + + String endpoint = getEndpoint(station); + + if (station.getVerifyPaymentOptionEndpoint() == null) { + throw new PaymentOptionsException(AppErrorCodeEnum.ODP_SEMANTICA, + "Station new verify endpoint not provided"); + } + + String[] verifyEndpointParts = + station.getVerifyPaymentOptionEndpoint().split("/",4); + String targetHost = verifyEndpointParts[0] + verifyEndpointParts[2]; + String[] hostSplit = verifyEndpointParts[2].split(":"); + Long targetPort = hostSplit.length > 1 ? + Long.parseLong(hostSplit[1]) : + verifyEndpointParts[0].contains(ProtocolEnum.HTTPS.name().toLowerCase()) ? + 443L : 80L; + String targetPath = verifyEndpointParts[3].concat(PAYMENT_OPTIONS_SERVICE_SUFFIX); + + PaymentOptionsRequest paymentOptionsRequest = + PaymentOptionsRequest.builder() + .idPSP(idPsp) + .idBrokerPSP(idBrokerPsp) + .idChannel(idChannel) + .qrCode(QrCode.builder() + .fiscalCode(fiscalCode) + .noticeNumber(noticeNumber) + .build() + ).build(); + + try { + return creditorInstitutionRestClient.callEcPaymentOptionsVerify( + endpoint, + station.getProxy() != null ? station.getProxy().getProxyHost() : null, + station.getProxy() != null ? station.getProxy().getProxyPort() : null, + targetHost, targetPort, targetPath, paymentOptionsRequest + ); + } catch (MalformedURLException e) { + logger.error("[Payment Options] Malformed URL: {}", e.getMessage()); + throw new PaymentOptionsException(AppErrorCodeEnum.ODP_SEMANTICA, e.getMessage()); + } + + } + + private static String getEndpoint(Station station) { + return (station.getConnection().getProtocol() != null && + (station.getConnection().getProtocol().equals(ProtocolEnum.HTTPS)) ? + ProtocolEnum.HTTPS.name().toLowerCase() : + station.getConnection().getProtocol().name().toLowerCase()) + + "://" + station.getConnection().getIp() + ":" + + (station.getConnection().getPort() != null ? + String.valueOf(station.getConnection().getPort()) : "80") + + PAYMENT_OPTIONS_SERVICE_SUFFIX; + } + +} diff --git a/src/test/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumerTest.java b/src/test/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumerTest.java index 13fca55..eb555fc 100644 --- a/src/test/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumerTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/consumers/ConfigCacheUpdatesConsumerTest.java @@ -2,7 +2,7 @@ import io.quarkus.test.InjectMock; import io.quarkus.test.junit.QuarkusTest; -import it.gov.pagopa.payment.options.models.CacheUpdateEvent; +import it.gov.pagopa.payment.options.models.events.CacheUpdateEvent; import it.gov.pagopa.payment.options.models.ConfigCacheData; import it.gov.pagopa.payment.options.services.ConfigCacheService; import jakarta.inject.Inject; diff --git a/src/test/java/it/gov/pagopa/payment/options/services/ConfigCacheServiceTest.java b/src/test/java/it/gov/pagopa/payment/options/services/ConfigCacheServiceTest.java index 4649d1e..1338f7a 100644 --- a/src/test/java/it/gov/pagopa/payment/options/services/ConfigCacheServiceTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/services/ConfigCacheServiceTest.java @@ -3,9 +3,8 @@ import io.quarkus.test.InjectMock; import io.quarkus.test.junit.QuarkusTest; import it.gov.pagopa.payment.options.clients.ApiConfigCacheClient; -import it.gov.pagopa.payment.options.clients.model.ConfigDataV1; -import it.gov.pagopa.payment.options.models.CacheUpdateEvent; -import it.gov.pagopa.payment.options.models.ConfigCacheData; +import it.gov.pagopa.payment.options.models.clients.cache.ConfigDataV1; +import it.gov.pagopa.payment.options.models.events.CacheUpdateEvent; import jakarta.inject.Inject; import org.eclipse.microprofile.rest.client.inject.RestClient; import org.junit.jupiter.api.BeforeEach; From 2b2f7ab697c164961ec4df64865cd27680554bb1 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 15:45:30 +0200 Subject: [PATCH 02/19] [PPANTT-81] feat: Updated exception management for ec station calls --- .../CreditorInstitutionRestClient.java | 51 +++++++++++++++++-- ...reditorInstitutionRestClientInterface.java | 17 +++++-- .../options/exception/AppErrorException.java | 15 ------ .../CreditorInstitutionException.java | 38 ++++++++++++++ .../exception/mapper/ExceptionMapper.java | 42 +++++++++------ .../payment/options/models/ErrorResponse.java | 23 +++++---- .../PaymentOptionsRequest.java | 24 --------- .../services/CreditorInstitutionService.java | 24 +++------ 8 files changed, 145 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/exception/CreditorInstitutionException.java delete mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java index c57cada..66bc0f9 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -1,19 +1,34 @@ package it.gov.pagopa.payment.options.clients; -import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsRequest; +import com.fasterxml.jackson.databind.ObjectMapper; +import it.gov.pagopa.payment.options.exception.CreditorInstitutionException; +import it.gov.pagopa.payment.options.exception.PaymentOptionsException; +import it.gov.pagopa.payment.options.models.ErrorResponse; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.RestClientBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.net.MalformedURLException; import java.net.URL; @ApplicationScoped public class CreditorInstitutionRestClient { + private final Logger logger = LoggerFactory.getLogger(CreditorInstitutionRestClient.class); + + @Inject + ObjectMapper objectMapper; + public PaymentOptionsResponse callEcPaymentOptionsVerify( String endpoint, String proxyHost, Long proxyPort, String targetHost, Long targetPort, String targetPath, - PaymentOptionsRequest request) throws MalformedURLException { + String idPsp, String idBrokerPsp, + String idStazione, String fiscalCode, String noticeNumber) + throws MalformedURLException { RestClientBuilder builder = RestClientBuilder.newBuilder().baseUrl(new URL(endpoint)); @@ -22,8 +37,36 @@ public PaymentOptionsResponse callEcPaymentOptionsVerify( } CreditorInstitutionRestClientInterface ecRestClientInterface = builder.build( CreditorInstitutionRestClientInterface.class); - return ecRestClientInterface.verifyPaymentOptions( - request, targetHost, targetPort.intValue(), targetPath); + + try (Response response = ecRestClientInterface.verifyPaymentOptions( + fiscalCode, noticeNumber, idPsp, idBrokerPsp, idStazione, + targetHost, targetPort.intValue(), targetPath)) { + + if (response.getStatus() != 200) { + + try { + ErrorResponse errorResponse = objectMapper.readValue( + response.readEntity(String.class), ErrorResponse.class); + throw new CreditorInstitutionException(errorResponse, + "Encountered a managed error calling the station REST endpoint"); + } catch (Exception e) { + logger.error("[Payment Options] Unable to call the station due to error: {}", + e.getMessage()); + throw new PaymentOptionsException( + AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, e.getMessage()); + } + + } + + return objectMapper.readValue( + response.readEntity(String.class), PaymentOptionsResponse.class); + + } catch (Exception e) { + logger.error("[Payment Options] Unable to call the station due to error: {}", + e.getMessage()); + throw new PaymentOptionsException( + AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, e.getMessage()); + } } diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java index d555009..b97e178 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java @@ -1,18 +1,25 @@ package it.gov.pagopa.payment.options.clients; -import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsRequest; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; -import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam; -@Path("") public interface CreditorInstitutionRestClientInterface { - @POST + @GET() + @Path("/payment-options/organizations/{fiscal-code}/notices/{notice-number}") @ClientHeaderParam(name = "Ocp-Apim-Subscription-Key", value = "${EcRestClient.ocpSubKey}") - PaymentOptionsResponse verifyPaymentOptions(PaymentOptionsRequest paymentOptionsRequest, + Response verifyPaymentOptions( + @PathParam("fiscal-code") String fiscalCode, + @PathParam("notice-number") String noticeNumber, + @QueryParam("idPA") String idPA, + @QueryParam("idBrokerPA") String idBrokerPA, + @QueryParam("idStation") String idStation, @HeaderParam("X-Host-Url") String hostUrl, @HeaderParam("X-Host-Port") Integer hostPort, @HeaderParam("X-Host-Path") String hostPath diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java b/src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java deleted file mode 100644 index c3d6ae4..0000000 --- a/src/main/java/it/gov/pagopa/payment/options/exception/AppErrorException.java +++ /dev/null @@ -1,15 +0,0 @@ -package it.gov.pagopa.payment.options.exception; - -import lombok.Getter; - -/** - * Base exception for Payment Options exceptions - */ -@Getter -public class AppErrorException extends RuntimeException { - - public AppErrorException(Throwable error) { - super(error); - } - -} diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/CreditorInstitutionException.java b/src/main/java/it/gov/pagopa/payment/options/exception/CreditorInstitutionException.java new file mode 100644 index 0000000..f1ac59a --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/exception/CreditorInstitutionException.java @@ -0,0 +1,38 @@ +package it.gov.pagopa.payment.options.exception; + +import it.gov.pagopa.payment.options.models.ErrorResponse; +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; +import jakarta.ws.rs.core.Response; +import lombok.Getter; +import java.util.Objects; + +@Getter +public class CreditorInstitutionException extends RuntimeException { + + private ErrorResponse errorResponse; + + /** + * Constructs new exception with provided error code and message + * + * @param errorResponse Error Response + * @param message Detail message + */ + public CreditorInstitutionException(ErrorResponse errorResponse, String message) { + super(message); + this.errorResponse = Objects.requireNonNull(errorResponse); + } + + /** + * Constructs new exception with provided error response, message and cause + * + * @param errorResponse Error Response + * @param message Detail message + * @param cause Exception causing the constructed one + */ + public CreditorInstitutionException(ErrorResponse errorResponse, String message, Throwable cause) { + super(message, cause); + this.errorResponse = Objects.requireNonNull(errorResponse); + } + + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java index 0ce0897..5b687f3 100644 --- a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java +++ b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java @@ -1,31 +1,34 @@ package it.gov.pagopa.payment.options.exception.mapper; +import static it.gov.pagopa.payment.options.exception.PaymentOptionsException.getHttpStatus; +import static org.jboss.resteasy.reactive.RestResponse.Status.NOT_FOUND; +import static org.jboss.resteasy.reactive.RestResponse.StatusCode.INTERNAL_SERVER_ERROR; + import io.smallrye.mutiny.CompositeException; +import it.gov.pagopa.payment.options.exception.CreditorInstitutionException; import it.gov.pagopa.payment.options.exception.PaymentOptionsException; import it.gov.pagopa.payment.options.models.ErrorResponse; import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +import java.time.Instant; +import java.util.List; import org.jboss.resteasy.reactive.server.ServerExceptionMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; - -import static it.gov.pagopa.payment.options.exception.PaymentOptionsException.getHttpStatus; -import static org.jboss.resteasy.reactive.RestResponse.Status.BAD_REQUEST; -import static org.jboss.resteasy.reactive.RestResponse.StatusCode.INTERNAL_SERVER_ERROR; - public class ExceptionMapper { Logger logger = LoggerFactory.getLogger(ExceptionMapper.class); private ErrorResponse buildErrorResponse(Response.Status status, AppErrorCodeEnum errorCode, String message) { return ErrorResponse.builder() - .title(status.getReasonPhrase()) - .status(status.getStatusCode()) - .detail(message) - .instance(errorCode.getErrorCode()) + .httpStatusCode(status.getStatusCode()) + .httpStatusDescription(status.getReasonPhrase()) + .appErrorCode(errorCode.getErrorCode()) + .errorMessage(errorCode.getErrorMessage()) + .timestamp(Instant.now().getEpochSecond()) .build(); } @@ -39,18 +42,27 @@ public Response mapCompositeException(CompositeException exception) { if(composedException instanceof NotFoundException ex) { return mapNotFoundException(ex); } else if(composedException instanceof PaymentOptionsException paymentNoticeException) { - return mapPaymentNoticeException(paymentNoticeException); + return mapPaymentNoticeException(paymentNoticeException); + } else if(composedException instanceof CreditorInstitutionException creditorInstitutionException) { + return mapCreditorInstitutionException(creditorInstitutionException); } else { return mapGenericException(exception); } } - @ServerExceptionMapper + @ServerExceptionMapper + private Response mapCreditorInstitutionException(CreditorInstitutionException creditorInstitutionException) { + logger.error(creditorInstitutionException.getMessage(), creditorInstitutionException); + return Response.status(creditorInstitutionException.getErrorResponse().getHttpStatusCode()) + .entity(creditorInstitutionException.getErrorResponse()).build(); + } + + @ServerExceptionMapper public Response mapNotFoundException(NotFoundException exception) { logger.error(exception.getMessage(), exception); - return Response.status(BAD_REQUEST).entity( - buildErrorResponse(Response.Status.BAD_REQUEST, AppErrorCodeEnum.ERRORE_SINTASSI_INPUT, + return Response.status(NOT_FOUND).entity( + buildErrorResponse(Status.NOT_FOUND, AppErrorCodeEnum.ODP_SINTASSI, "Invalid parameters on request")).build(); } @@ -68,7 +80,7 @@ public Response mapGenericException(Exception exception) { return Response.status(INTERNAL_SERVER_ERROR) .entity(buildErrorResponse( Response.Status.INTERNAL_SERVER_ERROR, - AppErrorCodeEnum.SYSTEM_ERROR, + AppErrorCodeEnum.ODP_SYSTEM_ERROR, "Unexpected Error")) .build(); } diff --git a/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java b/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java index 7135299..48d16cf 100644 --- a/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/ErrorResponse.java @@ -1,6 +1,5 @@ package it.gov.pagopa.payment.options.models; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; import io.quarkus.runtime.annotations.RegisterForReflection; import lombok.Builder; import lombok.Getter; @@ -13,19 +12,25 @@ @Getter @Builder @Jacksonized -@JsonPropertyOrder({"title", "status", "detail", "instance"}) @RegisterForReflection public class ErrorResponse { - @Schema(example = "Internal Server Error") - private String title; - @Schema(example = "500") - private int status; + private int httpStatusCode; + + @Schema(example = "Internal Server Error") + private String httpStatusDescription; @Schema(example = "An unexpected error has occurred. Please contact support.") - private String detail; + private String errorMessage; + + @Schema(example = "ODP-") + private String appErrorCode; + + @Schema(example = "1724425035") + private Long timestamp; + + @Schema(example = "2024-08-23T14:57:15.635528") + private String dateTime; - @Schema(example = "PN-500") - private String instance; } diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java deleted file mode 100644 index 1c9cf04..0000000 --- a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package it.gov.pagopa.payment.options.models.clients.creditorInstitution; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PaymentOptionsRequest { - - private String idPSP; - - private String idBrokerPSP; - - private String idChannel; - - private QrCode qrCode; - -} diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 7562683..919eba4 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -4,9 +4,7 @@ import it.gov.pagopa.payment.options.exception.PaymentOptionsException; import it.gov.pagopa.payment.options.models.clients.cache.Connection.ProtocolEnum; import it.gov.pagopa.payment.options.models.clients.cache.Station; -import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsRequest; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; -import it.gov.pagopa.payment.options.models.clients.creditorInstitution.QrCode; import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -21,13 +19,13 @@ public class CreditorInstitutionService { String APIM_FORWARDER_ENDPOINT = ""; - static String PAYMENT_OPTIONS_SERVICE_SUFFIX = "/payment-options"; + static String PAYMENT_OPTIONS_SERVICE_SUFFIX = "/payment-options/organizations/%s/notices/%s"; @Inject CreditorInstitutionRestClient creditorInstitutionRestClient; public PaymentOptionsResponse getPaymentOptions( - String idPsp, String idBrokerPsp, String idChannel, + String idPsp, String idBrokerPsp, String idStazione, String noticeNumber, String fiscalCode, Station station) { if (station.getConnection().getIp() == null || @@ -51,25 +49,17 @@ public PaymentOptionsResponse getPaymentOptions( Long.parseLong(hostSplit[1]) : verifyEndpointParts[0].contains(ProtocolEnum.HTTPS.name().toLowerCase()) ? 443L : 80L; - String targetPath = verifyEndpointParts[3].concat(PAYMENT_OPTIONS_SERVICE_SUFFIX); - - PaymentOptionsRequest paymentOptionsRequest = - PaymentOptionsRequest.builder() - .idPSP(idPsp) - .idBrokerPSP(idBrokerPsp) - .idChannel(idChannel) - .qrCode(QrCode.builder() - .fiscalCode(fiscalCode) - .noticeNumber(noticeNumber) - .build() - ).build(); + String targetPath = verifyEndpointParts[3].concat( + String.format(PAYMENT_OPTIONS_SERVICE_SUFFIX, fiscalCode, noticeNumber)); + try { return creditorInstitutionRestClient.callEcPaymentOptionsVerify( endpoint, station.getProxy() != null ? station.getProxy().getProxyHost() : null, station.getProxy() != null ? station.getProxy().getProxyPort() : null, - targetHost, targetPort, targetPath, paymentOptionsRequest + targetHost, targetPort, targetPath, + idPsp, idBrokerPsp, idStazione, fiscalCode, noticeNumber ); } catch (MalformedURLException e) { logger.error("[Payment Options] Malformed URL: {}", e.getMessage()); From a43caa5d95db4fed17714cb71d918ce4735ee86d Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 15:46:56 +0200 Subject: [PATCH 03/19] [PPANTT-81] feat: Updated exception management for ec station calls --- .../exception/mapper/ExceptionMapper.java | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java index 5b687f3..50553b2 100644 --- a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java +++ b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java @@ -59,30 +59,30 @@ private Response mapCreditorInstitutionException(CreditorInstitutionException cr } @ServerExceptionMapper - public Response mapNotFoundException(NotFoundException exception) { - logger.error(exception.getMessage(), exception); - return Response.status(NOT_FOUND).entity( - buildErrorResponse(Status.NOT_FOUND, AppErrorCodeEnum.ODP_SINTASSI, - "Invalid parameters on request")).build(); - } + public Response mapNotFoundException(NotFoundException exception) { + logger.error(exception.getMessage(), exception); + return Response.status(NOT_FOUND).entity( + buildErrorResponse(Status.NOT_FOUND, AppErrorCodeEnum.ODP_SINTASSI, + "Invalid parameters on request")).build(); + } - @ServerExceptionMapper - public Response mapPaymentNoticeException(PaymentOptionsException exception) { - logger.error(exception.getMessage(), exception); - Response.Status status = getHttpStatus(exception); - return Response.status(status).entity(buildErrorResponse(status, - exception.getErrorCode(), exception.getMessage())).build(); - } + @ServerExceptionMapper + public Response mapPaymentNoticeException(PaymentOptionsException exception) { + logger.error(exception.getMessage(), exception); + Response.Status status = getHttpStatus(exception); + return Response.status(status).entity(buildErrorResponse(status, + exception.getErrorCode(), exception.getMessage())).build(); + } - @ServerExceptionMapper - public Response mapGenericException(Exception exception) { - logger.error(exception.getMessage(), exception); - return Response.status(INTERNAL_SERVER_ERROR) - .entity(buildErrorResponse( - Response.Status.INTERNAL_SERVER_ERROR, - AppErrorCodeEnum.ODP_SYSTEM_ERROR, - "Unexpected Error")) - .build(); - } + @ServerExceptionMapper + public Response mapGenericException(Exception exception) { + logger.error(exception.getMessage(), exception); + return Response.status(INTERNAL_SERVER_ERROR) + .entity(buildErrorResponse( + Response.Status.INTERNAL_SERVER_ERROR, + AppErrorCodeEnum.ODP_SYSTEM_ERROR, + "Unexpected Error")) + .build(); + } } From 2e9cca330c8ce7e1bad86931a83188211e127853 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 15:47:34 +0200 Subject: [PATCH 04/19] [PPANTT-81] feat: Updated exception management for ec station calls --- .../options/clients/CreditorInstitutionRestClientInterface.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java index b97e178..0f06eb6 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java @@ -11,7 +11,7 @@ public interface CreditorInstitutionRestClientInterface { - @GET() + @GET @Path("/payment-options/organizations/{fiscal-code}/notices/{notice-number}") @ClientHeaderParam(name = "Ocp-Apim-Subscription-Key", value = "${EcRestClient.ocpSubKey}") Response verifyPaymentOptions( From 21e8234da2c99da444e479e5c7f035a90a1237f5 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 16:44:42 +0200 Subject: [PATCH 05/19] [PPANTT-81] feat: Updated config parameters --- .../options/services/CreditorInstitutionService.java | 4 +++- src/main/resources/application.properties | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 919eba4..7ae03ac 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -9,6 +9,7 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.net.MalformedURLException; +import org.eclipse.microprofile.config.inject.ConfigProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,7 +18,8 @@ public class CreditorInstitutionService { private final Logger logger = LoggerFactory.getLogger(CreditorInstitutionService.class); - String APIM_FORWARDER_ENDPOINT = ""; + @ConfigProperty(name = "CreditorInstitutionRestClient.apimEndpoint") + String APIM_FORWARDER_ENDPOINT; static String PAYMENT_OPTIONS_SERVICE_SUFFIX = "/payment-options/organizations/%s/notices/%s"; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e2732de..2b6edec 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -14,8 +14,7 @@ quarkus.native.additional-build-args=-H:ResourceConfigurationFiles=resources-con ################### ## LOG ################### -quarkus.log.level=${LOG_LEVEL:INFO} - +quarkus.log.level=${LOG_LEVEL:DEBUG} quarkus.log.category."org.jboss".level=${JBOSS_LOG_LEVEL:DEBUG} quarkus.log.category."it.gov.pagopa.payment.options".level=${APP_LOG_LEVEL:DEBUG} %dev.quarkus.log.console.json=false @@ -52,6 +51,13 @@ mp.messaging.incoming.nodo-dei-pagamenti-cache.connections.max.request.size=${KA quarkus.rest-client."it.gov.pagopa.payment.options.clients.ApiConfigCacheClient".url=${APICONFIG_CACHE_URL:localhost:8082} ApiConfigCacheClient.ocpSubKey=${APICONFIG_SUBKEY:} +################### +## EC REST CLIENT +################### + +CreditorInstitutionRestClient.ocpSubKey=${EC_APIM_SUBKEY:} +CreditorInstitutionRestClient.apimEndpoint=${EC_APIM_FORWARDER_SUBKEY:} + ################### ## OPENTELEMETRY ################### From a8412a94194ab4adf6e6108e13253af6726cd7b5 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 17:51:52 +0200 Subject: [PATCH 06/19] [PPANTT-81] feat: Updated models and logs --- pom.xml | 7 +++ .../CreditorInstitutionRestClient.java | 2 +- .../creditorInstitution/Installment.java | 26 ++++++++++ .../creditorInstitution/PaymentOption.java | 28 ++++++++++ .../PaymentOptionsResponse.java | 18 +++++++ .../clients/creditorInstitution/QrCode.java | 19 ------- .../options/models/enums/EnumInstallment.java | 11 ++++ .../payment/options/models/enums/EnumPo.java | 12 +++++ .../services/CreditorInstitutionService.java | 4 +- .../payment/options/WireMockExtensions.java | 51 +++++++++++++++++++ 10 files changed, 156 insertions(+), 22 deletions(-) create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/Installment.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOption.java delete mode 100644 src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/enums/EnumInstallment.java create mode 100644 src/main/java/it/gov/pagopa/payment/options/models/enums/EnumPo.java create mode 100644 src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java diff --git a/pom.xml b/pom.xml index 51e7941..03fa3fe 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ io.quarkus.platform 3.14.2 3.0.0-M7 + 3.9.1 @@ -103,6 +104,12 @@ 5.13.0 test + + org.wiremock + wiremock + test + ${wiremock.version} + io.quarkus quarkus-junit5-mockito diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java index 66bc0f9..32750dc 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -48,7 +48,7 @@ public PaymentOptionsResponse callEcPaymentOptionsVerify( ErrorResponse errorResponse = objectMapper.readValue( response.readEntity(String.class), ErrorResponse.class); throw new CreditorInstitutionException(errorResponse, - "Encountered a managed error calling the station REST endpoint"); + "[Payment Options] Encountered a managed error calling the station REST endpoint"); } catch (Exception e) { logger.error("[Payment Options] Unable to call the station due to error: {}", e.getMessage()); diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/Installment.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/Installment.java new file mode 100644 index 0000000..3731d96 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/Installment.java @@ -0,0 +1,26 @@ +package it.gov.pagopa.payment.options.models.clients.creditorInstitution; + +import it.gov.pagopa.payment.options.models.enums.EnumInstallment; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Installment { + + private String nav; + private String iuv; + private Long amount; + private String description; + private String dueDate; + private String validFrom; + private EnumInstallment status; + private String statusReason; + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOption.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOption.java new file mode 100644 index 0000000..d3a1ccd --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOption.java @@ -0,0 +1,28 @@ +package it.gov.pagopa.payment.options.models.clients.creditorInstitution; + +import it.gov.pagopa.payment.options.models.enums.EnumPo; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import java.util.List; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PaymentOption { + + private String description; + private Integer numberOfInstallments; + private String dueDate; + private String validFrom; + private Long amount; + private EnumPo status; + private String statusReason; + private Boolean allCCP; + private List installments; + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java index 3446850..81a0880 100644 --- a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/PaymentOptionsResponse.java @@ -1,5 +1,23 @@ package it.gov.pagopa.payment.options.models.clients.creditorInstitution; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import java.util.List; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class PaymentOptionsResponse { + private String paTaxCode; + private String paFullName; + private String paOfficeName; + private Boolean standin; + private List paymentOptions; + } diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java deleted file mode 100644 index fef885d..0000000 --- a/src/main/java/it/gov/pagopa/payment/options/models/clients/creditorInstitution/QrCode.java +++ /dev/null @@ -1,19 +0,0 @@ -package it.gov.pagopa.payment.options.models.clients.creditorInstitution; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class QrCode { - - private String fiscalCode; - private String noticeNumber; - -} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/enums/EnumInstallment.java b/src/main/java/it/gov/pagopa/payment/options/models/enums/EnumInstallment.java new file mode 100644 index 0000000..f36a598 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/enums/EnumInstallment.java @@ -0,0 +1,11 @@ +package it.gov.pagopa.payment.options.models.enums; + +public enum EnumInstallment { + + POI_UNPAID, + POI_PAID, + POI_EXPIRED_NOT_PAYABLE, + POI_EXPIRED_UNPAID, + POI_INVALID + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/models/enums/EnumPo.java b/src/main/java/it/gov/pagopa/payment/options/models/enums/EnumPo.java new file mode 100644 index 0000000..8c1da9d --- /dev/null +++ b/src/main/java/it/gov/pagopa/payment/options/models/enums/EnumPo.java @@ -0,0 +1,12 @@ +package it.gov.pagopa.payment.options.models.enums; + +public enum EnumPo { + + PO_UNPAID, + PO_PAID, + PO_PARTIALLY_PAID, + PO_EXPIRED_NOT_PAYABLE, + PO_EXPIRED_UNPAID, + PO_INVALID + +} diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 7ae03ac..892b5a3 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -33,14 +33,14 @@ public PaymentOptionsResponse getPaymentOptions( if (station.getConnection().getIp() == null || !station.getConnection().getIp().contains(APIM_FORWARDER_ENDPOINT)) { throw new PaymentOptionsException(AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, - "Station not configured to pass through the APIM Forwarder"); + "[Payment Options] Station not configured to pass through the APIM Forwarder"); } String endpoint = getEndpoint(station); if (station.getVerifyPaymentOptionEndpoint() == null) { throw new PaymentOptionsException(AppErrorCodeEnum.ODP_SEMANTICA, - "Station new verify endpoint not provided"); + "[Payment Options] Station new verify endpoint not provided"); } String[] verifyEndpointParts = diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java new file mode 100644 index 0000000..f297197 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -0,0 +1,51 @@ +package it.gov.pagopa.payment.options; + +import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.WireMockServer; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import lombok.SneakyThrows; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; + + +public class WireMockExtensions implements QuarkusTestResourceLifecycleManager { + + private WireMockServer wireMockServer; + + @SneakyThrows + @Override + public Map start() { + ObjectMapper objectMapper = new ObjectMapper(); + wireMockServer = new WireMockServer(); + wireMockServer.start(); + + wireMockServer.stubFor( + get(urlEqualTo("/extensions?id=io.quarkus:quarkus-rest-client")) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody( + objectMapper.writeValueAsString( + PaymentOptionsResponse.builder().build() + ) + ) + ) + ); + + return Map.of( + "quarkus.rest-client.\"org.acme.rest.client.ExtensionsService\".url", + wireMockServer.baseUrl() + ); + } + + @Override + public void stop() { + if (null != wireMockServer) { + wireMockServer.stop(); + } + } +} From 87263eda2105fa639868e353c65385f7d4b37418 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 12 Sep 2024 18:16:22 +0200 Subject: [PATCH 07/19] [PPANTT-81] feat: Introducing unit testing for CreditorInstitutionRestClient --- src/main/resources/application.properties | 2 +- .../payment/options/WireMockExtensions.java | 23 ++++++-- .../CreditorInstitutionRestClientTest.java | 53 +++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2b6edec..d6df921 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -56,7 +56,7 @@ ApiConfigCacheClient.ocpSubKey=${APICONFIG_SUBKEY:} ################### CreditorInstitutionRestClient.ocpSubKey=${EC_APIM_SUBKEY:} -CreditorInstitutionRestClient.apimEndpoint=${EC_APIM_FORWARDER_SUBKEY:} +CreditorInstitutionRestClient.apimEndpoint=${EC_APIM_FORWARDER_ENDPOINT:localhost:8083} ################### ## OPENTELEMETRY diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java index f297197..7e57fcc 100644 --- a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import it.gov.pagopa.payment.options.models.ErrorResponse; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; import lombok.SneakyThrows; @@ -25,7 +26,8 @@ public Map start() { wireMockServer.start(); wireMockServer.stubFor( - get(urlEqualTo("/extensions?id=io.quarkus:quarkus-rest-client")) + get(urlEqualTo( + "/payment-options/organizations/77777777777/notices/311111111112222222")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody( @@ -36,9 +38,24 @@ public Map start() { ) ); + wireMockServer.stubFor( + get(urlEqualTo( + "/payment-options/organizations/87777777777/notices/311111111112222222")) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withStatus(500) + .withBody( + objectMapper.writeValueAsString( + ErrorResponse.builder().build() + ) + ) + ) + ); + return Map.of( - "quarkus.rest-client.\"org.acme.rest.client.ExtensionsService\".url", - wireMockServer.baseUrl() + "CreditorInstitutionRestClient.apimEndpoint", + wireMockServer.baseUrl(), + "CreditorInstitutionRestClient.ocpSubKey", "test" ); } diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java new file mode 100644 index 0000000..9277f08 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -0,0 +1,53 @@ +package it.gov.pagopa.payment.options.clients; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import it.gov.pagopa.payment.options.WireMockExtensions; +import it.gov.pagopa.payment.options.exception.CreditorInstitutionException; +import it.gov.pagopa.payment.options.models.clients.cache.Connection; +import it.gov.pagopa.payment.options.models.clients.cache.Connection.ProtocolEnum; +import it.gov.pagopa.payment.options.models.clients.cache.Station; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import jakarta.inject.Inject; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +@QuarkusTest +@QuarkusTestResource(WireMockExtensions.class) +class CreditorInstitutionRestClientTest { + + @ConfigProperty(name = "CreditorInstitutionRestClient.apimEndpoint") + private String wiremockUrl; + + @Inject + CreditorInstitutionRestClient creditorInstitutionRestClient; + + @Test + void callEcPaymentOptionsVerifyShouldReturnData() { + PaymentOptionsResponse paymentOptionsResponse = + assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + wiremockUrl, null, null, + "http://externalService", 443L, "/externalPath", + "88888888888", "88888888888", "88888888888_01", + "77777777777", "311111111112222222")); + assertNotNull(paymentOptionsResponse); + } + + @Test + void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { + CreditorInstitutionException exception = + assertThrows(CreditorInstitutionException.class, + () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + wiremockUrl, null, null, + "http://externalService", 443L, "/externalPath", + "88888888888", "88888888888", "88888888888_01", + "87777777777", "311111111112222222")); + assertNotNull(exception); + assertEquals(exception.getErrorResponse().getHttpStatusCode(), 500); + } + + +} From 1396708ded15e2da315c6189d212bc862209c730 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Fri, 13 Sep 2024 10:44:06 +0200 Subject: [PATCH 08/19] [PPANTT-81] feat: Updated unit testing for CreditorInstitutionRestClient --- .../CreditorInstitutionRestClient.java | 36 ++++++++++++------- ...reditorInstitutionRestClientInterface.java | 2 +- .../exception/mapper/ExceptionMapper.java | 2 +- src/main/resources/application.properties | 5 ++- .../payment/options/WireMockExtensions.java | 33 +++++++++++------ 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java index 32750dc..ca72043 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -10,6 +10,7 @@ import jakarta.inject.Inject; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.RestClientBuilder; +import org.jboss.resteasy.reactive.ClientWebApplicationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.MalformedURLException; @@ -43,24 +44,17 @@ public PaymentOptionsResponse callEcPaymentOptionsVerify( targetHost, targetPort.intValue(), targetPath)) { if (response.getStatus() != 200) { - - try { - ErrorResponse errorResponse = objectMapper.readValue( - response.readEntity(String.class), ErrorResponse.class); - throw new CreditorInstitutionException(errorResponse, - "[Payment Options] Encountered a managed error calling the station REST endpoint"); - } catch (Exception e) { - logger.error("[Payment Options] Unable to call the station due to error: {}", - e.getMessage()); - throw new PaymentOptionsException( - AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, e.getMessage()); - } - + manageErrorResponse(response); } return objectMapper.readValue( response.readEntity(String.class), PaymentOptionsResponse.class); + } catch (ClientWebApplicationException clientWebApplicationException) { + logger.error("[Payment Options] Encountered REST client exception: {}", + clientWebApplicationException.getMessage()); + manageErrorResponse(clientWebApplicationException.getResponse()); + return null; } catch (Exception e) { logger.error("[Payment Options] Unable to call the station due to error: {}", e.getMessage()); @@ -70,4 +64,20 @@ public PaymentOptionsResponse callEcPaymentOptionsVerify( } + private void manageErrorResponse(Response response) { + try { + ErrorResponse errorResponse = objectMapper.readValue( + response.readEntity(String.class), ErrorResponse.class); + throw new CreditorInstitutionException(errorResponse, + "[Payment Options] Encountered a managed error calling the station REST endpoint"); + } catch (CreditorInstitutionException creditorInstitutionException) { + throw creditorInstitutionException; + } catch (Exception e) { + logger.error("[Payment Options] Unable to call the station due to error: {}", + e.getMessage()); + throw new PaymentOptionsException( + AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, e.getMessage()); + } + } + } diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java index 0f06eb6..93965f3 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java @@ -13,7 +13,7 @@ public interface CreditorInstitutionRestClientInterface { @GET @Path("/payment-options/organizations/{fiscal-code}/notices/{notice-number}") - @ClientHeaderParam(name = "Ocp-Apim-Subscription-Key", value = "${EcRestClient.ocpSubKey}") + @ClientHeaderParam(name = "Ocp-Apim-Subscription-Key", value = "${CreditorInstitutionRestClient.ocpSubKey}") Response verifyPaymentOptions( @PathParam("fiscal-code") String fiscalCode, @PathParam("notice-number") String noticeNumber, diff --git a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java index 50553b2..7229cb3 100644 --- a/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java +++ b/src/main/java/it/gov/pagopa/payment/options/exception/mapper/ExceptionMapper.java @@ -52,7 +52,7 @@ public Response mapCompositeException(CompositeException exception) { } @ServerExceptionMapper - private Response mapCreditorInstitutionException(CreditorInstitutionException creditorInstitutionException) { + public Response mapCreditorInstitutionException(CreditorInstitutionException creditorInstitutionException) { logger.error(creditorInstitutionException.getMessage(), creditorInstitutionException); return Response.status(creditorInstitutionException.getErrorResponse().getHttpStatusCode()) .entity(creditorInstitutionException.getErrorResponse()).build(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d6df921..b8a46cd 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -27,15 +27,18 @@ quarkus.log.console.json.additional-field."app_environment".value=${quarkus.appl ## KAFKA ################### -kafka.bootstrap.servers=${KAFKA_HOST:localhost:9092} +kafka.bootstrap.servers=${KAFKA_HOST:localhost:9093} mp.messaging.incoming.nodo-dei-pagamenti-cache.bootstrap.servers=${CACHE_EVT_HOST:localhost:9093} mp.messaging.incoming.nodo-dei-pagamenti-cache.topic=${CACHE_EVT_TOPIC:nodo-dei-pagamenti-cache} mp.messaging.incoming.nodo-dei-pagamenti-cache.key.serializer=org.apache.kafka.common.serialization.StringSerializer mp.messaging.incoming.nodo-dei-pagamenti-cache.offset.reset=latest mp.messaging.incoming.nodo-dei-pagamenti-cache.group.id=${quarkus.uuid} mp.messaging.incoming.nodo-dei-pagamenti-cache.security.protocol=${KAFKA_CONFIG_SECURITY_PROTOCOL:SASL_SSL} +%test.mp.messaging.incoming.nodo-dei-pagamenti-cache.security.protocol=${KAFKA_CONFIG_SECURITY_PROTOCOL:PLAINTEXT} mp.messaging.incoming.nodo-dei-pagamenti-cache.sasl.mechanism=${KAFKA_CONFIG_SASL_MECHANISM:PLAIN} +%test.mp.messaging.incoming.nodo-dei-pagamenti-cache.sasl.mechanism=${KAFKA_CONFIG_SASL_MECHANISM:} mp.messaging.incoming.nodo-dei-pagamenti-cache.sasl.jaas.config=${KAFKA_EH_CACHE_JAAS_CONFIG:} +%test.mp.messaging.incoming.nodo-dei-pagamenti-cache.sasl.jaas.config=${KAFKA_EH_CACHE_JAAS_CONFIG:test} mp.messaging.incoming.nodo-dei-pagamenti-cache.session.timeout.ms=${KAFKA_CONFIG_SESSION_TIMEOUT_MS:60000} mp.messaging.incoming.nodo-dei-pagamenti-cache.request.timeout.ms=${KAFKA_CONFIG_REQUEST_TIMEOUT_MS:60000} mp.messaging.incoming.nodo-dei-pagamenti-cache.connections.max.idle.ms=${KAFKA_CONFIG_CONNECTION_MAX_IDLE_TIME:180000} diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java index 7e57fcc..63c0525 100644 --- a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -1,9 +1,13 @@ package it.gov.pagopa.payment.options; +import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.http.Body; +import com.github.tomakehurst.wiremock.matching.EqualToPattern; +import com.github.tomakehurst.wiremock.matching.StringValuePattern; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import it.gov.pagopa.payment.options.models.ErrorResponse; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; @@ -27,27 +31,34 @@ public Map start() { wireMockServer.stubFor( get(urlEqualTo( - "/payment-options/organizations/77777777777/notices/311111111112222222")) + "/payment-options/organizations/77777777777/notices/311111111112222222" + + "?idPA=88888888888&idBrokerPA=88888888888&idStation=88888888888_01")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") - .withBody( - objectMapper.writeValueAsString( - PaymentOptionsResponse.builder().build() - ) + .withResponseBody( + new Body(objectMapper.writeValueAsString( + PaymentOptionsResponse.builder().standin(true).build() + )) ) ) ); wireMockServer.stubFor( get(urlEqualTo( - "/payment-options/organizations/87777777777/notices/311111111112222222")) + "/payment-options/organizations/87777777777/notices/311111111112222222" + + "?idPA=88888888888&idBrokerPA=88888888888&idStation=88888888888_01")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") - .withStatus(500) - .withBody( - objectMapper.writeValueAsString( - ErrorResponse.builder().build() - ) + .withStatus(412) + .withResponseBody( + new Body(objectMapper.writeValueAsString( + ErrorResponse.builder() + .httpStatusCode(500) + .httpStatusDescription("Error") + .appErrorCode("ODB_ERRID") + .errorMessage("TEST") + .build() + )) ) ) ); From 77847960a7db7c57e2b8a4e4d6d7d5b18767e869 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Fri, 13 Sep 2024 14:24:19 +0200 Subject: [PATCH 09/19] [PPANTT-81] feat: Updated unit testing for CreditorInstitutionRestClientTest --- .../services/CreditorInstitutionService.java | 35 +++-- .../payment/options/WireMockExtensions.java | 12 +- .../CreditorInstitutionRestClientTest.java | 30 ++++ .../CreditorInstitutionServiceTest.java | 134 ++++++++++++++++++ 4 files changed, 189 insertions(+), 22 deletions(-) create mode 100644 src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 892b5a3..34d1633 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -27,11 +27,11 @@ public class CreditorInstitutionService { CreditorInstitutionRestClient creditorInstitutionRestClient; public PaymentOptionsResponse getPaymentOptions( - String idPsp, String idBrokerPsp, String idStazione, + String idPsp, String idBrokerPsp, String noticeNumber, String fiscalCode, Station station) { if (station.getConnection().getIp() == null || - !station.getConnection().getIp().contains(APIM_FORWARDER_ENDPOINT)) { + !APIM_FORWARDER_ENDPOINT.contains(station.getConnection().getIp())) { throw new PaymentOptionsException(AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE, "[Payment Options] Station not configured to pass through the APIM Forwarder"); } @@ -43,17 +43,24 @@ public PaymentOptionsResponse getPaymentOptions( "[Payment Options] Station new verify endpoint not provided"); } - String[] verifyEndpointParts = - station.getVerifyPaymentOptionEndpoint().split("/",4); - String targetHost = verifyEndpointParts[0] + verifyEndpointParts[2]; - String[] hostSplit = verifyEndpointParts[2].split(":"); - Long targetPort = hostSplit.length > 1 ? - Long.parseLong(hostSplit[1]) : - verifyEndpointParts[0].contains(ProtocolEnum.HTTPS.name().toLowerCase()) ? - 443L : 80L; - String targetPath = verifyEndpointParts[3].concat( - String.format(PAYMENT_OPTIONS_SERVICE_SUFFIX, fiscalCode, noticeNumber)); - + String targetHost; + long targetPort; + String targetPath; + try { + String[] verifyEndpointParts = + station.getVerifyPaymentOptionEndpoint().split("/", 4); + targetHost = verifyEndpointParts[0] + verifyEndpointParts[2]; + String[] hostSplit = verifyEndpointParts[2].split(":"); + targetPort = hostSplit.length > 1 ? + Long.parseLong(hostSplit[1]) : + verifyEndpointParts[0].contains(ProtocolEnum.HTTPS.name().toLowerCase()) ? + 443L : 80L; + targetPath = verifyEndpointParts[3].concat( + String.format(PAYMENT_OPTIONS_SERVICE_SUFFIX, fiscalCode, noticeNumber)); + } catch (Exception e) { + logger.error("[Payment Options] Malformed Target URL: {}", e.getMessage()); + throw new PaymentOptionsException(AppErrorCodeEnum.ODP_SEMANTICA, e.getMessage()); + } try { return creditorInstitutionRestClient.callEcPaymentOptionsVerify( @@ -61,7 +68,7 @@ public PaymentOptionsResponse getPaymentOptions( station.getProxy() != null ? station.getProxy().getProxyHost() : null, station.getProxy() != null ? station.getProxy().getProxyPort() : null, targetHost, targetPort, targetPath, - idPsp, idBrokerPsp, idStazione, fiscalCode, noticeNumber + idPsp, idBrokerPsp, station.getStationCode(), fiscalCode, noticeNumber ); } catch (MalformedURLException e) { logger.error("[Payment Options] Malformed URL: {}", e.getMessage()); diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java index 63c0525..d143825 100644 --- a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -1,22 +1,18 @@ package it.gov.pagopa.payment.options; -import java.util.HashMap; -import java.util.Map; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.http.Body; -import com.github.tomakehurst.wiremock.matching.EqualToPattern; -import com.github.tomakehurst.wiremock.matching.StringValuePattern; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import it.gov.pagopa.payment.options.models.ErrorResponse; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import java.util.Map; import lombok.SneakyThrows; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; - public class WireMockExtensions implements QuarkusTestResourceLifecycleManager { diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 9277f08..9a20abe 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -4,15 +4,19 @@ import io.quarkus.test.junit.QuarkusTest; import it.gov.pagopa.payment.options.WireMockExtensions; import it.gov.pagopa.payment.options.exception.CreditorInstitutionException; +import it.gov.pagopa.payment.options.exception.PaymentOptionsException; import it.gov.pagopa.payment.options.models.clients.cache.Connection; import it.gov.pagopa.payment.options.models.clients.cache.Connection.ProtocolEnum; import it.gov.pagopa.payment.options.models.clients.cache.Station; import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; import jakarta.inject.Inject; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.net.MalformedURLException; + import static org.junit.jupiter.api.Assertions.*; @QuarkusTest @@ -49,5 +53,31 @@ void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { assertEquals(exception.getErrorResponse().getHttpStatusCode(), 500); } + @Test + void callEcPaymentOptionsVerifyShouldReturnUnreachableKOWithoutErrorResponse() { + PaymentOptionsException exception = + assertThrows(PaymentOptionsException.class, + () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + wiremockUrl, null, null, + "http://externalService", 443L, "/externalPath", + "08888888888", "88888888888", "88888888888_01", + "87777777777", "311111111112222222")); + assertNotNull(exception); + assertEquals(exception.getErrorCode(), AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE); + } + + + @Test + void callEcPaymentOptionsVerifyShouldReturnExceptionOnMalformedUrl() { + assertThrows(MalformedURLException.class, + () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + "AAAAAAA", null, null, + "http://externalService", 443L, "/externalPath", + "88888888888", "88888888888", "88888888888_01", + "87777777777", "311111111112222222")); + } + + + } diff --git a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java new file mode 100644 index 0000000..e94f707 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java @@ -0,0 +1,134 @@ +package it.gov.pagopa.payment.options.services; + +import io.quarkus.test.InjectMock; +import io.quarkus.test.junit.QuarkusTest; +import it.gov.pagopa.payment.options.clients.CreditorInstitutionRestClient; +import it.gov.pagopa.payment.options.exception.PaymentOptionsException; +import it.gov.pagopa.payment.options.models.clients.cache.Connection; +import it.gov.pagopa.payment.options.models.clients.cache.Connection.ProtocolEnum; +import it.gov.pagopa.payment.options.models.clients.cache.Station; +import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; +import it.gov.pagopa.payment.options.models.enums.AppErrorCodeEnum; +import jakarta.inject.Inject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.net.MalformedURLException; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +@QuarkusTest +class CreditorInstitutionServiceTest { + + @InjectMock + CreditorInstitutionRestClient creditorInstitutionRestClient; + + @Inject + CreditorInstitutionService creditorInstitutionService; + + @BeforeEach + public void init() { + Mockito.reset(creditorInstitutionRestClient); + } + + @Test + void getPaymentOptionsShouldReturnData() throws MalformedURLException { + when(creditorInstitutionRestClient.callEcPaymentOptionsVerify( + any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()) + ).thenReturn(PaymentOptionsResponse.builder().build()); + PaymentOptionsResponse paymentOptionsResponse = + assertDoesNotThrow(() -> creditorInstitutionService.getPaymentOptions( + "000001","000001","12345","322334", + Station.builder().stationCode("000001_01") + .connection( + Connection.builder() + .ip("localhost") + .protocol(ProtocolEnum.HTTP) + .port(8082L) + .build() + ) + .verifyPaymentOptionEndpoint("http://localhost:8080/test") + .verifyPaymentOptionEnabled(true) + .build() + )); + assertNotNull(paymentOptionsResponse); + verify(creditorInstitutionRestClient).callEcPaymentOptionsVerify( + any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + } + + @Test + void getPaymentOptionsShouldReturnExceptionOnMalformed() throws MalformedURLException { + when(creditorInstitutionRestClient.callEcPaymentOptionsVerify( + any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()) + ).thenThrow(new MalformedURLException()); + PaymentOptionsException paymentOptionsException = + assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( + "000001","000001","12345","322334", + Station.builder().stationCode("000001_01") + .connection( + Connection.builder() + .ip("localhost") + .protocol(ProtocolEnum.HTTP) + .port(8082L) + .build() + ) + .verifyPaymentOptionEndpoint("http://localhost:8080/test") + .verifyPaymentOptionEnabled(true) + .build() + )); + assertNotNull(paymentOptionsException); + assertEquals(paymentOptionsException.getErrorCode(), AppErrorCodeEnum.ODP_SEMANTICA); + verify(creditorInstitutionRestClient).callEcPaymentOptionsVerify( + any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + } + + @Test + void getPaymentOptionsShouldReturnExceptionOnMissingEndpoint() throws MalformedURLException { + PaymentOptionsException paymentOptionsException = + assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( + "000001","000001","12345","322334", + Station.builder().stationCode("000001_01") + .connection( + Connection.builder() + .ip("localhost") + .protocol(ProtocolEnum.HTTP) + .port(8082L) + .build() + ) + .verifyPaymentOptionEndpoint(null) + .verifyPaymentOptionEnabled(true) + .build() + )); + assertNotNull(paymentOptionsException); + assertEquals(paymentOptionsException.getErrorCode(), AppErrorCodeEnum.ODP_SEMANTICA); + verifyNoInteractions(creditorInstitutionRestClient); + } + + @Test + void getPaymentOptionsShouldReturnExceptionOnBrokerServiceUrl() throws MalformedURLException { + PaymentOptionsException paymentOptionsException = + assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( + "000001","000001","12345","322334", + Station.builder().stationCode("000001_01") + .connection( + Connection.builder() + .ip("localhost") + .protocol(ProtocolEnum.HTTP) + .port(8082L) + .build() + ) + .verifyPaymentOptionEndpoint(":8080") + .verifyPaymentOptionEnabled(true) + .build() + )); + assertNotNull(paymentOptionsException); + assertEquals(paymentOptionsException.getErrorCode(), AppErrorCodeEnum.ODP_SEMANTICA); + } + + +} From 27b5ebd3d1c465bf8ce29dc7ffd64b1f8c59f17a Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Fri, 13 Sep 2024 15:08:41 +0200 Subject: [PATCH 10/19] [PPANTT-81] feat: Updated docs --- .../CreditorInstitutionRestClientInterface.java | 4 +++- .../services/CreditorInstitutionService.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java index 93965f3..a7ffded 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java @@ -1,6 +1,5 @@ package it.gov.pagopa.payment.options.clients; -import it.gov.pagopa.payment.options.models.clients.creditorInstitution.PaymentOptionsResponse; import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.Path; @@ -9,6 +8,9 @@ import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam; +/** + * Template for the creditor institution REST client + */ public interface CreditorInstitutionRestClientInterface { @GET diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 34d1633..073b434 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -13,6 +13,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Service containing methods to manage call to the creditor institution REST service + */ @ApplicationScoped public class CreditorInstitutionService { @@ -26,6 +29,20 @@ public class CreditorInstitutionService { @Inject CreditorInstitutionRestClient creditorInstitutionRestClient; + /** + * Using the provided input attempts to call the creditor institution service + * to obtain the list paymentOptions related to the input + * + * The method contains checks regarding the endpoint to use, and attempts to + * extract the REST target params + * + * @param idPsp psp identifier + * @param idBrokerPsp broker psp identifier + * @param noticeNumber input notice number + * @param fiscalCode input fiscal code + * @param station station containing the connection config to use + * @return + */ public PaymentOptionsResponse getPaymentOptions( String idPsp, String idBrokerPsp, String noticeNumber, String fiscalCode, Station station) { From bac28d587a0b4ffe9a5831deda9dd5a9671647df Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Fri, 13 Sep 2024 15:11:33 +0200 Subject: [PATCH 11/19] [PPANTT-81] feat: Updated docs --- .../CreditorInstitutionRestClient.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java index ca72043..26f5d44 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -16,6 +16,9 @@ import java.net.MalformedURLException; import java.net.URL; +/** + * Rest Client for Creditor Institution services + */ @ApplicationScoped public class CreditorInstitutionRestClient { @@ -24,6 +27,23 @@ public class CreditorInstitutionRestClient { @Inject ObjectMapper objectMapper; + /** + * + * @param endpoint endpoint to use for the call (should be equivalent to the forwader( + * @param proxyHost proxy host, optional + * @param proxyPort proxy port, optional + * @param targetHost verify service host + * @param targetPort verify service port + * @param targetPath verify service path + * @param idPsp psp id to be used as parameter for the call + * @param idBrokerPsp broker id to be used as parameter for the call + * @param idStazione station id to be used for the call + * @param fiscalCode fiscal code to be used as input for the call + * @param noticeNumber notice number to be used as input for the call + * @return PaymentOptionResponse + * @throws MalformedURLException + * @throws PaymentOptionsException + */ public PaymentOptionsResponse callEcPaymentOptionsVerify( String endpoint, String proxyHost, Long proxyPort, String targetHost, Long targetPort, String targetPath, From 088544aa4a89e99462e875e0f297785b138a305e Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Fri, 13 Sep 2024 16:06:09 +0200 Subject: [PATCH 12/19] [PPANTT-81] feat: Updated rest call and related tests and interfaces --- .../clients/CreditorInstitutionRestClient.java | 13 ++++++------- .../CreditorInstitutionRestClientInterface.java | 6 +++--- .../services/CreditorInstitutionService.java | 8 ++++---- .../payment/options/WireMockExtensions.java | 6 ++---- .../CreditorInstitutionRestClientTest.java | 12 ++++-------- .../CreditorInstitutionServiceTest.java | 17 +++++++++-------- 6 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java index 26f5d44..24e9d46 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -35,9 +35,6 @@ public class CreditorInstitutionRestClient { * @param targetHost verify service host * @param targetPort verify service port * @param targetPath verify service path - * @param idPsp psp id to be used as parameter for the call - * @param idBrokerPsp broker id to be used as parameter for the call - * @param idStazione station id to be used for the call * @param fiscalCode fiscal code to be used as input for the call * @param noticeNumber notice number to be used as input for the call * @return PaymentOptionResponse @@ -47,8 +44,8 @@ public class CreditorInstitutionRestClient { public PaymentOptionsResponse callEcPaymentOptionsVerify( String endpoint, String proxyHost, Long proxyPort, String targetHost, Long targetPort, String targetPath, - String idPsp, String idBrokerPsp, - String idStazione, String fiscalCode, String noticeNumber) +// String idPA, String idBrokerPA, String idStazione, + String fiscalCode, String noticeNumber) throws MalformedURLException { RestClientBuilder builder = @@ -60,8 +57,10 @@ public PaymentOptionsResponse callEcPaymentOptionsVerify( CreditorInstitutionRestClientInterface.class); try (Response response = ecRestClientInterface.verifyPaymentOptions( - fiscalCode, noticeNumber, idPsp, idBrokerPsp, idStazione, - targetHost, targetPort.intValue(), targetPath)) { + fiscalCode, noticeNumber, +// idPA, idBrokerPA, idStazione, + targetHost, targetPort.intValue(), + targetPath)) { if (response.getStatus() != 200) { manageErrorResponse(response); diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java index a7ffded..61708e2 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientInterface.java @@ -19,9 +19,9 @@ public interface CreditorInstitutionRestClientInterface { Response verifyPaymentOptions( @PathParam("fiscal-code") String fiscalCode, @PathParam("notice-number") String noticeNumber, - @QueryParam("idPA") String idPA, - @QueryParam("idBrokerPA") String idBrokerPA, - @QueryParam("idStation") String idStation, +// @QueryParam("idPA") String idPA, +// @QueryParam("idBrokerPA") String idBrokerPA, +// @QueryParam("idStation") String idStation, @HeaderParam("X-Host-Url") String hostUrl, @HeaderParam("X-Host-Port") Integer hostPort, @HeaderParam("X-Host-Path") String hostPath diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 073b434..941f496 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -36,15 +36,15 @@ public class CreditorInstitutionService { * The method contains checks regarding the endpoint to use, and attempts to * extract the REST target params * - * @param idPsp psp identifier - * @param idBrokerPsp broker psp identifier +// * @param idPA pa identifier +// * @param idBrokerPA broker pa identifier * @param noticeNumber input notice number * @param fiscalCode input fiscal code * @param station station containing the connection config to use * @return */ public PaymentOptionsResponse getPaymentOptions( - String idPsp, String idBrokerPsp, + //String idPA, String idBrokerPA, String noticeNumber, String fiscalCode, Station station) { if (station.getConnection().getIp() == null || @@ -85,7 +85,7 @@ public PaymentOptionsResponse getPaymentOptions( station.getProxy() != null ? station.getProxy().getProxyHost() : null, station.getProxy() != null ? station.getProxy().getProxyPort() : null, targetHost, targetPort, targetPath, - idPsp, idBrokerPsp, station.getStationCode(), fiscalCode, noticeNumber + fiscalCode, noticeNumber ); } catch (MalformedURLException e) { logger.error("[Payment Options] Malformed URL: {}", e.getMessage()); diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java index d143825..91689b0 100644 --- a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -27,8 +27,7 @@ public Map start() { wireMockServer.stubFor( get(urlEqualTo( - "/payment-options/organizations/77777777777/notices/311111111112222222" - + "?idPA=88888888888&idBrokerPA=88888888888&idStation=88888888888_01")) + "/payment-options/organizations/77777777777/notices/311111111112222222")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withResponseBody( @@ -41,8 +40,7 @@ public Map start() { wireMockServer.stubFor( get(urlEqualTo( - "/payment-options/organizations/87777777777/notices/311111111112222222" - + "?idPA=88888888888&idBrokerPA=88888888888&idStation=88888888888_01")) + "/payment-options/organizations/87777777777/notices/311111111112222222")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withStatus(412) diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 9a20abe..594f9d3 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -35,8 +35,7 @@ void callEcPaymentOptionsVerifyShouldReturnData() { assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( wiremockUrl, null, null, "http://externalService", 443L, "/externalPath", - "88888888888", "88888888888", "88888888888_01", - "77777777777", "311111111112222222")); + "88888888888", "88888888888")); assertNotNull(paymentOptionsResponse); } @@ -47,8 +46,7 @@ void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( wiremockUrl, null, null, "http://externalService", 443L, "/externalPath", - "88888888888", "88888888888", "88888888888_01", - "87777777777", "311111111112222222")); + "88888888888", "88888888888")); assertNotNull(exception); assertEquals(exception.getErrorResponse().getHttpStatusCode(), 500); } @@ -60,8 +58,7 @@ void callEcPaymentOptionsVerifyShouldReturnUnreachableKOWithoutErrorResponse() { () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( wiremockUrl, null, null, "http://externalService", 443L, "/externalPath", - "08888888888", "88888888888", "88888888888_01", - "87777777777", "311111111112222222")); + "08888888888", "88888888888")); assertNotNull(exception); assertEquals(exception.getErrorCode(), AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE); } @@ -73,8 +70,7 @@ void callEcPaymentOptionsVerifyShouldReturnExceptionOnMalformedUrl() { () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( "AAAAAAA", null, null, "http://externalService", 443L, "/externalPath", - "88888888888", "88888888888", "88888888888_01", - "87777777777", "311111111112222222")); + "88888888888", "88888888888")); } diff --git a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java index e94f707..210a06a 100644 --- a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java @@ -39,11 +39,11 @@ public void init() { @Test void getPaymentOptionsShouldReturnData() throws MalformedURLException { when(creditorInstitutionRestClient.callEcPaymentOptionsVerify( - any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()) + any(), any(), any(), any(), any(), any(), any(), any()) ).thenReturn(PaymentOptionsResponse.builder().build()); PaymentOptionsResponse paymentOptionsResponse = assertDoesNotThrow(() -> creditorInstitutionService.getPaymentOptions( - "000001","000001","12345","322334", + "000001","000001", Station.builder().stationCode("000001_01") .connection( Connection.builder() @@ -58,17 +58,17 @@ void getPaymentOptionsShouldReturnData() throws MalformedURLException { )); assertNotNull(paymentOptionsResponse); verify(creditorInstitutionRestClient).callEcPaymentOptionsVerify( - any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + any(), any(), any(), any(), any(), any(), any(), any()); } @Test void getPaymentOptionsShouldReturnExceptionOnMalformed() throws MalformedURLException { when(creditorInstitutionRestClient.callEcPaymentOptionsVerify( - any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()) + any(), any(), any(), any(), any(), any(), any(), any()) ).thenThrow(new MalformedURLException()); PaymentOptionsException paymentOptionsException = assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( - "000001","000001","12345","322334", + "000001","000001", Station.builder().stationCode("000001_01") .connection( Connection.builder() @@ -84,14 +84,15 @@ void getPaymentOptionsShouldReturnExceptionOnMalformed() throws MalformedURLExce assertNotNull(paymentOptionsException); assertEquals(paymentOptionsException.getErrorCode(), AppErrorCodeEnum.ODP_SEMANTICA); verify(creditorInstitutionRestClient).callEcPaymentOptionsVerify( - any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + any(), any(), any(), any(), any(), any(), any(), any() + ); } @Test void getPaymentOptionsShouldReturnExceptionOnMissingEndpoint() throws MalformedURLException { PaymentOptionsException paymentOptionsException = assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( - "000001","000001","12345","322334", + "000001","000001", Station.builder().stationCode("000001_01") .connection( Connection.builder() @@ -113,7 +114,7 @@ void getPaymentOptionsShouldReturnExceptionOnMissingEndpoint() throws MalformedU void getPaymentOptionsShouldReturnExceptionOnBrokerServiceUrl() throws MalformedURLException { PaymentOptionsException paymentOptionsException = assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( - "000001","000001","12345","322334", + "000001","000001", Station.builder().stationCode("000001_01") .connection( Connection.builder() From 4123e842e8cbd37bcd87a28a07441222394388ad Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Fri, 13 Sep 2024 16:38:40 +0200 Subject: [PATCH 13/19] [PPANTT-81] feat: Updated CreditorInstitutionService, CreditorInstitutionServiceTest, Station --- .../payment/options/models/clients/cache/Station.java | 4 ++-- .../options/services/CreditorInstitutionService.java | 4 ++-- .../options/services/CreditorInstitutionServiceTest.java | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java index 90ffb9d..1b17687 100644 --- a/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java +++ b/src/main/java/it/gov/pagopa/payment/options/models/clients/cache/Station.java @@ -71,7 +71,7 @@ public class Station { @JsonProperty("verify_payment_option_enabled") private Boolean verifyPaymentOptionEnabled = false; - @JsonProperty("verify_payment_option_endpoint") - private String verifyPaymentOptionEndpoint; + @JsonProperty("rest_endpoint") + private String restEndpoint; } diff --git a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java index 941f496..2ac1a17 100644 --- a/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java +++ b/src/main/java/it/gov/pagopa/payment/options/services/CreditorInstitutionService.java @@ -55,7 +55,7 @@ public PaymentOptionsResponse getPaymentOptions( String endpoint = getEndpoint(station); - if (station.getVerifyPaymentOptionEndpoint() == null) { + if (station.getRestEndpoint() == null) { throw new PaymentOptionsException(AppErrorCodeEnum.ODP_SEMANTICA, "[Payment Options] Station new verify endpoint not provided"); } @@ -65,7 +65,7 @@ public PaymentOptionsResponse getPaymentOptions( String targetPath; try { String[] verifyEndpointParts = - station.getVerifyPaymentOptionEndpoint().split("/", 4); + station.getRestEndpoint().split("/", 4); targetHost = verifyEndpointParts[0] + verifyEndpointParts[2]; String[] hostSplit = verifyEndpointParts[2].split(":"); targetPort = hostSplit.length > 1 ? diff --git a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java index 210a06a..88553cd 100644 --- a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java @@ -52,7 +52,7 @@ void getPaymentOptionsShouldReturnData() throws MalformedURLException { .port(8082L) .build() ) - .verifyPaymentOptionEndpoint("http://localhost:8080/test") + .restEndpoint("http://localhost:8080/test") .verifyPaymentOptionEnabled(true) .build() )); @@ -77,7 +77,7 @@ void getPaymentOptionsShouldReturnExceptionOnMalformed() throws MalformedURLExce .port(8082L) .build() ) - .verifyPaymentOptionEndpoint("http://localhost:8080/test") + .restEndpoint("http://localhost:8080/test") .verifyPaymentOptionEnabled(true) .build() )); @@ -101,7 +101,7 @@ void getPaymentOptionsShouldReturnExceptionOnMissingEndpoint() throws MalformedU .port(8082L) .build() ) - .verifyPaymentOptionEndpoint(null) + .restEndpoint(null) .verifyPaymentOptionEnabled(true) .build() )); @@ -123,7 +123,7 @@ void getPaymentOptionsShouldReturnExceptionOnBrokerServiceUrl() throws Malformed .port(8082L) .build() ) - .verifyPaymentOptionEndpoint(":8080") + .restEndpoint(":8080") .verifyPaymentOptionEnabled(true) .build() )); From 0c4e2487de3df19daf297503129ff3b2dc91c3cc Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Thu, 19 Sep 2024 17:19:03 +0200 Subject: [PATCH 14/19] [PPANTT-82] feat: Updated CreditorInstitutionRestClientTest --- .../options/clients/CreditorInstitutionRestClientTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 594f9d3..25463ad 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -35,7 +35,7 @@ void callEcPaymentOptionsVerifyShouldReturnData() { assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( wiremockUrl, null, null, "http://externalService", 443L, "/externalPath", - "88888888888", "88888888888")); + "77777777777", "311111111112222222")); assertNotNull(paymentOptionsResponse); } @@ -46,7 +46,7 @@ void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( wiremockUrl, null, null, "http://externalService", 443L, "/externalPath", - "88888888888", "88888888888")); + "87777777777", "311111111112222222")); assertNotNull(exception); assertEquals(exception.getErrorResponse().getHttpStatusCode(), 500); } From 08d54f1f0d3b67c952515e8c44bf74ec04b7ca37 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Mon, 23 Sep 2024 19:00:01 +0200 Subject: [PATCH 15/19] [PPANTT-81] feat: Updated tests --- .../CreditorInstitutionRestClientTest.java | 9 ++++ .../CreditorInstitutionServiceTest.java | 45 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 25463ad..33b9008 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -73,6 +73,15 @@ void callEcPaymentOptionsVerifyShouldReturnExceptionOnMalformedUrl() { "88888888888", "88888888888")); } + @Test + void callEcPaymentOptionsVerifyShouldReturnExceptionOnWrongProxy() { + assertThrows(Exception.class, + () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + "AAAAAAA", "AAAAAAA%%%", 8081L, + "http://externalService", 443L, "/externalPath", + "88888888888", "88888888888")); + } + diff --git a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java index 88553cd..6b0ee6f 100644 --- a/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/services/CreditorInstitutionServiceTest.java @@ -61,6 +61,31 @@ void getPaymentOptionsShouldReturnData() throws MalformedURLException { any(), any(), any(), any(), any(), any(), any(), any()); } + @Test + void getPaymentOptionsShouldReturnDataWithDefaultPort() throws MalformedURLException { + when(creditorInstitutionRestClient.callEcPaymentOptionsVerify( + any(), any(), any(), any(), any(), any(), any(), any()) + ).thenReturn(PaymentOptionsResponse.builder().build()); + PaymentOptionsResponse paymentOptionsResponse = + assertDoesNotThrow(() -> creditorInstitutionService.getPaymentOptions( + "000001","000001", + Station.builder().stationCode("000001_01") + .connection( + Connection.builder() + .ip("localhost") + .protocol(ProtocolEnum.HTTP) + .port(8082L) + .build() + ) + .restEndpoint("http://localhost/test") + .verifyPaymentOptionEnabled(true) + .build() + )); + assertNotNull(paymentOptionsResponse); + verify(creditorInstitutionRestClient).callEcPaymentOptionsVerify( + any(), any(), any(), any(), any(), any(), any(), any()); + } + @Test void getPaymentOptionsShouldReturnExceptionOnMalformed() throws MalformedURLException { when(creditorInstitutionRestClient.callEcPaymentOptionsVerify( @@ -131,5 +156,25 @@ void getPaymentOptionsShouldReturnExceptionOnBrokerServiceUrl() throws Malformed assertEquals(paymentOptionsException.getErrorCode(), AppErrorCodeEnum.ODP_SEMANTICA); } + @Test + void getPaymentOptionsShouldReturnExceptionOnMissingConnection() throws MalformedURLException { + PaymentOptionsException paymentOptionsException = + assertThrows(PaymentOptionsException.class, () -> creditorInstitutionService.getPaymentOptions( + "000001","000001", + Station.builder().stationCode("000001_01") + .connection( + Connection.builder() + .protocol(ProtocolEnum.HTTP) + .port(8082L) + .build() + ) + .restEndpoint(":8080") + .verifyPaymentOptionEnabled(true) + .build() + )); + assertNotNull(paymentOptionsException); + assertEquals(paymentOptionsException.getErrorCode(), AppErrorCodeEnum.ODP_STAZIONE_INT_PA_IRRAGGIUNGIBILE); + } + } From 5b2433372cb63e15302a64f2254a0583b68cdbff Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Tue, 24 Sep 2024 13:00:05 +0200 Subject: [PATCH 16/19] [PPANTT-81] feat: Updated tests --- .../clients/CreditorInstitutionRestClient.java | 4 ---- .../payment/options/WireMockExtensions.java | 3 ++- .../CreditorInstitutionRestClientTest.java | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java index 24e9d46..0c3ecb6 100644 --- a/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java +++ b/src/main/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClient.java @@ -62,10 +62,6 @@ public PaymentOptionsResponse callEcPaymentOptionsVerify( targetHost, targetPort.intValue(), targetPath)) { - if (response.getStatus() != 200) { - manageErrorResponse(response); - } - return objectMapper.readValue( response.readEntity(String.class), PaymentOptionsResponse.class); diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java index 91689b0..7e9b283 100644 --- a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -60,7 +60,8 @@ public Map start() { return Map.of( "CreditorInstitutionRestClient.apimEndpoint", wireMockServer.baseUrl(), - "CreditorInstitutionRestClient.ocpSubKey", "test" + "CreditorInstitutionRestClient.ocpSubKey", "test", + "wiremock.port", String.valueOf(wireMockServer.port()) ); } diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 33b9008..517c06e 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -26,6 +26,10 @@ class CreditorInstitutionRestClientTest { @ConfigProperty(name = "CreditorInstitutionRestClient.apimEndpoint") private String wiremockUrl; + @ConfigProperty(name = "wiremock.port") + private String wiremockPort; + + @Inject CreditorInstitutionRestClient creditorInstitutionRestClient; @@ -39,6 +43,17 @@ void callEcPaymentOptionsVerifyShouldReturnData() { assertNotNull(paymentOptionsResponse); } + @Test + void callEcPaymentOptionsVerifyShouldReturnDataWithProxy() { + PaymentOptionsResponse paymentOptionsResponse = + assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + wiremockUrl, "http://localhost", Long.valueOf(wiremockPort), + "http://externalService", 443L, "/externalPath", + "77777777777", "311111111112222222")); + assertNotNull(paymentOptionsResponse); + } + + @Test void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { CreditorInstitutionException exception = From 5e4ed6a94f70ff9c71246a2588542d06bfccbfaa Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Tue, 24 Sep 2024 14:32:54 +0200 Subject: [PATCH 17/19] [PPANTT-81] feat: Updated CreditorInstitutionRestClientTest --- .../options/clients/CreditorInstitutionRestClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 517c06e..bd67a07 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -47,7 +47,7 @@ void callEcPaymentOptionsVerifyShouldReturnData() { void callEcPaymentOptionsVerifyShouldReturnDataWithProxy() { PaymentOptionsResponse paymentOptionsResponse = assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( - wiremockUrl, "http://localhost", Long.valueOf(wiremockPort), + wiremockUrl, wiremockUrl.split(":",2)[0], Long.valueOf(wiremockPort), "http://externalService", 443L, "/externalPath", "77777777777", "311111111112222222")); assertNotNull(paymentOptionsResponse); From 127f5497a9c128c2dc862a25e500ee82ab1d8083 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Tue, 24 Sep 2024 14:39:06 +0200 Subject: [PATCH 18/19] [PPANTT-81] feat: Updated CreditorInstitutionRestClientTest --- .../options/clients/CreditorInstitutionRestClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index bd67a07..86851b6 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -47,7 +47,7 @@ void callEcPaymentOptionsVerifyShouldReturnData() { void callEcPaymentOptionsVerifyShouldReturnDataWithProxy() { PaymentOptionsResponse paymentOptionsResponse = assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( - wiremockUrl, wiremockUrl.split(":",2)[0], Long.valueOf(wiremockPort), + wiremockUrl, "http:"+wiremockUrl.split(":",3)[1], Long.valueOf(wiremockPort), "http://externalService", 443L, "/externalPath", "77777777777", "311111111112222222")); assertNotNull(paymentOptionsResponse); From 5488238afe9449e2f12f08c17bcdb4b46cbef2f3 Mon Sep 17 00:00:00 2001 From: Alessio Cialini Date: Tue, 24 Sep 2024 14:50:15 +0200 Subject: [PATCH 19/19] [PPANTT-81] feat: Updated CreditorInstitutionRestClientTest --- .../payment/options/WireMockExtensions.java | 9 ++++++++ .../CreditorInstitutionRestClientTest.java | 22 +++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java index 7e9b283..bb3d638 100644 --- a/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java +++ b/src/test/java/it/gov/pagopa/payment/options/WireMockExtensions.java @@ -38,6 +38,15 @@ public Map start() { ) ); + wireMockServer.stubFor( + get(urlEqualTo( + "/payment-options/organizations/97777777777/notices/311111111112222222")) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody("AAAAAAAA") + ) + ); + wireMockServer.stubFor( get(urlEqualTo( "/payment-options/organizations/87777777777/notices/311111111112222222")) diff --git a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java index 86851b6..4da7e48 100644 --- a/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java +++ b/src/test/java/it/gov/pagopa/payment/options/clients/CreditorInstitutionRestClientTest.java @@ -43,17 +43,6 @@ void callEcPaymentOptionsVerifyShouldReturnData() { assertNotNull(paymentOptionsResponse); } - @Test - void callEcPaymentOptionsVerifyShouldReturnDataWithProxy() { - PaymentOptionsResponse paymentOptionsResponse = - assertDoesNotThrow(() -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( - wiremockUrl, "http:"+wiremockUrl.split(":",3)[1], Long.valueOf(wiremockPort), - "http://externalService", 443L, "/externalPath", - "77777777777", "311111111112222222")); - assertNotNull(paymentOptionsResponse); - } - - @Test void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { CreditorInstitutionException exception = @@ -66,6 +55,17 @@ void callEcPaymentOptionsVerifyShouldReturnErrorResponse() { assertEquals(exception.getErrorResponse().getHttpStatusCode(), 500); } + @Test + void callEcPaymentOptionsVerifyShouldReturnErrorOnUnexpectedContent() { + PaymentOptionsException exception = + assertThrows(PaymentOptionsException.class, + () -> creditorInstitutionRestClient.callEcPaymentOptionsVerify( + wiremockUrl, null, null, + "http://externalService", 443L, "/externalPath", + "97777777777", "311111111112222222")); + assertNotNull(exception); + } + @Test void callEcPaymentOptionsVerifyShouldReturnUnreachableKOWithoutErrorResponse() { PaymentOptionsException exception =