Skip to content

Commit

Permalink
[PAGOPA-2113] refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
cap-ang committed Sep 26, 2024
1 parent e7a27a0 commit 33d12c7
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,25 @@ public ResponseEntity<RecoveryReceiptResponse> recoverReceiptKOForCreditorInstit

@Operation(summary = "Execute IUV reconciliation for certain creditor institution.", description = "Execute reconciliation of all IUVs for certain creditor institution, sending RT for close payment.", security = {@SecurityRequirement(name = "ApiKey")}, tags = {"Recovery"})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Started reconciling IUV with explicit RT send")
@ApiResponse(responseCode = "200", description = "Completed IUV reconciliation with explicit RT submission"),
@ApiResponse(responseCode = "400", description = "It is not possible to complete reconciliation (with explicit RT submission) for the submitted UIV")
})
@PostMapping(value = "/{creditor_institution}/rpt/{iuv}/receipt-ko")
public ResponseEntity<String> recoverReceiptKOForCreditorInstitutionAndIUV(@Pattern(regexp = "[a-zA-Z0-9_-]{1,100}") @PathVariable("creditor_institution") String ci,
public ResponseEntity<RecoveryReceiptResponse> recoverReceiptKOForCreditorInstitutionAndIUV(@Pattern(regexp = "[a-zA-Z0-9_-]{1,100}") @PathVariable("creditor_institution") String ci,
@Pattern(regexp = "[a-zA-Z0-9_-]{1,100}") @PathVariable("iuv") String iuv,
@Pattern(regexp = "[a-zA-Z0-9_-]{1,10}") @QueryParam("date_from") String dateFrom,
@Pattern(regexp = "[a-zA-Z0-9_-]{1,10}") @QueryParam("date_to") String dateTo) {
try {
log.info("Invoking API operation recoverReceiptKOForCreditorInstitution - args: {} {} {} {}", ci, iuv, dateFrom, dateTo);

boolean recovered = recoveryService.recoverReceiptKOByIUV(ci, iuv, dateFrom, dateTo);
if(recovered)
return ResponseEntity.ok(String.format("RPT with CI %s and IUV %s recovered via API", ci, iuv));
else return ResponseEntity.ok(String.format("RPT with CI %s and IUV %s could not be recovered via API", ci, iuv));
RecoveryReceiptResponse recoveryReceiptResponse = recoveryService.recoverReceiptKOByIUV(ci, iuv, dateFrom, dateTo);
if(recoveryReceiptResponse != null) {
RecoveryReceiptResponse response = recoveryService.recoverReceiptKOByCI(ci, dateFrom, dateTo);
return ResponseEntity.ok(response);
} else {
// RPT with CI and IUV could not be recovered via API
return ResponseEntity.badRequest().build();
}
} catch (Exception ex) {
String operationId = MDC.get(Constants.MDC_OPERATION_ID);
log.error(String.format("GenericException: operation-id=[%s]", operationId != null ? operationId : "n/a"), ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public void recoverReceiptKOCronJob() {
log.info("[Scheduled] Reconciliation Cron: recoverReceiptKOCronJob running at {}, for recover stale RPT from {} to {}",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()), dateFrom, dateTo);

int receiptSize = recoveryService.recoverReceiptKOByDates(dateFrom, dateTo);
int missingRedirectRecovery = recoveryService.recoverMissingRedirect(dateFrom, dateTo);
int missingRTRecovered = this.recoveryService.recoverMissingRT(dateFrom, dateTo);
int missingRedirectRecovered = this.recoveryService.recoverMissingRedirect(dateFrom, dateTo);

log.info("[Scheduled] Reconciliation Cron: recoverReceiptKOCronJob {} receipt-ko sent", receiptSize + missingRedirectRecovery);
log.info("[Scheduled] Reconciliation Cron: recoverReceiptKOCronJob {} receipt-ko sent", missingRedirectRecovered + missingRTRecovered);
this.threadOfExecution = Thread.currentThread();
}
}
114 changes: 65 additions & 49 deletions src/main/java/it/gov/pagopa/wispconverter/service/RecoveryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class RecoveryService {
@Value("${wisp-converter.recovery.receipt-generation.wait-time.minutes:60}")
public Long receiptGenerationWaitTime;

public boolean recoverReceiptKOByIUV(String creditorInstitution, String iuv, String dateFrom, String dateTo) {
public RecoveryReceiptResponse recoverReceiptKOByIUV(String creditorInstitution, String iuv, String dateFrom, String dateTo) {
checkDateValidity(dateFrom, dateTo);
List<ReEventEntity> reEvents = reEventRepository.findByIuvAndOrganizationId(dateFrom, dateTo, iuv, creditorInstitution)
.stream()
Expand All @@ -76,11 +76,19 @@ public boolean recoverReceiptKOByIUV(String creditorInstitution, String iuv, Str
String status = lastEvent.getStatus();
if(status != null && interruptStatusSet.contains(status)) {
this.recoverReceiptKO(creditorInstitution, iuv, lastEvent.getSessionId(), lastEvent.getCcp(), dateFrom, dateTo);
return true;
return RecoveryReceiptResponse.builder()
.payments(
List.of(
RecoveryReceiptPaymentResponse.builder()
.iuv(iuv)
.ccp(lastEvent.getCcp())
.ci(lastEvent.getDomainId())
.build()))
.build();
}
}

return false;
return null;
}

public RecoveryReceiptResponse recoverReceiptKOByCI(String creditorInstitution, String dateFrom, String dateTo) {
Expand Down Expand Up @@ -121,52 +129,6 @@ public RecoveryReceiptResponse recoverReceiptKOByCI(String creditorInstitution,
.build();
}

// Recover all CI for which there is a stale/pending RPT (i.e. receipts-rt = null)
public int recoverReceiptKOByDates(ZonedDateTime dateFrom, ZonedDateTime dateTo) {
String dateFromString = dateFrom.format(DateTimeFormatter.ofPattern(DATE_FORMAT));
String dateToString = dateTo.format(DateTimeFormatter.ofPattern(DATE_FORMAT));

List<RTEntity> receiptRTs = rtRepository.findPendingRT(dateFromString, dateToString);
List<RecoveryReceiptPaymentResponse> paymentsToReconcile = receiptRTs.stream().map(entity -> RecoveryReceiptPaymentResponse.builder()
.iuv(entity.getIuv())
.ccp(entity.getCcp())
.ci(entity.getIdDominio())
.build())
.toList();

recoverReceiptKOByRecoveryPayment(dateFromString, dateToString, paymentsToReconcile);

return RecoveryReceiptResponse.builder()
.payments(paymentsToReconcile)
.build()
.getPayments()
.size();
}

public int recoverMissingRedirect(ZonedDateTime dateFrom, ZonedDateTime dateTo) {
String dateFromString = dateFrom.format(DateTimeFormatter.ofPattern(DATE_FORMAT));
String dateToString = dateTo.format(DateTimeFormatter.ofPattern(DATE_FORMAT));

List<SessionIdEntity> sessionsWithoutRedirect = reEventRepository.findSessionWithoutRedirect(dateFromString, dateToString);

for(SessionIdEntity sessionIdEntity : sessionsWithoutRedirect) {
String sessionId = sessionIdEntity.getSessionId();
List<ReEventEntity> reEventList = reEventRepository.findBySessionIdAndStatus(dateFromString, dateToString, sessionId, RPT_ACCETTATA_NODO);

if(!reEventList.isEmpty()) {
ReEventEntity reEvent = reEventList.get(0);
String iuv = reEvent.getIuv();
String ccp = reEvent.getCcp();
String ci = reEvent.getDomainId();

log.info("[RECOVER-MISSING-REDIRECT] Recovery with receipt-ko for ci = {}, iuv = {}, ccp = {}, sessionId = {}", ci, iuv, ccp, sessionId);
this.recoverReceiptKO(ci, iuv, ccp, sessionId, dateFromString, dateToString);
}
}

return sessionsWithoutRedirect.size();
}

private CompletableFuture<Boolean> recoverReceiptKOAsync(String dateFrom, String dateTo, List<RecoveryReceiptPaymentResponse> paymentsToReconcile) {
return CompletableFuture.supplyAsync(() -> recoverReceiptKOByRecoveryPayment(dateFrom, dateTo, paymentsToReconcile));
}
Expand Down Expand Up @@ -204,6 +166,60 @@ private boolean recoverReceiptKOByRecoveryPayment(String dateFrom, String dateTo
return true;
}

// missing rt recovery
public int recoverMissingRT(ZonedDateTime dateFrom, ZonedDateTime dateTo) {
String dateFromString = dateFrom.format(DateTimeFormatter.ofPattern(DATE_FORMAT));
String dateToString = dateTo.format(DateTimeFormatter.ofPattern(DATE_FORMAT));
List<RTEntity> receiptRTs = rtRepository.findPendingRT(dateFromString, dateToString);
int recovered = 0;

for(RTEntity rt : receiptRTs) {
String iuv = rt.getIuv();
String ci = rt.getIdDominio();
String ccp = rt.getCcp();

List<ReEventEntity> reEvents = reEventRepository.findByIuvAndOrganizationId(dateFromString, dateToString, iuv, ci);
Set<String> interruptStatusSet = getWISPInterruptStatusSet();

if(!reEvents.isEmpty()) {
ReEventEntity lastEvent = reEvents.get(0);
String status = lastEvent.getStatus();
if(status != null && interruptStatusSet.contains(status)) {
log.info("[RECOVER-MISSING-RT] Recovery with receipt-ko for ci = {}, iuv = {}, ccp = {}", ci, iuv, ccp);
this.recoverReceiptKO(ci, iuv, lastEvent.getSessionId(), lastEvent.getCcp(), dateFromString, dateToString);
recovered++;
}
}
}

return recovered;
}

// missing redirect recovery
public int recoverMissingRedirect(ZonedDateTime dateFrom, ZonedDateTime dateTo) {
String dateFromString = dateFrom.format(DateTimeFormatter.ofPattern(DATE_FORMAT));
String dateToString = dateTo.format(DateTimeFormatter.ofPattern(DATE_FORMAT));

List<SessionIdEntity> sessionsWithoutRedirect = reEventRepository.findSessionWithoutRedirect(dateFromString, dateToString);

for(SessionIdEntity sessionIdEntity : sessionsWithoutRedirect) {
String sessionId = sessionIdEntity.getSessionId();
List<ReEventEntity> reEventList = reEventRepository.findBySessionIdAndStatus(dateFromString, dateToString, sessionId, RPT_ACCETTATA_NODO);

if(!reEventList.isEmpty()) {
ReEventEntity reEvent = reEventList.get(0);
String iuv = reEvent.getIuv();
String ccp = reEvent.getCcp();
String ci = reEvent.getDomainId();

log.info("[RECOVER-MISSING-REDIRECT] Recovery with receipt-ko for ci = {}, iuv = {}, ccp = {}, sessionId = {}", ci, iuv, ccp, sessionId);
this.recoverReceiptKO(ci, iuv, ccp, sessionId, dateFromString, dateToString);
}
}

return sessionsWithoutRedirect.size();
}

// check if there is a successful RT submission, if there isn't prepare cached data and send receipt-ko
public void recoverReceiptKO(String ci, String iuv, String ccp, String sessionId, String dateFrom, String dateTo) {
// search by sessionId, then filter by status=RT_SEND_SUCCESS. If there is zero, then proceed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void testRecoverReceiptKOForCreditorInstitutionAndIUV() throws Exception {
mockMvc.perform(post("/recovery/{ci}/rpt/{iuv}/receipt-ko", ci, iuv)
.queryParam("date_from", dateFrom)
.queryParam("date_to", dateTo))
.andExpect(status().isOk());
.andExpect(status().isBadRequest());

Mockito.verify(recoveryService, times(1)).recoverReceiptKOByIUV(eq(ci), eq(iuv), any(), any());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ public void setup() {
@Test
void testRecoverReceiptKOCronJob() {
// Arrange
when(recoveryService.recoverReceiptKOByDates(any(), any())).thenReturn(5);
when(recoveryService.recoverMissingRT(any(), any())).thenReturn(5);
when(recoveryService.recoverMissingRedirect(any(), any())).thenReturn(3);

// Act
recoveryScheduler.recoverReceiptKOCronJob();

// Assert
verify(recoveryService, times(1)).recoverReceiptKOByDates(any(ZonedDateTime.class), any(ZonedDateTime.class));
verify(recoveryService, times(1)).recoverMissingRT(any(ZonedDateTime.class), any(ZonedDateTime.class));
verify(recoveryService, times(1)).recoverMissingRedirect(any(ZonedDateTime.class), any(ZonedDateTime.class));

assertNotNull(recoveryScheduler.getThreadOfExecution());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void testRecoverReceiptKOAll() {
when(rtRepository.findPendingRT(anyString(), anyString())).thenReturn(mockRTEntities);

// Act
int recoveredReceipt = recoveryService.recoverReceiptKOByDates(dateFrom, dateTo);
int recoveredReceipt = recoveryService.recoverMissingRT(dateFrom, dateTo);

// Assert
assertEquals(0, recoveredReceipt);
Expand All @@ -108,7 +108,7 @@ public void testRecoverReceiptKOAll_notEmpty() {
when(reRepository.findByIuvAndOrganizationId(anyString(), anyString(), anyString(), anyString())).thenReturn(mockReEventEntities);

// Act
int recoveredReceipt = recoveryService.recoverReceiptKOByDates(dateFrom, dateTo);
int recoveredReceipt = recoveryService.recoverMissingRT(dateFrom, dateTo);

// Assert
assertEquals(1, recoveredReceipt);
Expand Down

0 comments on commit 33d12c7

Please sign in to comment.