Skip to content

Commit

Permalink
[PRDP-253] split recover failed APIs and do some refactor to avoid du…
Browse files Browse the repository at this point in the history
…plicated code
  • Loading branch information
giomella committed Dec 1, 2023
1 parent c0b2be4 commit d4b2889
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
package it.gov.pagopa.receipt.pdf.helpdesk;

import com.azure.cosmos.models.FeedResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.OutputBinding;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.BindingName;
import com.microsoft.azure.functions.annotation.CosmosDBOutput;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
import it.gov.pagopa.receipt.pdf.helpdesk.client.ReceiptCosmosClient;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.ReceiptCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.PDVTokenizerException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ReceiptFailedRecoveryRequest;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.ReceiptCosmosServiceImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.time.LocalDateTime;
import java.util.Optional;


Expand All @@ -39,23 +39,22 @@ public class RecoverFailedReceipt {

private final BizEventToReceiptService bizEventToReceiptService;
private final BizEventCosmosClient bizEventCosmosClient;
private final ReceiptCosmosClient receiptCosmosClient;
private final ReceiptCosmosService receiptCosmosService;

public RecoverFailedReceipt(){
this.bizEventToReceiptService = new BizEventToReceiptServiceImpl();
this.receiptCosmosClient = ReceiptCosmosClientImpl.getInstance();
this.receiptCosmosService = new ReceiptCosmosServiceImpl();
this.bizEventCosmosClient = BizEventCosmosClientImpl.getInstance();
}

RecoverFailedReceipt(BizEventToReceiptService bizEventToReceiptService,
BizEventCosmosClient bizEventCosmosClient,
ReceiptCosmosClient receiptCosmosClient){
ReceiptCosmosService receiptCosmosService){
this.bizEventToReceiptService = bizEventToReceiptService;
this.bizEventCosmosClient = bizEventCosmosClient;
this.receiptCosmosClient = receiptCosmosClient;
this.receiptCosmosService = receiptCosmosService;
}


/**
* This function will be invoked when a Http Trigger occurs
*
Expand All @@ -65,116 +64,57 @@ public RecoverFailedReceipt(){
public HttpResponseMessage run (
@HttpTrigger(name = "RecoverFailedReceiptTrigger",
methods = {HttpMethod.PUT},
route = "recoverFailed",
route = "/receipts/{event-id}/recover-failed",
authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<ReceiptFailedRecoveryRequest>> request,
HttpRequestMessage<Optional<String>> request,
@BindingName("event-id") String eventId,
@CosmosDBOutput(
name = "ReceiptDatastore",
databaseName = "db",
collectionName = "receipts",
connectionStringSetting = "COSMOS_RECEIPTS_CONN_STRING")
OutputBinding<List<Receipt>> documentdb,
OutputBinding<Receipt> documentdb,
final ExecutionContext context) {

List<Receipt> receiptList = new ArrayList<>();
logger.info("[{}] function called at {}", context.getFunctionName(), LocalDateTime.now());

if (eventId == null || eventId.isBlank()) {
return request
.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ProblemJson.builder()
.title(HttpStatus.BAD_REQUEST.name())
.detail("Please pass a valid biz-event id")
.status(HttpStatus.BAD_REQUEST.value())
.build())
.build();
}

try {
Receipt receipt = BizEventToReceiptUtils.getEvent(eventId, context, this.bizEventToReceiptService,
this.bizEventCosmosClient, this.receiptCosmosService, null, logger);

ReceiptFailedRecoveryRequest receiptFailedRecoveryRequest = request.getBody().orElse(
new ReceiptFailedRecoveryRequest());

if (receiptFailedRecoveryRequest.getEventId() != null) {

getEvent(receiptFailedRecoveryRequest.getEventId(), context, bizEventToReceiptService, receiptList,
bizEventCosmosClient, receiptCosmosClient, null);

} else {

String continuationToken = null;

do {

Iterable<FeedResponse<Receipt>> feedResponseIterator =
receiptCosmosClient.getFailedReceiptDocuments(continuationToken, 100);

for (FeedResponse<Receipt> page : feedResponseIterator) {

for (Receipt receipt : page.getResults()) {
try {
getEvent(receipt.getEventId(), context, bizEventToReceiptService, receiptList,
bizEventCosmosClient, receiptCosmosClient, receipt);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}

continuationToken = page.getContinuationToken();

}

} while (continuationToken != null);

}


documentdb.setValue(receiptList);
documentdb.setValue(receipt);
String responseMsg = String.format("Receipt with eventId %s recovered", eventId);
return request.createResponseBuilder(HttpStatus.OK)
.body("OK")
.body(responseMsg)
.build();

} catch (NoSuchElementException | ReceiptNotFoundException | BizEventNotFoundException exception) {
logger.error(exception.getMessage(), exception);
return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
} catch (BizEventNotFoundException exception) {
String msg = String.format("Unable to retrieve the biz-event with id %s", eventId);
logger.error(msg, exception);
return request
.createResponseBuilder(HttpStatus.NOT_FOUND)
.body(msg)
.build();
} catch (PDVTokenizerException | JsonProcessingException e) {
logger.error(e.getMessage(), e);
return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
return request
.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ProblemJson.builder()
.title(HttpStatus.INTERNAL_SERVER_ERROR.name())
.detail(e.getMessage())
.status(HttpStatus.INTERNAL_SERVER_ERROR.value())
.build())
.build();
}
}

private void getEvent(String eventId, ExecutionContext context,
BizEventToReceiptService bizEventToReceiptService,
List<Receipt> receiptList, BizEventCosmosClient bizEventCosmosClient,
ReceiptCosmosClient receiptCosmosClient, Receipt receipt)
throws BizEventNotFoundException, ReceiptNotFoundException, PDVTokenizerException, JsonProcessingException {

BizEvent bizEvent = bizEventCosmosClient.getBizEventDocument(
eventId);

if (!BizEventToReceiptUtils.isBizEventInvalid(bizEvent, context, logger)) {

if (receipt == null) {
try {
receipt = receiptCosmosClient.getReceiptDocument(
eventId);
} catch (ReceiptNotFoundException e) {
receipt = BizEventToReceiptUtils.createReceipt(bizEvent,
bizEventToReceiptService, logger);
receipt.setStatus(ReceiptStatusType.FAILED);
}
}

if (receipt != null && (
receipt.getStatus().equals(ReceiptStatusType.FAILED) ||
receipt.getStatus().equals(ReceiptStatusType.INSERTED) ||
receipt.getStatus().equals(ReceiptStatusType.NOT_QUEUE_SENT)
)) {
if (receipt.getEventData() == null || receipt.getEventData().getDebtorFiscalCode() == null) {
BizEventToReceiptUtils.tokenizeReceipt(bizEventToReceiptService, bizEvent, receipt);
}
bizEventToReceiptService.handleSendMessageToQueue(bizEvent, receipt);
if(receipt.getStatus() != ReceiptStatusType.NOT_QUEUE_SENT){
receipt.setStatus(ReceiptStatusType.INSERTED);
receipt.setInsertedAt(System.currentTimeMillis());
receipt.setReasonErr(null);
receipt.setReasonErrPayer(null);
}
receiptList.add(receipt);
}

}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package it.gov.pagopa.receipt.pdf.helpdesk;

import com.azure.cosmos.models.FeedResponse;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.OutputBinding;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.CosmosDBOutput;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import it.gov.pagopa.receipt.pdf.helpdesk.client.BizEventCosmosClient;
import it.gov.pagopa.receipt.pdf.helpdesk.client.impl.BizEventCosmosClientImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.Receipt;
import it.gov.pagopa.receipt.pdf.helpdesk.entity.receipt.enumeration.ReceiptStatusType;
import it.gov.pagopa.receipt.pdf.helpdesk.model.ProblemJson;
import it.gov.pagopa.receipt.pdf.helpdesk.service.BizEventToReceiptService;
import it.gov.pagopa.receipt.pdf.helpdesk.service.ReceiptCosmosService;
import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.BizEventToReceiptServiceImpl;
import it.gov.pagopa.receipt.pdf.helpdesk.service.impl.ReceiptCosmosServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

import static it.gov.pagopa.receipt.pdf.helpdesk.utils.BizEventToReceiptUtils.getEvent;


/**
* Azure Functions with Azure Http trigger.
*/
public class RecoverFailedReceiptMassive {

private final Logger logger = LoggerFactory.getLogger(RecoverFailedReceiptMassive.class);

private final BizEventToReceiptService bizEventToReceiptService;
private final BizEventCosmosClient bizEventCosmosClient;
private final ReceiptCosmosService receiptCosmosService;

public RecoverFailedReceiptMassive(){
this.bizEventToReceiptService = new BizEventToReceiptServiceImpl();
this.receiptCosmosService = new ReceiptCosmosServiceImpl();
this.bizEventCosmosClient = BizEventCosmosClientImpl.getInstance();
}

RecoverFailedReceiptMassive(BizEventToReceiptService bizEventToReceiptService,
BizEventCosmosClient bizEventCosmosClient,
ReceiptCosmosService receiptCosmosService){
this.bizEventToReceiptService = bizEventToReceiptService;
this.bizEventCosmosClient = bizEventCosmosClient;
this.receiptCosmosService = receiptCosmosService;
}

/**
* This function will be invoked when a Http Trigger occurs
*
* @return response with HttpStatus.OK
*/
@FunctionName("RecoverFailedReceiptMassive")
public HttpResponseMessage run (
@HttpTrigger(name = "RecoverFailedReceiptMassiveTrigger",
methods = {HttpMethod.PUT},
route = "/receipts/recover-failed",
authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
@CosmosDBOutput(
name = "ReceiptDatastore",
databaseName = "db",
collectionName = "receipts",
connectionStringSetting = "COSMOS_RECEIPTS_CONN_STRING")
OutputBinding<List<Receipt>> documentdb,
final ExecutionContext context) {
logger.info("[{}] function called at {}", context.getFunctionName(), LocalDateTime.now());

// Get named parameter
String status = request.getQueryParameters().get("status");
if (status == null) {
return request
.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ProblemJson.builder()
.title(HttpStatus.BAD_REQUEST.name())
.detail("Please pass a status to recover")
.status(HttpStatus.BAD_REQUEST.value())
.build())
.build();
}

ReceiptStatusType statusType;
try {
statusType = ReceiptStatusType.valueOf(status);
} catch (IllegalArgumentException e) {
return request
.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ProblemJson.builder()
.title(HttpStatus.BAD_REQUEST.name())
.detail("Please pass a valid status to recover")
.status(HttpStatus.BAD_REQUEST.value())
.build())
.build();
}

List<Receipt> receiptList = new ArrayList<>();
String continuationToken = null;
int errorCounter = 0;
try {
do {
Iterable<FeedResponse<Receipt>> feedResponseIterator =
this.receiptCosmosService.getFailedReceiptByStatus(continuationToken, 100, statusType);

for (FeedResponse<Receipt> page : feedResponseIterator) {
for (Receipt receipt : page.getResults()) {
try {
Receipt restored = getEvent(receipt.getEventId(), context, this.bizEventToReceiptService,
this.bizEventCosmosClient, this.receiptCosmosService, receipt, logger);
receiptList.add(restored);
} catch (Exception e) {
logger.error(e.getMessage(), e);
errorCounter++;
}
}
continuationToken = page.getContinuationToken();
}
} while (continuationToken != null);
} catch (NoSuchElementException e) {
logger.error(e.getMessage(), e);
return request
.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ProblemJson.builder()
.title(HttpStatus.INTERNAL_SERVER_ERROR.name())
.detail(e.getMessage())
.status(HttpStatus.INTERNAL_SERVER_ERROR.value())
.build())
.build();
}

documentdb.setValue(receiptList);
if (errorCounter > 0) {
String msg = String.format("Recovered %s receipt but %s encountered an error.", receiptList.size(), errorCounter);
return request
.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ProblemJson.builder()
.title("Partial OK")
.detail(msg)
.status(HttpStatus.MULTI_STATUS.value())
.build())
.build();
}
String responseMsg = String.format("Recovered %s receipt", receiptList.size());
return request.createResponseBuilder(HttpStatus.OK)
.body(responseMsg)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import it.gov.pagopa.receipt.pdf.helpdesk.entity.event.BizEvent;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.BizEventNotFoundException;
import it.gov.pagopa.receipt.pdf.helpdesk.exception.ReceiptNotFoundException;

public interface BizEventCosmosClient {
BizEvent getBizEventDocument(String eventId) throws ReceiptNotFoundException, BizEventNotFoundException;
BizEvent getBizEventDocument(String eventId) throws BizEventNotFoundException;
}
Loading

0 comments on commit d4b2889

Please sign in to comment.