From c601f18fa461dfa521e74365c5a7d869cad224e8 Mon Sep 17 00:00:00 2001 From: Alberto Gelmi Date: Mon, 9 Oct 2023 11:29:02 +0200 Subject: [PATCH 1/9] GP-24: vpos - management of simultaneous calls to the resume APIs --- .../CreditCardPaymentController.java | 11 ++- .../controller/XPayPaymentController.java | 2 +- .../dto/enums/PaymentRequestStatusEnum.java | 3 +- .../PaymentRequestLockRepository.java | 16 ++++ .../gateway/service/CcPaymentInfoService.java | 1 + .../gateway/service/CcResumeStep1Service.java | 37 ++++++-- .../gateway/service/CcResumeStep2Service.java | 40 ++++++-- .../service/CcResumeStep1ServiceTest.java | 91 +++++++++++++------ .../service/CcResumeStep2ServiceTest.java | 89 ++++++++++++------ 9 files changed, 216 insertions(+), 74 deletions(-) create mode 100644 src/main/java/it/pagopa/pm/gateway/repository/PaymentRequestLockRepository.java diff --git a/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java b/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java index d3d924a9..21db83c1 100644 --- a/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java +++ b/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java @@ -96,8 +96,12 @@ public ResponseEntity resumeCreditCardPayment(@Request @RequestBody CreditCardResumeRequest request) { MdcUtils.setMdcFields(mdcFields); log.info("START - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_METHOD, requestId); + ResponseEntity responseEntity = null; VposResumeMethodResponse response = new VposResumeMethodResponse(requestId); - resumeStep1Service.startResumeStep1(request, requestId.toString()); + + if (resumeStep1Service.prepareResumeStep1(requestId.toString())) { + resumeStep1Service.startResumeStep1(request, requestId.toString()); + } log.info("END - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_METHOD, requestId); return ResponseEntity.status(HttpStatus.OK).body(response); @@ -109,7 +113,10 @@ public ResponseEntity resumeCreditCardPaymentStep2(@RequestHeader(requir MdcUtils.setMdcFields(mdcFields); log.info("START - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_CHALLENGE, requestId); - resumeStep2Service.startResumeStep2(requestId); + if (resumeStep2Service.prepareResumeStep2(requestId)) { + resumeStep2Service.startResumeStep2(requestId); + } + log.info("END - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_CHALLENGE, requestId); String vposPollingRedirect = vposPollingUrl + requestId; diff --git a/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java b/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java index 316b6c95..9a188c73 100644 --- a/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java +++ b/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java @@ -233,7 +233,7 @@ private ResponseEntity createXPayAuthPollingResponse(Paymen XPayPollingResponse response = new XPayPollingResponse(); response.setRequestId(requestId); response.setPaymentRequestStatusEnum(statusEnum); - if (statusEnum.equals(CREATED)) { + if (isStatusOneOf(statusEnum, CREATED, PROCESSING)) { response.setHtml(paymentRequestEntity.getXpayHtml()); } else if (isStatusOneOf(statusEnum, AUTHORIZED, DENIED, CANCELLED)) { OutcomeXpayGatewayResponse outcomeXpayGatewayResponse = buildOutcomeXpayGateway(paymentRequestEntity.getErrorCode(), diff --git a/src/main/java/it/pagopa/pm/gateway/dto/enums/PaymentRequestStatusEnum.java b/src/main/java/it/pagopa/pm/gateway/dto/enums/PaymentRequestStatusEnum.java index 523a6b46..802c3d00 100644 --- a/src/main/java/it/pagopa/pm/gateway/dto/enums/PaymentRequestStatusEnum.java +++ b/src/main/java/it/pagopa/pm/gateway/dto/enums/PaymentRequestStatusEnum.java @@ -10,7 +10,8 @@ public enum PaymentRequestStatusEnum { CREATED(1L, "Creata"), AUTHORIZED(2L, "Autorizzazione concessa"), DENIED(3L, "Autorizzazione negata"), - CANCELLED(4L, "Cancellata"); + CANCELLED(4L, "Cancellata"), + PROCESSING(5L, "In elaborazione"); private static final Map map = new HashMap<>(values().length, 1); diff --git a/src/main/java/it/pagopa/pm/gateway/repository/PaymentRequestLockRepository.java b/src/main/java/it/pagopa/pm/gateway/repository/PaymentRequestLockRepository.java new file mode 100644 index 00000000..22233272 --- /dev/null +++ b/src/main/java/it/pagopa/pm/gateway/repository/PaymentRequestLockRepository.java @@ -0,0 +1,16 @@ +package it.pagopa.pm.gateway.repository; + +import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; +import org.springframework.stereotype.Repository; + +import javax.persistence.LockModeType; + +@Repository +public interface PaymentRequestLockRepository extends JpaRepository { + + @Lock(LockModeType.PESSIMISTIC_WRITE) + PaymentRequestEntity findByGuid(String guid); + +} diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcPaymentInfoService.java b/src/main/java/it/pagopa/pm/gateway/service/CcPaymentInfoService.java index 0fd5b179..23918539 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcPaymentInfoService.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcPaymentInfoService.java @@ -83,6 +83,7 @@ private CcPaymentInfoResponse buildCcPaymentInfoResponse(PaymentRequestEntity pa } switch (paymentRequestStatusEnum) { case CREATED: + case PROCESSING: ThreeDS2ResponseTypeEnum responseTypeEnum = valueOf(paymentRequestEntity.getResponseType()); response.setThreeDS2ResponseTypeEnum(responseTypeEnum); response.setVposUrl(vposUrl); diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java index 541a6677..5225d14d 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java @@ -3,9 +3,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import it.pagopa.pm.gateway.dto.creditcard.CreditCardResumeRequest; import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.enums.ThreeDS2ResponseTypeEnum; import it.pagopa.pm.gateway.dto.vpos.MethodCompletedEnum; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; import it.pagopa.pm.gateway.service.async.CcResumeStep1AsyncService; import it.pagopa.pm.gateway.utils.VPosRequestUtils; @@ -14,6 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.util.Map; import java.util.Objects; @@ -27,6 +31,9 @@ public class CcResumeStep1Service { @Value("${vpos.requestUrl}") private String vposUrl; + @Autowired + private PaymentRequestLockRepository paymentRequestLockRepository; + @Autowired private PaymentRequestRepository paymentRequestRepository; @@ -39,23 +46,39 @@ public class CcResumeStep1Service { @Autowired private CcResumeStep1AsyncService ccResumeStep1AsyncService; - public void startResumeStep1(CreditCardResumeRequest request, String requestId) { - PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId); + @Transactional(propagation = Propagation.REQUIRES_NEW) + public boolean prepareResumeStep1(String requestId) { + PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId); if (Objects.isNull(entity)) { log.error("No CreditCard request entity has been found for requestId: " + requestId); - return; + return false; } if (Objects.nonNull(entity.getAuthorizationOutcome())) { log.warn(String.format("requestId %s already processed", requestId)); entity.setErrorMessage("requestId already processed"); - return; + return false; + } + + String responseType = entity.getResponseType(); + if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) + && responseType != null + && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) { + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + paymentRequestLockRepository.save(entity); + return true; } - processResume(request, entity, requestId); + + return false; + } + + public void startResumeStep1(CreditCardResumeRequest request, String requestId) { + PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId); + processResume(request, entity); } - private void processResume(CreditCardResumeRequest request, PaymentRequestEntity entity, String requestId) { + private void processResume(CreditCardResumeRequest request, PaymentRequestEntity entity) { String methodCompleted = request.getMethodCompleted(); String responseType = entity.getResponseType(); String correlationId = entity.getCorrelationId(); @@ -68,7 +91,7 @@ private void processResume(CreditCardResumeRequest request, PaymentRequestEntity ccResumeStep1AsyncService.executeStep1(params, entity, stepZeroRequest); } } catch (Exception e) { - log.error("error during execution of resume for requestId {}", requestId, e); + log.error("error during execution of resume for requestId {}", entity.getGuid(), e); } } } diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java index da499543..819e9101 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.enums.ThreeDS2ResponseTypeEnum; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; import it.pagopa.pm.gateway.service.async.CcResumeStep2AsyncService; import it.pagopa.pm.gateway.utils.VPosRequestUtils; @@ -11,47 +13,69 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.util.Map; import java.util.Objects; @Service @Slf4j +@Transactional @NoArgsConstructor public class CcResumeStep2Service { + private PaymentRequestLockRepository paymentRequestLockRepository; private PaymentRequestRepository paymentRequestRepository; private VPosRequestUtils vPosRequestUtils; private ObjectMapper objectMapper; private CcResumeStep2AsyncService ccResumeStep2AsyncService; @Autowired - public CcResumeStep2Service(PaymentRequestRepository paymentRequestRepository, + public CcResumeStep2Service(PaymentRequestLockRepository paymentRequestLockRepository, + PaymentRequestRepository paymentRequestRepository, VPosRequestUtils vPosRequestUtils, ObjectMapper objectMapper, CcResumeStep2AsyncService ccResumeStep2AsyncService) { + this.paymentRequestLockRepository = paymentRequestLockRepository; this.paymentRequestRepository = paymentRequestRepository; this.vPosRequestUtils = vPosRequestUtils; this.objectMapper = objectMapper; this.ccResumeStep2AsyncService = ccResumeStep2AsyncService; } - public void startResumeStep2(String requestId) { - PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId); + @Transactional(propagation = Propagation.REQUIRES_NEW) + public boolean prepareResumeStep2(String requestId) { + PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId); + if (Objects.isNull(entity)) { log.error("No CreditCard request entity has been found for requestId: " + requestId); - return; + return false; } if (Objects.nonNull(entity.getAuthorizationOutcome())) { log.warn(String.format("requestId %s already processed", requestId)); entity.setErrorMessage("requestId already processed"); - return; + return false; + } + + String responseType = entity.getResponseType(); + if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) + && responseType != null + && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) { + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + paymentRequestLockRepository.save(entity); + return true; } - processResume(entity, requestId); + return false; + } + + public void startResumeStep2(String requestId) { + PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId); + processResume(entity); } - private void processResume(PaymentRequestEntity entity, String requestId) { + private void processResume(PaymentRequestEntity entity) { String responseType = entity.getResponseType(); String correlationId = entity.getCorrelationId(); try { @@ -62,7 +86,7 @@ private void processResume(PaymentRequestEntity entity, String requestId) { ccResumeStep2AsyncService.executeStep2(params, entity, stepZeroRequest); } } catch (Exception e) { - log.error("error during execution of resume for requestId {}", requestId, e); + log.error("error during execution of resume for requestId {}", entity.getGuid(), e); } } } diff --git a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java index de3940ac..43b9ffb3 100644 --- a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java +++ b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java @@ -7,14 +7,16 @@ import it.pagopa.pm.gateway.dto.config.VposClientConfig; import it.pagopa.pm.gateway.dto.creditcard.CreditCardResumeRequest; import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.enums.ThreeDS2ResponseTypeEnum; -import it.pagopa.pm.gateway.dto.vpos.AuthResponse; import it.pagopa.pm.gateway.dto.vpos.ThreeDS2Response; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; import it.pagopa.pm.gateway.service.async.CcResumeStep1AsyncService; import it.pagopa.pm.gateway.utils.VPosRequestUtils; import it.pagopa.pm.gateway.utils.VPosResponseUtils; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,7 +38,7 @@ @RunWith(MockitoJUnitRunner.class) @SpringBootTest(classes = CcResumeStep1Service.class) public class CcResumeStep1ServiceTest { - public static final String RESULT_CODE_00 = "00"; + // public static final String RESULT_CODE_00 = "00"; private final ClientConfig clientConfig = new ClientConfig(); @Spy @@ -57,6 +59,8 @@ public void setUpProperties() { clientConfig.setVpos(vposClientConfig); } + @Mock + private PaymentRequestLockRepository paymentRequestLockRepository; @Mock private PaymentRequestRepository paymentRequestRepository; @Mock @@ -71,21 +75,44 @@ public void setUpProperties() { private final String UUID_SAMPLE = "8d8b30e3-de52-4f1c-a71c-9905a8043dac"; @Test - public void startResume_Test_EntityNull() { - CreditCardResumeRequest request = ValidBeans.createCreditCardResumeRequest(true); - when(paymentRequestRepository.findByGuid(any())).thenReturn(null); - service.startResumeStep1(request, UUID_SAMPLE); - verify(service).startResumeStep1(request, UUID_SAMPLE); + public void prepareResume_Test_EntityNull() { + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(null); + boolean check = service.prepareResumeStep1(UUID_SAMPLE); + verify(service).prepareResumeStep1(UUID_SAMPLE); + Assert.assertFalse(check); } @Test - public void startResume_Test_EntityAlreadyAuthorized() { - CreditCardResumeRequest request = ValidBeans.createCreditCardResumeRequest(true); + public void prepareResume_Test_EntityAlreadyAuthorized() { PaymentRequestEntity entity = new PaymentRequestEntity(); entity.setAuthorizationOutcome(true); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); - service.startResumeStep1(request, UUID_SAMPLE); - verify(service).startResumeStep1(request, UUID_SAMPLE); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + boolean check = service.prepareResumeStep1(UUID_SAMPLE); + verify(service).prepareResumeStep1(UUID_SAMPLE); + Assert.assertFalse(check); + } + + @Test + public void prepareResume_Test_EntityAlreadyInProcessing() { + PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + boolean check = service.prepareResumeStep1(UUID_SAMPLE); + verify(service).prepareResumeStep1(UUID_SAMPLE); + Assert.assertFalse(check); + } + + @Test + public void prepareResume_Test_OK() { + PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.save(any())).thenReturn(entity); + boolean check = service.prepareResumeStep1(UUID_SAMPLE); + verify(service).prepareResumeStep1(UUID_SAMPLE); + Assert.assertTrue(check); } @Test @@ -94,6 +121,7 @@ public void startResume_STEP_1_Test_OK() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -101,19 +129,19 @@ public void startResume_STEP_1_Test_OK() throws IOException { entity.setIdTransaction("1234566"); ThreeDS2Response response = ValidBeans.createThreeDS2ResponseStep0Authorization(); - AuthResponse authResponse = ValidBeans.createVPosAuthResponse(RESULT_CODE_00); +// AuthResponse authResponse = ValidBeans.createVPosAuthResponse(RESULT_CODE_00); Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); +// when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); - when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); +// when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -124,12 +152,13 @@ public void startResume_STEP_1_Test_MethodCompletedNull() throws IOException { CreditCardResumeRequest creditCardResumeRequest = new CreditCardResumeRequest(null); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); entity.setJsonRequest("jsonRequest"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -140,6 +169,7 @@ public void startResume_STEP_1_Execpetion_in_executeStep1() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -149,12 +179,12 @@ public void startResume_STEP_1_Execpetion_in_executeStep1() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenThrow(RuntimeException.class); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -165,6 +195,7 @@ public void startResume_callVpos_KO() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -174,11 +205,11 @@ public void startResume_callVpos_KO() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createKOHttpClientResponseVPos()); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -189,6 +220,7 @@ public void startResume_STEP_1_Test_OK_Challenge_Response() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -199,12 +231,12 @@ public void startResume_STEP_1_Test_OK_Challenge_Response() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -215,6 +247,7 @@ public void startResume_STEP_1_Test_OK_Error_Response() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -226,12 +259,12 @@ public void startResume_STEP_1_Test_OK_Error_Response() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -242,6 +275,7 @@ public void startResume_Exception_in_executeAccount() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -252,15 +286,15 @@ public void startResume_Exception_in_executeAccount() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); +// when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); - when(vPosResponseUtils.buildAuthResponse(any())).thenThrow(RuntimeException.class); +// when(vPosResponseUtils.buildAuthResponse(any())).thenThrow(RuntimeException.class); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } @@ -271,6 +305,7 @@ public void startResume_Accounting_KO() throws IOException { CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -278,19 +313,19 @@ public void startResume_Accounting_KO() throws IOException { entity.setIdTransaction("1234566"); ThreeDS2Response response = ValidBeans.createThreeDS2ResponseStep0Authorization(); - AuthResponse authResponse = ValidBeans.createVPosAuthResponse("99"); +// AuthResponse authResponse = ValidBeans.createVPosAuthResponse("99"); Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); +// when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); - when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); +// when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } diff --git a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java index 2cae06f0..57548ee9 100644 --- a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java +++ b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java @@ -5,15 +5,16 @@ import it.pagopa.pm.gateway.client.vpos.HttpClient; import it.pagopa.pm.gateway.dto.config.ClientConfig; import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.enums.ThreeDS2ResponseTypeEnum; -import it.pagopa.pm.gateway.dto.vpos.AuthResponse; import it.pagopa.pm.gateway.dto.vpos.ThreeDS2Response; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; import it.pagopa.pm.gateway.service.async.CcResumeStep2AsyncService; -import it.pagopa.pm.gateway.utils.EcommercePatchUtils; import it.pagopa.pm.gateway.utils.VPosRequestUtils; import it.pagopa.pm.gateway.utils.VPosResponseUtils; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,6 +38,8 @@ public class CcResumeStep2ServiceTest { private final ClientConfig clientConfig = new ClientConfig(); + @Mock + private PaymentRequestLockRepository paymentRequestLockRepository; @Mock private PaymentRequestRepository paymentRequestRepository; @Mock @@ -47,8 +50,8 @@ public class CcResumeStep2ServiceTest { private HttpClient httpClient; @Mock private ObjectMapper objectMapper; - @Mock - private EcommercePatchUtils ecommercePatchUtils; + // @Mock +// private EcommercePatchUtils ecommercePatchUtils; @Spy @InjectMocks private CcResumeStep2Service service; @@ -65,19 +68,44 @@ public void setUpProperties() { } @Test - public void startResume_Test_EntityNull() { - when(paymentRequestRepository.findByGuid(any())).thenReturn(null); - service.startResumeStep2(UUID_SAMPLE); - verify(service).startResumeStep2(UUID_SAMPLE); + public void prepareResume_Test_EntityNull() { + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(null); + boolean check = service.prepareResumeStep2(UUID_SAMPLE); + verify(service).prepareResumeStep2(UUID_SAMPLE); + Assert.assertFalse(check); } @Test - public void startResume_Test_EntityAlreadyAuthorized() { + public void prepareResume_Test_EntityAlreadyAuthorized() { PaymentRequestEntity entity = new PaymentRequestEntity(); entity.setAuthorizationOutcome(true); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); - service.startResumeStep2(UUID_SAMPLE); - verify(service).startResumeStep2(UUID_SAMPLE); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + boolean check = service.prepareResumeStep2(UUID_SAMPLE); + verify(service).prepareResumeStep2(UUID_SAMPLE); + Assert.assertFalse(check); + } + + @Test + public void prepareResume_Test_EntityAlreadyInProcessing() { + PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + boolean check = service.prepareResumeStep2(UUID_SAMPLE); + verify(service).prepareResumeStep2(UUID_SAMPLE); + Assert.assertFalse(check); + } + + @Test + public void prepareResume_Test_OK() { + PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.save(any())).thenReturn(entity); + boolean check = service.prepareResumeStep2(UUID_SAMPLE); + verify(service).prepareResumeStep2(UUID_SAMPLE); + Assert.assertTrue(check); } @Test @@ -85,6 +113,7 @@ public void startResume_STEP_2_Test_OK() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -92,18 +121,18 @@ public void startResume_STEP_2_Test_OK() throws IOException { entity.setIdTransaction("1234566"); ThreeDS2Response response = ValidBeans.createThreeDS2ResponseStep0Authorization(); - AuthResponse authResponse = ValidBeans.createVPosAuthResponse("00"); +// AuthResponse authResponse = ValidBeans.createVPosAuthResponse("00"); Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); +// when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); - when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); +// when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } @@ -113,15 +142,16 @@ public void startResume_STEP_2_Execpetion_in_processResume() throws IOException StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); entity.setCorrelationId("CorrelationId"); entity.setIdTransaction("1234566"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenThrow(RuntimeException.class); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } @@ -131,17 +161,18 @@ public void startResume_STEP_2_Execpetion_in_executeStep2() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); entity.setCorrelationId("CorrelationId"); entity.setIdTransaction("1234566"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenThrow(RuntimeException.class); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } @@ -151,6 +182,7 @@ public void startResume_STEP_2_Test_OK_Error_Response() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -160,11 +192,11 @@ public void startResume_STEP_2_Test_OK_Error_Response() throws IOException { ThreeDS2Response response = ValidBeans.createThreeDS2ResponseStep0Authorization(); response.setResultCode("99"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } @@ -174,6 +206,7 @@ public void startResume_Exception_in_executeAccount() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -184,15 +217,15 @@ public void startResume_Exception_in_executeAccount() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepTwoRequestParams(any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); +// when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); - when(vPosResponseUtils.buildAuthResponse(any())).thenThrow(RuntimeException.class); +// when(vPosResponseUtils.buildAuthResponse(any())).thenThrow(RuntimeException.class); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } @@ -202,6 +235,7 @@ public void startResume_Accounting_KO() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -209,19 +243,19 @@ public void startResume_Accounting_KO() throws IOException { entity.setIdTransaction("1234566"); ThreeDS2Response response = ValidBeans.createThreeDS2ResponseStep0Authorization(); - AuthResponse authResponse = ValidBeans.createVPosAuthResponse("99"); +// AuthResponse authResponse = ValidBeans.createVPosAuthResponse("99"); Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepTwoRequestParams(any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); when(vPosResponseUtils.build3ds2Response(any())).thenReturn(response); - when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); +// when((vPosRequestUtils.buildAccountingRequestParams(any(), any()))).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createHttpClientResponseVPos()); - when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); +// when(vPosResponseUtils.buildAuthResponse(any())).thenReturn(authResponse); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } @@ -231,6 +265,7 @@ public void startResume_callVpos_KO() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); String requestJson = objectMapper.writeValueAsString(stepZeroRequest); entity.setJsonRequest(requestJson); @@ -240,11 +275,11 @@ public void startResume_callVpos_KO() throws IOException { Map params = new HashMap<>(); params.put("1", "prova"); + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); when(vPosRequestUtils.buildStepTwoRequestParams(any(), any())).thenReturn(params); when(httpClient.callVPos(any(), any())).thenReturn(ValidBeans.createKOHttpClientResponseVPos()); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } From 3f614a087f3156080e82e69cb679f33f1b41ad08 Mon Sep 17 00:00:00 2001 From: Roberto Rasi Date: Mon, 9 Oct 2023 13:21:25 +0200 Subject: [PATCH 2/9] Added PROCESSING state in api spec --- api-specs/api_spec_PGS.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/api-specs/api_spec_PGS.yaml b/api-specs/api_spec_PGS.yaml index 1dd6d21e..444afd4a 100644 --- a/api-specs/api_spec_PGS.yaml +++ b/api-specs/api_spec_PGS.yaml @@ -1087,7 +1087,7 @@ components: example: affd8e24-f99a-406f-9ded-67a4a20c097f status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] description: status example: CREATED authCode: @@ -1128,7 +1128,7 @@ components: type: string status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] required: - requestId - status @@ -1171,7 +1171,7 @@ components: example: "Error while requesting refund for requestId: xxx" status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] required: - transactionId - error @@ -1287,7 +1287,7 @@ components: properties: status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] requestId: type: string vposUrl: @@ -1308,7 +1308,7 @@ components: properties: status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] responseType: type: string enum: [METHOD, CHALLENGE, AUTHORIZATION, ERROR] @@ -1332,7 +1332,7 @@ components: properties: status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] requestId: type: string redirectUrl: @@ -1390,7 +1390,7 @@ components: type: string status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] error: type: string description: "null if no error occurred" @@ -1404,7 +1404,7 @@ components: type: string status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] error: type: string VposDeleteResponse409: @@ -1434,6 +1434,6 @@ components: type: string status: type: string - enum: [CREATED, AUTHORIZED, DENIED, CANCELLED] + enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING] error: type: string \ No newline at end of file From 2e0fa92bbb07e1966f43a68373aee547aff7f4f8 Mon Sep 17 00:00:00 2001 From: Roberto Rasi Date: Mon, 9 Oct 2023 13:22:04 +0200 Subject: [PATCH 3/9] added log --- .../it/pagopa/pm/gateway/service/CcResumeStep1Service.java | 7 +++++-- .../it/pagopa/pm/gateway/service/CcResumeStep2Service.java | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java index 5225d14d..21331cea 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java @@ -51,12 +51,12 @@ public boolean prepareResumeStep1(String requestId) { PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId); if (Objects.isNull(entity)) { - log.error("No CreditCard request entity has been found for requestId: " + requestId); + log.error("No CreditCard request entity has been found for requestId: {}",requestId); return false; } if (Objects.nonNull(entity.getAuthorizationOutcome())) { - log.warn(String.format("requestId %s already processed", requestId)); + log.warn("requestId {} already processed", requestId); entity.setErrorMessage("requestId already processed"); return false; } @@ -65,9 +65,12 @@ public boolean prepareResumeStep1(String requestId) { if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) && responseType != null && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) { + log.info("prepareResumeStep1 request in state CREATED METHOD - proceed for requestId: {}",requestId); entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); paymentRequestLockRepository.save(entity); return true; + } else { + log.info("prepareResumeStep1 request in state {} {} - not proceed for requestId: {}",entity.getStatus(),responseType,requestId); } return false; diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java index 819e9101..4fc3dd58 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java @@ -48,12 +48,12 @@ public boolean prepareResumeStep2(String requestId) { PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId); if (Objects.isNull(entity)) { - log.error("No CreditCard request entity has been found for requestId: " + requestId); + log.error("No CreditCard request entity has been found for requestId: {}", requestId); return false; } if (Objects.nonNull(entity.getAuthorizationOutcome())) { - log.warn(String.format("requestId %s already processed", requestId)); + log.warn("requestId {} already processed", requestId); entity.setErrorMessage("requestId already processed"); return false; } @@ -62,9 +62,12 @@ public boolean prepareResumeStep2(String requestId) { if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) && responseType != null && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) { + log.info("prepareResumeStep2 request in state CREATED CHALLENGE - proceed for requestId: {}",requestId); entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); paymentRequestLockRepository.save(entity); return true; + } else { + log.info("prepareResumeStep2 request in state {} {} - not proceed for requestId: {}",entity.getStatus(),responseType,requestId); } return false; From 1cc658f0cb53e6361c3ea63c88fed07c1be115ae Mon Sep 17 00:00:00 2001 From: Roberto Rasi Date: Mon, 9 Oct 2023 13:23:27 +0200 Subject: [PATCH 4/9] Add PROCESSING state in XPAY resume call --- .../controller/XPayPaymentController.java | 31 ++++---- .../async/XPayPaymentAsyncService.java | 32 +++++++- .../pagopa/pm/gateway/beans/ValidBeans.java | 11 ++- .../controller/XPayPaymentControllerTest.java | 73 +++++++++++++++++-- 4 files changed, 119 insertions(+), 28 deletions(-) diff --git a/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java b/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java index 9a188c73..9d66533d 100644 --- a/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java +++ b/src/main/java/it/pagopa/pm/gateway/controller/XPayPaymentController.java @@ -133,24 +133,21 @@ public ResponseEntity resumeXPayPayment(@PathVariable String requestId, EsitoXpay outcome = xPay3DSResponse.getOutcome(); String pollingUrlRedirect = StringUtils.join(xpayPollingUrl, requestId); - PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId); - if (Objects.isNull(entity)) { - log.error("No XPay entity has been found for requestId: " + requestId); - return ResponseEntity.status(HttpStatus.FOUND).location(URI.create(pollingUrlRedirect)).build(); - } - - setMdcFields(entity.getMdcInfo()); - - if (outcome.equals(OK) && checkResumeRequest(entity, requestId, xPay3DSResponse) - && CREATED.name().equals(entity.getStatus())) { - - xPayPaymentAsyncService.executeXPayPaymentCall(requestId, xPay3DSResponse, entity); - } else { - log.info(String.format("Outcome is %s: setting status as DENIED for requestId %s", outcome, requestId)); - entity.setStatus(DENIED.name()); - paymentRequestRepository.save(entity); - ecommercePatchUtils.executePatchTransactionXPay(entity); + boolean proceed = xPayPaymentAsyncService.prepareResume(requestId, xPay3DSResponse); + + if (proceed) + { + PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId); + setMdcFields(entity.getMdcInfo()); + if (outcome.equals(OK) && checkResumeRequest(entity, requestId, xPay3DSResponse)) { + xPayPaymentAsyncService.executeXPayPaymentCall(requestId, xPay3DSResponse, entity); + } else { + log.info(String.format("Outcome is %s: setting status as DENIED for requestId %s", outcome, requestId)); + entity.setStatus(DENIED.name()); + paymentRequestRepository.save(entity); + ecommercePatchUtils.executePatchTransactionXPay(entity); + } } log.info("END - GET {}{} for requestId {}", REQUEST_PAYMENTS_XPAY, REQUEST_PAYMENTS_RESUME, requestId); diff --git a/src/main/java/it/pagopa/pm/gateway/service/async/XPayPaymentAsyncService.java b/src/main/java/it/pagopa/pm/gateway/service/async/XPayPaymentAsyncService.java index 4dbb31a0..098d5754 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/async/XPayPaymentAsyncService.java +++ b/src/main/java/it/pagopa/pm/gateway/service/async/XPayPaymentAsyncService.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.core.JsonProcessingException; import it.pagopa.pm.gateway.client.ecommerce.EcommerceClient; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.xpay.*; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; import it.pagopa.pm.gateway.service.XpayService; import it.pagopa.pm.gateway.utils.ClientsConfig; @@ -17,8 +19,11 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.math.BigInteger; +import java.util.Objects; import static it.pagopa.pm.gateway.constant.Messages.GENERIC_ERROR_MSG; import static it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum.AUTHORIZED; @@ -36,8 +41,10 @@ public class XPayPaymentAsyncService { public static final String ZERO_CHAR = "0"; private static final int MAX_ERROR_MESSAGE_ENTITY_SIZE = 50; private static final String ERROR_MESSAGE_TRUNCATE_SUFFIX = "..."; + private static final String PGS_GENERIC_ERROR = "1000"; private XpayService xpayService; private PaymentRequestRepository paymentRequestRepository; + private PaymentRequestLockRepository paymentRequestLockRepository; private XPayUtils xPayUtils; private String apiKey; private ClientsConfig clientsConfig; @@ -47,7 +54,7 @@ public class XPayPaymentAsyncService { @Autowired public XPayPaymentAsyncService(PaymentRequestRepository paymentRequestRepository, XpayService xpayService, XPayUtils xPayUtils, @Value("${xpay.apiKey}") String apiKey, ClientsConfig clientsConfig, EcommerceClient ecommerceClient, - EcommercePatchUtils ecommercePatchUtils) { + EcommercePatchUtils ecommercePatchUtils, PaymentRequestLockRepository paymentRequestLockRepository) { this.paymentRequestRepository = paymentRequestRepository; this.xpayService = xpayService; this.apiKey = apiKey; @@ -55,6 +62,7 @@ public XPayPaymentAsyncService(PaymentRequestRepository paymentRequestRepository this.xPayUtils = xPayUtils; this.clientsConfig = clientsConfig; this.ecommercePatchUtils = ecommercePatchUtils; + this.paymentRequestLockRepository = paymentRequestLockRepository; } @Async @@ -177,4 +185,26 @@ private void setErrorCodeAndMessage(String requestId, PaymentRequestEntity entit entity.setErrorMessage(truncatedMessage); } } + + @Transactional(propagation = Propagation.REQUIRES_NEW) + public boolean prepareResume(String requestId, XPay3DSResponse xpay3DSResponse) { + log.info("prepareResume for requestId: " + requestId); + + PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId); + + if (Objects.isNull(entity)) { + log.error("No XPay entity has been found for requestId: {}", requestId); + return false; + } + + if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus())) { + log.info("prepareResume request in state CREATED - proceed for requestId: {}", requestId); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + paymentRequestLockRepository.save(entity); + return true; + } else { + log.info("prepareResume request in state {} - not proceed for requestId: {}", entity.getStatus(), requestId); + } + return false; + } } \ No newline at end of file diff --git a/src/test/java/it/pagopa/pm/gateway/beans/ValidBeans.java b/src/test/java/it/pagopa/pm/gateway/beans/ValidBeans.java index 9c2edfaf..16df6252 100644 --- a/src/test/java/it/pagopa/pm/gateway/beans/ValidBeans.java +++ b/src/test/java/it/pagopa/pm/gateway/beans/ValidBeans.java @@ -546,11 +546,16 @@ public static AuthPaymentXPayResponse createBadXPayAuthResponse(AuthPaymentXPayR return authPaymentXPayResponse; } - public static XPayPollingResponse createXpayAuthPollingResponse(boolean isOk, boolean isCancelled) { + public static XPayPollingResponse createXpayAuthPollingResponse(boolean isOk, boolean isCancelled, boolean isProcessing) { XPayPollingResponse response = new XPayPollingResponse(); if (isOk) { - response.setHtml(""); - response.setPaymentRequestStatusEnum(CREATED); + if (isProcessing) { + response.setHtml(""); + response.setPaymentRequestStatusEnum(PROCESSING); + } else { + response.setHtml(""); + response.setPaymentRequestStatusEnum(CREATED); + } } else { response.setPaymentRequestStatusEnum(DENIED); } diff --git a/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java b/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java index e468c976..2f10d279 100644 --- a/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java +++ b/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java @@ -9,6 +9,7 @@ import it.pagopa.pm.gateway.dto.transaction.TransactionInfo; import it.pagopa.pm.gateway.dto.xpay.*; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; +import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; import it.pagopa.pm.gateway.service.XpayService; import it.pagopa.pm.gateway.service.async.XPayPaymentAsyncService; @@ -37,7 +38,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -55,6 +56,8 @@ public class XPayPaymentControllerTest { @Mock private PaymentRequestRepository paymentRequestRepository; @Mock + private PaymentRequestLockRepository paymentRequestLockRepository; + @Mock private XpayService xpayService; @Mock private EcommerceClient ecommerceClient; @@ -73,7 +76,7 @@ public void init() { EcommercePatchUtils ecommercePatchUtils = new EcommercePatchUtils(ecommerceClient, clientsConfig); XPayPaymentAsyncService xPayPaymentAsyncService = new XPayPaymentAsyncService(paymentRequestRepository,xpayService,xPayUtils, - "apiKey", clientsConfig, ecommerceClient, ecommercePatchUtils); + "apiKey", clientsConfig, ecommerceClient, ecommercePatchUtils, paymentRequestLockRepository); XPayPaymentController xpayController = new XPayPaymentController("http://localhost:8080/", "http://localhost:8080/", "apiKey", paymentRequestRepository, xpayService, xPayUtils, jwtTokenUtils, clientsConfig, xPayPaymentAsyncService, ecommercePatchUtils); mvc = MockMvcBuilders.standaloneSetup(xpayController).build(); @@ -183,7 +186,7 @@ public void xPay_givenResponseNull_shouldThrowException() throws Exception { public void xPay_shouldReturnAuthPollingResponseOK() throws Exception { XPayAuthRequest xPayAuthRequest = ValidBeans.createXPayAuthRequest(true); PaymentRequestEntity entity = ValidBeans.paymentRequestEntityxPay(xPayAuthRequest, ECOMMERCE_APP_ORIGIN, true, CREATED, false); - XPayPollingResponse expectedResponse = ValidBeans.createXpayAuthPollingResponse(true, false); + XPayPollingResponse expectedResponse = ValidBeans.createXpayAuthPollingResponse(true, false,false); when(paymentRequestRepository.findByGuid(UUID_SAMPLE)).thenReturn(entity); String url = REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE; mvc.perform(get(url)).andExpect(content().json(mapper.writeValueAsString(expectedResponse))); @@ -198,7 +201,7 @@ public void xPay_shouldReturnAuthPollingResponseKO() throws Exception { when(clientsConfig.getByKey(any())).thenReturn(clientConfig); String url = REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE; mvc.perform(get(url)) - .andExpect(content().json(mapper.writeValueAsString(ValidBeans.createXpayAuthPollingResponse(false, false)))); + .andExpect(content().json(mapper.writeValueAsString(ValidBeans.createXpayAuthPollingResponse(false, false,false)))); } @Test @@ -221,6 +224,19 @@ public void xPay_givenInvalidRequestId_shouldReturnNotFound() throws Exception { } + @Test + public void xPay_shouldReturnProcessingCase() throws Exception { + XPayAuthRequest xPayAuthRequest = ValidBeans.createXPayAuthRequest(true); + when(paymentRequestRepository.findByGuid(UUID_SAMPLE)) + .thenReturn(ValidBeans.paymentRequestEntityxPay(xPayAuthRequest, ECOMMERCE_APP_ORIGIN, true, PROCESSING, false)); + when(clientsConfig.getByKey(any())).thenReturn(clientConfig); + + String url = REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE; + mvc.perform(get(url)) + .andExpect(content().json(mapper.writeValueAsString(ValidBeans.createXpayAuthPollingResponse(true, + false, true)))); + } + @Test public void xPay_givenGoodResumeRequest_shouldReturn302Status() throws Exception { boolean isTrue = true; @@ -237,6 +253,7 @@ public void xPay_givenGoodResumeRequest_shouldReturn302Status() throws Exception PaymentXPayResponse xPayResponse = ValidBeans.createPaymentXPayResponse(isTrue); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(xPayUtils.checkMac(any(), any())).thenReturn(isTrue); @@ -264,6 +281,7 @@ public void xPay_givenMacIncorrect_shouldReturn302Status() throws Exception { TransactionInfo patchResponse = new TransactionInfo(); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(xPayUtils.checkMac(any(), any())).thenReturn(false); @@ -291,6 +309,7 @@ public void xPay_givenGoodResumeRequest_shouldReturnPaymentKO302Status() throws PaymentXPayResponse xPayResponse = ValidBeans.createPaymentXPayResponse(false); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(xPayUtils.checkMac(any(), any())).thenReturn(true); @@ -318,6 +337,7 @@ public void xPay_givenGoodResumeRequest_shouldReturnPaymentResponseEmpty302Statu TransactionInfo patchResponse = new TransactionInfo(); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(xPayUtils.checkMac(any(), any())).thenReturn(true); @@ -345,6 +365,7 @@ public void xPay_givenGoodResumeRequest_paymentCallShouldThrowAnException302Stat TransactionInfo patchResponse = new TransactionInfo(); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(xPayUtils.checkMac(any(), any())).thenReturn(true); @@ -373,6 +394,7 @@ public void xPay_givenResumeRequestWithKO_shouldReturnResponseFromXPayOKAnd302St TransactionInfo patchResponse = new TransactionInfo(); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(ecommerceClient.callPatchTransaction(argThat(new TypeUpdateAuthRequestXPayMatcher()), any(), any())).thenReturn(patchResponse); mvc.perform(get(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE + "/resume/") @@ -395,6 +417,7 @@ public void xPay_givenGoodResumeRequest_patchCallShouldThrowAnException() throws PaymentXPayResponse xPayResponse = ValidBeans.createPaymentXPayResponse(true); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(xPayUtils.checkMac(any(), any())).thenReturn(true); @@ -414,6 +437,7 @@ public void xPay_givenGoodResumeRequest_NoEntityshouldReturn302Status() throws E MultiValueMap params = ValidBeans.createXPayResumeRequest(true); when(paymentRequestRepository.findByGuid(any())).thenReturn(null); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(null); mvc.perform(get(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE + "/resume") .header(Headers.X_CLIENT_ID, ECOMMERCE_APP_ORIGIN) @@ -437,6 +461,7 @@ public void xPay_givenBadResumeRequest_TransactionAlredyProcessedshouldReturn302 TransactionInfo patchResponse = new TransactionInfo(); when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(ecommerceClient.callPatchTransaction(argThat(new TypeUpdateAuthRequestXPayMatcher()), any(), any())).thenReturn(patchResponse); mvc.perform(get(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE + "/resume") @@ -446,6 +471,41 @@ public void xPay_givenBadResumeRequest_TransactionAlredyProcessedshouldReturn302 .andExpect(status().isFound()); } + @Test + public void xPay_givenResumeAlreadyInProcessingState_shouldNotProceed_shouldReturn302Status() throws Exception { + boolean isTrue = true; + MultiValueMap params = ValidBeans.createXPayResumeRequest(isTrue); + XPayAuthRequest xPayAuthRequest = ValidBeans.createXPayAuthRequest(isTrue); + PaymentRequestEntity entity = ValidBeans.paymentRequestEntityxPay(xPayAuthRequest, ECOMMERCE_APP_ORIGIN, isTrue, PROCESSING, false); + + AuthPaymentXPayRequest authPaymentXPayRequest = ValidBeans.createAuthPaymentRequest(xPayAuthRequest); + String jsonRequest = mapper.writeValueAsString(authPaymentXPayRequest); + entity.setJsonRequest(jsonRequest); + + TransactionInfo patchResponse = new TransactionInfo(); + + PaymentXPayResponse xPayResponse = ValidBeans.createPaymentXPayResponse(isTrue); + + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); + + when(xPayUtils.checkMac(any(), any())).thenReturn(isTrue); + + when(xpayService.callPaga3DS(any())).thenReturn(xPayResponse); + + when(ecommerceClient.callPatchTransaction(argThat(new TypeUpdateAuthRequestXPayMatcher()), any(), any())).thenReturn(patchResponse); + + mvc.perform(get(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE + "/resume/") + .header(Headers.X_CLIENT_ID, ECOMMERCE_APP_ORIGIN) + .contentType(MediaType.APPLICATION_JSON) + .params(params)) + .andExpect(status().isFound()); + + verifyNoInteractions(ecommerceClient); + verifyNoInteractions(xpayService); + } + + @Test public void xPay_givenBadRequestIdForRefund_shouldReturn404() throws Exception { @@ -465,7 +525,6 @@ public void xPay_givenDeniedTransactionRequestIdForRefund_shouldReturn409() thro when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); - mvc.perform(delete(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE) .header(Headers.X_CLIENT_ID, ECOMMERCE_APP_ORIGIN) .contentType(MediaType.APPLICATION_JSON)) @@ -599,7 +658,7 @@ public void xPay_shouldReturnCancelledCase() throws Exception { String url = REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE; mvc.perform(get(url)) .andExpect(content().json(mapper.writeValueAsString(ValidBeans.createXpayAuthPollingResponse(false, - true)))); + true,false)))); } @Test @@ -613,6 +672,6 @@ public void xPay_shouldReturnRefundedCase() throws Exception { String url = REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE; mvc.perform(get(url)) .andExpect(content().json(mapper.writeValueAsString(ValidBeans.createXpayAuthPollingResponse(false, - true)))); + true, false)))); } } \ No newline at end of file From 2ee9ba7801308cc66bd9eec918007f00a318c9c1 Mon Sep 17 00:00:00 2001 From: Alberto Gelmi Date: Mon, 9 Oct 2023 15:17:55 +0200 Subject: [PATCH 5/9] GP-24: vpos - management of simultaneous calls to the resume APIs --- .../it/pagopa/pm/gateway/service/CcResumeStep1Service.java | 2 +- .../pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java index 21331cea..a292213a 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java @@ -64,7 +64,7 @@ public boolean prepareResumeStep1(String requestId) { String responseType = entity.getResponseType(); if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) && responseType != null - && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) { + && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.METHOD.name())) { log.info("prepareResumeStep1 request in state CREATED METHOD - proceed for requestId: {}",requestId); entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); paymentRequestLockRepository.save(entity); diff --git a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java index 43b9ffb3..62d6e1fe 100644 --- a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java +++ b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java @@ -96,7 +96,7 @@ public void prepareResume_Test_EntityAlreadyAuthorized() { public void prepareResume_Test_EntityAlreadyInProcessing() { PaymentRequestEntity entity = new PaymentRequestEntity(); entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); - entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); boolean check = service.prepareResumeStep1(UUID_SAMPLE); verify(service).prepareResumeStep1(UUID_SAMPLE); @@ -107,7 +107,7 @@ public void prepareResume_Test_EntityAlreadyInProcessing() { public void prepareResume_Test_OK() { PaymentRequestEntity entity = new PaymentRequestEntity(); entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); - entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); when(paymentRequestLockRepository.save(any())).thenReturn(entity); boolean check = service.prepareResumeStep1(UUID_SAMPLE); From 7a259dfaea4f4d3ce91d7b36f8e51318b3e3106f Mon Sep 17 00:00:00 2001 From: Roberto Rasi Date: Mon, 9 Oct 2023 15:48:36 +0200 Subject: [PATCH 6/9] Remove unnecessary mokito stub in junit --- .../pm/gateway/controller/XPayPaymentControllerTest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java b/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java index 2f10d279..ab7d5a4d 100644 --- a/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java +++ b/src/test/java/it/pagopa/pm/gateway/controller/XPayPaymentControllerTest.java @@ -229,7 +229,6 @@ public void xPay_shouldReturnProcessingCase() throws Exception { XPayAuthRequest xPayAuthRequest = ValidBeans.createXPayAuthRequest(true); when(paymentRequestRepository.findByGuid(UUID_SAMPLE)) .thenReturn(ValidBeans.paymentRequestEntityxPay(xPayAuthRequest, ECOMMERCE_APP_ORIGIN, true, PROCESSING, false)); - when(clientsConfig.getByKey(any())).thenReturn(clientConfig); String url = REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE; mvc.perform(get(url)) @@ -436,7 +435,6 @@ public void xPay_givenGoodResumeRequest_patchCallShouldThrowAnException() throws public void xPay_givenGoodResumeRequest_NoEntityshouldReturn302Status() throws Exception { MultiValueMap params = ValidBeans.createXPayResumeRequest(true); - when(paymentRequestRepository.findByGuid(any())).thenReturn(null); when(paymentRequestLockRepository.findByGuid(any())).thenReturn(null); mvc.perform(get(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE + "/resume") @@ -486,15 +484,8 @@ public void xPay_givenResumeAlreadyInProcessingState_shouldNotProceed_shouldRetu PaymentXPayResponse xPayResponse = ValidBeans.createPaymentXPayResponse(isTrue); - when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); when(paymentRequestLockRepository.findByGuid(any())).thenReturn(entity); - when(xPayUtils.checkMac(any(), any())).thenReturn(isTrue); - - when(xpayService.callPaga3DS(any())).thenReturn(xPayResponse); - - when(ecommerceClient.callPatchTransaction(argThat(new TypeUpdateAuthRequestXPayMatcher()), any(), any())).thenReturn(patchResponse); - mvc.perform(get(REQUEST_PAYMENTS_XPAY + "/" + UUID_SAMPLE + "/resume/") .header(Headers.X_CLIENT_ID, ECOMMERCE_APP_ORIGIN) .contentType(MediaType.APPLICATION_JSON) From 4fbf68b7e5b8254cff65730cb6e6cdbf43fef433 Mon Sep 17 00:00:00 2001 From: Alberto Gelmi Date: Mon, 9 Oct 2023 16:56:00 +0200 Subject: [PATCH 7/9] GP-24: vpos - management of simultaneous calls to the resume APIs --- .../service/CcPaymentInfoServiceTest.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/test/java/it/pagopa/pm/gateway/service/CcPaymentInfoServiceTest.java b/src/test/java/it/pagopa/pm/gateway/service/CcPaymentInfoServiceTest.java index 9af52316..8bb4d137 100644 --- a/src/test/java/it/pagopa/pm/gateway/service/CcPaymentInfoServiceTest.java +++ b/src/test/java/it/pagopa/pm/gateway/service/CcPaymentInfoServiceTest.java @@ -18,8 +18,7 @@ import java.util.Optional; -import static it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum.AUTHORIZED; -import static it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum.CREATED; +import static it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -81,6 +80,26 @@ public void getPaymentInfoNoAuthorizedSuccessTest() { assertNotNull(response.getVposUrl()); } + @Test + public void getPaymentInfoProcessingNoAuthorizedSuccessTest() { + PaymentRequestEntity paymentInfo = new PaymentRequestEntity(); + paymentInfo.setStatus(PROCESSING.name()); + paymentInfo.setResponseType("type"); + paymentInfo.setGuid("guid"); + paymentInfo.setAuthorizationUrl("url"); + paymentInfo.setResponseType("METHOD"); + paymentInfo.setIdTransaction("12345"); + + when(paymentRequestRepository.findByGuidAndRequestEndpoint(any(), any())) + .thenReturn(Optional.of(paymentInfo)); + + CcPaymentInfoResponse response = ccPaymentInfoService.getPaymentInfo("123"); + assertNotNull(response.getPaymentRequestStatusEnum()); + assertNotNull(response.getRequestId()); + assertNotNull(response.getThreeDS2ResponseTypeEnum()); + assertNotNull(response.getVposUrl()); + } + @Test public void getPaymentInfoChallengeSuccessTest() { String authUrl = "https://local?TK=tkFromVpos&creq=realcreq"; @@ -103,6 +122,28 @@ public void getPaymentInfoChallengeSuccessTest() { assertEquals("realcreq", response.getCreq()); } + @Test + public void getPaymentInfoProcessingChallengeSuccessTest() { + String authUrl = "https://local?TK=tkFromVpos&creq=realcreq"; + PaymentRequestEntity paymentInfo = new PaymentRequestEntity(); + paymentInfo.setStatus(PROCESSING.name()); + paymentInfo.setGuid("guid"); + paymentInfo.setAuthorizationUrl(authUrl); + paymentInfo.setResponseType("CHALLENGE"); + paymentInfo.setIdTransaction("12345"); + + when(paymentRequestRepository.findByGuidAndRequestEndpoint(any(), any())) + .thenReturn(Optional.of(paymentInfo)); + + CcPaymentInfoResponse response = ccPaymentInfoService.getPaymentInfo("123"); + assertNotNull(response.getPaymentRequestStatusEnum()); + assertNotNull(response.getRequestId()); + assertNotNull(response.getThreeDS2ResponseTypeEnum()); + assertNotNull(response.getVposUrl()); + assertEquals("https://local?TK=tkFromVpos", response.getVposUrl()); + assertEquals("realcreq", response.getCreq()); + } + @Test public void getPaymentInfo404Test() { when(paymentRequestRepository.findByGuidAndRequestEndpoint(any(), any())).thenReturn(Optional.empty()); From 34652f20a2c4573b3c13a4afd5d4e83306aa158a Mon Sep 17 00:00:00 2001 From: Alberto Gelmi Date: Tue, 10 Oct 2023 15:30:07 +0200 Subject: [PATCH 8/9] GP-24: vpos - management of simultaneous calls to the resume APIs --- .../gateway/service/CcResumeStep1Service.java | 10 +++++--- .../gateway/service/CcResumeStep2Service.java | 8 ++++-- .../async/CcResumeStep1AsyncService.java | 10 +++++--- .../async/CcResumeStep2AsyncService.java | 10 +++++--- .../service/CcResumeStep1ServiceTest.java | 25 +++++++++++++++++++ .../service/CcResumeStep2ServiceTest.java | 24 ++++++++++++++++++ 6 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java index a292213a..fbc62505 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep1Service.java @@ -51,7 +51,7 @@ public boolean prepareResumeStep1(String requestId) { PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId); if (Objects.isNull(entity)) { - log.error("No CreditCard request entity has been found for requestId: {}",requestId); + log.error("No CreditCard request entity has been found for requestId: {}", requestId); return false; } @@ -65,12 +65,12 @@ public boolean prepareResumeStep1(String requestId) { if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) && responseType != null && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.METHOD.name())) { - log.info("prepareResumeStep1 request in state CREATED METHOD - proceed for requestId: {}",requestId); + log.info("prepareResumeStep1 request in state CREATED METHOD - proceed for requestId: {}", requestId); entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); paymentRequestLockRepository.save(entity); return true; } else { - log.info("prepareResumeStep1 request in state {} {} - not proceed for requestId: {}",entity.getStatus(),responseType,requestId); + log.info("prepareResumeStep1 request in state {} {} - not proceed for requestId: {}", entity.getStatus(), responseType, requestId); } return false; @@ -95,6 +95,10 @@ private void processResume(CreditCardResumeRequest request, PaymentRequestEntity } } catch (Exception e) { log.error("error during execution of resume for requestId {}", entity.getGuid(), e); + if (PaymentRequestStatusEnum.PROCESSING.name().equals(entity.getStatus())) { + entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); + paymentRequestRepository.save(entity); + } } } } diff --git a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java index 4fc3dd58..613d5ee9 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java +++ b/src/main/java/it/pagopa/pm/gateway/service/CcResumeStep2Service.java @@ -62,12 +62,12 @@ public boolean prepareResumeStep2(String requestId) { if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus()) && responseType != null && responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) { - log.info("prepareResumeStep2 request in state CREATED CHALLENGE - proceed for requestId: {}",requestId); + log.info("prepareResumeStep2 request in state CREATED CHALLENGE - proceed for requestId: {}", requestId); entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); paymentRequestLockRepository.save(entity); return true; } else { - log.info("prepareResumeStep2 request in state {} {} - not proceed for requestId: {}",entity.getStatus(),responseType,requestId); + log.info("prepareResumeStep2 request in state {} {} - not proceed for requestId: {}", entity.getStatus(), responseType, requestId); } return false; @@ -90,6 +90,10 @@ private void processResume(PaymentRequestEntity entity) { } } catch (Exception e) { log.error("error during execution of resume for requestId {}", entity.getGuid(), e); + if (PaymentRequestStatusEnum.PROCESSING.name().equals(entity.getStatus())) { + entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); + paymentRequestRepository.save(entity); + } } } } diff --git a/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep1AsyncService.java b/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep1AsyncService.java index e270333e..cef07fd5 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep1AsyncService.java +++ b/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep1AsyncService.java @@ -3,6 +3,7 @@ import it.pagopa.pm.gateway.client.vpos.HttpClient; import it.pagopa.pm.gateway.client.vpos.HttpClientResponse; import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.vpos.*; import it.pagopa.pm.gateway.entity.PaymentRequestEntity; import it.pagopa.pm.gateway.repository.PaymentRequestRepository; @@ -15,7 +16,6 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.Map; @@ -62,7 +62,7 @@ public void executeStep1(Map params, PaymentRequestEntity entity MdcUtils.setMdcFields(entity.getMdcInfo()); String requestId = entity.getGuid(); log.info("Calling VPOS - Step 1 - for requestId: " + requestId); - HttpClientResponse clientResponse = httpClient.callVPos(vposUrl,params); + HttpClientResponse clientResponse = httpClient.callVPos(vposUrl, params); ThreeDS2Response response = vPosResponseUtils.build3ds2Response(clientResponse.getEntity()); vPosResponseUtils.validateResponseMac(response.getTimestamp(), response.getResultCode(), response.getResultMac(), request); log.info("Result code from VPOS - Step 1 - for RequestId {} is {}", requestId, response.getResultCode()); @@ -76,6 +76,10 @@ public void executeStep1(Map params, PaymentRequestEntity entity } } catch (Exception e) { log.error("{}{}", GENERIC_ERROR_MSG, entity.getIdTransaction(), e); + if (PaymentRequestStatusEnum.PROCESSING.name().equals(entity.getStatus())) { + entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); + paymentRequestRepository.save(entity); + } } } @@ -122,7 +126,7 @@ private void executeAccount(PaymentRequestEntity entity, StepZeroRequest pgsRequ try { log.info("Calling VPOS - Accounting - for requestId: {}", entity.getGuid()); Map params = vPosRequestUtils.buildAccountingRequestParams(pgsRequest, entity.getCorrelationId()); - HttpClientResponse clientResponse = httpClient.callVPos(vposUrl,params); + HttpClientResponse clientResponse = httpClient.callVPos(vposUrl, params); AuthResponse response = vPosResponseUtils.buildAuthResponse(clientResponse.getEntity()); vPosResponseUtils.validateResponseMac(response.getTimestamp(), response.getResultCode(), response.getResultMac(), pgsRequest); checkAccountResultCode(response, entity); diff --git a/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep2AsyncService.java b/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep2AsyncService.java index 06cef490..fc871740 100644 --- a/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep2AsyncService.java +++ b/src/main/java/it/pagopa/pm/gateway/service/async/CcResumeStep2AsyncService.java @@ -3,6 +3,7 @@ import it.pagopa.pm.gateway.client.vpos.HttpClient; import it.pagopa.pm.gateway.client.vpos.HttpClientResponse; import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest; +import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum; import it.pagopa.pm.gateway.dto.vpos.AuthResponse; import it.pagopa.pm.gateway.dto.vpos.ThreeDS2Authorization; import it.pagopa.pm.gateway.dto.vpos.ThreeDS2Response; @@ -17,7 +18,6 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.Map; @@ -56,7 +56,7 @@ public void executeStep2(Map params, PaymentRequestEntity entity MdcUtils.setMdcFields(entity.getMdcInfo()); String requestId = entity.getGuid(); log.info("Calling VPOS - Step 2 - for requestId: " + requestId); - HttpClientResponse clientResponse = httpClient.callVPos(vposUrl,params); + HttpClientResponse clientResponse = httpClient.callVPos(vposUrl, params); ThreeDS2Response response = vPosResponseUtils.build3ds2Response(clientResponse.getEntity()); vPosResponseUtils.validateResponseMac(response.getTimestamp(), response.getResultCode(), response.getResultMac(), request); log.info("Result code from VPOS - Step 2 - for RequestId {} is {}", requestId, response.getResultCode()); @@ -67,6 +67,10 @@ public void executeStep2(Map params, PaymentRequestEntity entity ecommercePatchUtils.executePatchTransactionVPos(entity); } catch (Exception e) { log.error("{}{}", GENERIC_ERROR_MSG, entity.getIdTransaction(), e); + if (PaymentRequestStatusEnum.PROCESSING.name().equals(entity.getStatus())) { + entity.setStatus(PaymentRequestStatusEnum.CREATED.name()); + paymentRequestRepository.save(entity); + } } } @@ -102,7 +106,7 @@ private void executeAccount(PaymentRequestEntity entity, StepZeroRequest pgsRequ try { log.info("Calling VPOS - Accounting - for requestId: {}", entity.getGuid()); Map params = vPosRequestUtils.buildAccountingRequestParams(pgsRequest, entity.getCorrelationId()); - HttpClientResponse clientResponse = httpClient.callVPos(vposUrl,params); + HttpClientResponse clientResponse = httpClient.callVPos(vposUrl, params); AuthResponse response = vPosResponseUtils.buildAuthResponse(clientResponse.getEntity()); vPosResponseUtils.validateResponseMac(response.getTimestamp(), response.getResultCode(), response.getResultMac(), pgsRequest); checkAccountResultCode(response, entity); diff --git a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java index 62d6e1fe..9a5f357a 100644 --- a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java +++ b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep1ServiceTest.java @@ -214,6 +214,31 @@ public void startResume_callVpos_KO() throws IOException { verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); } + @Test + public void startResume_callVpos_Exception() throws IOException { + StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); + CreditCardResumeRequest creditCardResumeRequest = ValidBeans.createCreditCardResumeRequest(true); + + PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.METHOD.name()); + String requestJson = objectMapper.writeValueAsString(stepZeroRequest); + entity.setJsonRequest(requestJson); + entity.setCorrelationId("CorrelationId"); + entity.setIdTransaction("1234566"); + + Map params = new HashMap<>(); + params.put("1", "prova"); + + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); + when(vPosRequestUtils.buildStepOneRequestParams(any(), any(), any())).thenReturn(params); + when(httpClient.callVPos(any(), any())).thenThrow(new IOException()); + + service.startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); + verify(service).startResumeStep1(creditCardResumeRequest, UUID_SAMPLE); + } + @Test public void startResume_STEP_1_Test_OK_Challenge_Response() throws IOException { StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); diff --git a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java index 57548ee9..6709f9ad 100644 --- a/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java +++ b/src/test/java/it/pagopa/pm/gateway/service/CcResumeStep2ServiceTest.java @@ -283,4 +283,28 @@ public void startResume_callVpos_KO() throws IOException { service.startResumeStep2(UUID_SAMPLE); verify(service).startResumeStep2(UUID_SAMPLE); } + + @Test + public void startResume_callVpos_Exception() throws IOException { + StepZeroRequest stepZeroRequest = ValidBeans.createStep0Request(false); + + PaymentRequestEntity entity = new PaymentRequestEntity(); + entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name()); + entity.setResponseType(ThreeDS2ResponseTypeEnum.CHALLENGE.name()); + String requestJson = objectMapper.writeValueAsString(stepZeroRequest); + entity.setJsonRequest(requestJson); + entity.setCorrelationId("CorrelationId"); + entity.setIdTransaction("1234566"); + + Map params = new HashMap<>(); + params.put("1", "prova"); + + when(paymentRequestRepository.findByGuid(any())).thenReturn(entity); + when(objectMapper.readValue(entity.getJsonRequest(), StepZeroRequest.class)).thenReturn(stepZeroRequest); + when(vPosRequestUtils.buildStepTwoRequestParams(any(), any())).thenReturn(params); + when(httpClient.callVPos(any(), any())).thenThrow(new IOException()); + + service.startResumeStep2(UUID_SAMPLE); + verify(service).startResumeStep2(UUID_SAMPLE); + } } From c2e2721d5a61870288fc27ca59a85643e59d2f03 Mon Sep 17 00:00:00 2001 From: Alberto Gelmi Date: Tue, 10 Oct 2023 16:43:04 +0200 Subject: [PATCH 9/9] GP-24: vpos - management of simultaneous calls to the resume APIs --- .../pm/gateway/controller/CreditCardPaymentController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java b/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java index 21db83c1..184174bd 100644 --- a/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java +++ b/src/main/java/it/pagopa/pm/gateway/controller/CreditCardPaymentController.java @@ -96,7 +96,6 @@ public ResponseEntity resumeCreditCardPayment(@Request @RequestBody CreditCardResumeRequest request) { MdcUtils.setMdcFields(mdcFields); log.info("START - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_METHOD, requestId); - ResponseEntity responseEntity = null; VposResumeMethodResponse response = new VposResumeMethodResponse(requestId); if (resumeStep1Service.prepareResumeStep1(requestId.toString())) {