Skip to content

Commit

Permalink
[PAGOPA-2341] code smells
Browse files Browse the repository at this point in the history
  • Loading branch information
jacopocarlini committed Nov 8, 2024
1 parent 10d3117 commit e252df8
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 252 deletions.
278 changes: 149 additions & 129 deletions src/main/java/it/gov/pagopa/wispconverter/service/RecoveryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.Gson;
import gov.telematici.pagamenti.ws.nodoperpa.ppthead.IntestazionePPT;
import gov.telematici.pagamenti.ws.pafornode.PaSendRTV2Request;
import gov.telematici.pagamenti.ws.papernodo.ObjectFactory;
import it.gov.pagopa.gen.wispconverter.client.cache.model.ConnectionDto;
import it.gov.pagopa.gen.wispconverter.client.cache.model.StationDto;
import it.gov.pagopa.wispconverter.controller.ReceiptController;
Expand Down Expand Up @@ -418,146 +419,165 @@ public RecoveryReceiptReportResponse recoverReceiptToBeReSent(RecoveryReceiptReq
gov.telematici.pagamenti.ws.papernodo.ObjectFactory objectFactory =
new gov.telematici.pagamenti.ws.papernodo.ObjectFactory();
for (String receiptId : request.getReceiptIds()) {
recoverSingleReceipt(receiptId, objectFactory, response);
}

String sessionId = null;
try {
Optional<RTRequestEntity> rtRequestEntityOpt = rtRetryRepository.findById(receiptId);
if (rtRequestEntityOpt.isEmpty()) {
throw new AppException(
AppErrorCodeMessageEnum.ERROR,
String.format("No valid receipt found with id [%s]", receiptId));
}
return response;
}

RTRequestEntity rtRequestEntity = rtRequestEntityOpt.get();
String idempotencyKey = rtRequestEntity.getIdempotencyKey();
String[] idempotencyKeyComponents = idempotencyKey.split("_");
if (idempotencyKeyComponents.length < 2) {
throw new AppException(
AppErrorCodeMessageEnum.ERROR,
String.format(
"Invalid idempotency key [%s]. It must be composed of sessionId, notice number and domain.",
idempotencyKey));
}
private void recoverSingleReceipt(String receiptId, ObjectFactory objectFactory, RecoveryReceiptReportResponse response) {
String sessionId = null;
try {
RTRequestEntity rtRequestEntity = findRtRequestEntityIfExists(receiptId);
String[] idempotencyKeyComponents = getIdempotencyKeyComponents(rtRequestEntity);

sessionId = idempotencyKeyComponents[0];
MDC.put(Constants.MDC_SESSION_ID, sessionId);
RPTRequestEntity rptRequestEntity = findRptRequestEntityIfExists(sessionId);
SessionDataDTO sessionData =
rptExtractorService.extractSessionData(
rptRequestEntity.getPrimitive(), rptRequestEntity.getPayload());

String stationId = sessionData.getCommonFields().getStationId();
StationDto station = configCacheService.getStationByIdFromCache(stationId);

// regenerate destination networking info
ConnectionDto stationConnection = station.getConnection();
URI uri =
CommonUtility.constructUrl(
stationConnection.getProtocol().getValue(),
stationConnection.getIp(),
stationConnection.getPort().intValue(),
station.getService() != null ? station.getService().getPath() : "");
rtRequestEntity.setUrl(uri.toString());
rtRequestEntity.setHeaders(generateHeader(uri, station));

InetSocketAddress proxyAddress =
CommonUtility.constructProxyAddress(uri, station, apimPath);
if (proxyAddress != null) {
rtRequestEntity.setProxyAddress(
String.format("%s:%s", proxyAddress.getHostString(), proxyAddress.getPort()));
}

sessionId = idempotencyKeyComponents[0];
MDC.put(Constants.MDC_SESSION_ID, sessionId);
Optional<RPTRequestEntity> rptRequestOpt = rptRequestRepository.findById(sessionId);
if (rptRequestOpt.isEmpty()) {
throw new AppException(
AppErrorCodeMessageEnum.ERROR,
String.format("No valid RPT request found with id [%s].", sessionId));
}
// regenerate paaInviaRT payload info
// extract data from old paaInviaRT
String oldReceipt =
new String(ZipUtil.unzip(AppBase64Util.base64Decode(rtRequestEntity.getPayload())));

SOAPMessage msg = jaxbElementUtil.getMessage(oldReceipt);

IntestazionePPT oldReceiptHeader = jaxbElementUtil.getHeader(msg, IntestazionePPT.class);

String domainId = oldReceiptHeader.getIdentificativoDominio();
String iuv = oldReceiptHeader.getIdentificativoUnivocoVersamento();

// retrieve the needed RPT
List<RPTContentDTO> rpts = ReceiptService.extractRequiredRPTs(sessionData, iuv, domainId);
int overrideId = 1;
for (RPTContentDTO rpt : rpts) {

// Re-generate the RT payload in order to actualize values and structural errors
// If newly-generated payload is not null, the data in 'receipt-rt' is updated with
// extracted data
String newlyGeneratedPayload =
regenerateReceiptPayload(
rtRequestEntity.getPartitionKey(),
rtRequestEntity.getReceiptType(),
sessionData,
rpt,
objectFactory);

String payload = newlyGeneratedPayload != null ? newlyGeneratedPayload : oldReceipt;

// update entity from 'receipt' container with retry 0 and newly-generated payload
String rptDomainId = rpt.getRpt().getDomain().getDomainId();
String overriddenIdempotencyKey =
String.format(
"%s_%s_%s",
idempotencyKeyComponents[0], idempotencyKeyComponents[1], rptDomainId);
String overriddenReceiptId = receiptId + "-" + overrideId;
rtRequestEntity.setId(overriddenReceiptId);
rtRequestEntity.setDomainId(domainId);
rtRequestEntity.setIdempotencyKey(overriddenIdempotencyKey);
rtRequestEntity.setSessionId(sessionId);
rtRequestEntity.setRetry(0);
rtRequestEntity.setPayload(AppBase64Util.base64Encode(ZipUtil.zip(payload)));
rtRetryRepository.save(rtRequestEntity);

String compositedIdForReceipt =
String.format("%s_%s", rtRequestEntity.getPartitionKey(), overriddenReceiptId);
serviceBusService.sendMessage(compositedIdForReceipt, null);

RPTRequestEntity rptRequestEntity = rptRequestOpt.get();
SessionDataDTO sessionData =
rptExtractorService.extractSessionData(
rptRequestEntity.getPrimitive(), rptRequestEntity.getPayload());

String stationId = sessionData.getCommonFields().getStationId();
StationDto station = configCacheService.getStationByIdFromCache(stationId);

// regenerate destination networking info
ConnectionDto stationConnection = station.getConnection();
URI uri =
CommonUtility.constructUrl(
stationConnection.getProtocol().getValue(),
stationConnection.getIp(),
stationConnection.getPort().intValue(),
station.getService() != null ? station.getService().getPath() : "");
rtRequestEntity.setUrl(uri.toString());
rtRequestEntity.setHeaders(generateHeader(uri, station));

InetSocketAddress proxyAddress =
CommonUtility.constructProxyAddress(uri, station, apimPath);
if (proxyAddress != null) {
rtRequestEntity.setProxyAddress(
String.format("%s:%s", proxyAddress.getHostString(), proxyAddress.getPort()));
}
generateRE(
Constants.PAA_INVIA_RT,
WorkflowStatus.RT_SEND_RESCHEDULING_SUCCESS,
domainId,
iuv,
rpt.getCcp(),
sessionId,
String.format("Generated receipt: %s", overriddenReceiptId));
response.getReceiptStatus().add(Pair.of(overriddenReceiptId, "SCHEDULED"));
overrideId += 1;
}
// remove old receipt
rtRetryRepository.deleteById(
receiptId, new PartitionKey(rtRequestEntity.getPartitionKey()));

// regenerate paaInviaRT payload info
// extract data from old paaInviaRT
String oldReceipt =
new String(ZipUtil.unzip(AppBase64Util.base64Decode(rtRequestEntity.getPayload())));

SOAPMessage msg = jaxbElementUtil.getMessage(oldReceipt);

IntestazionePPT oldReceiptHeader = jaxbElementUtil.getHeader(msg, IntestazionePPT.class);

String domainId = oldReceiptHeader.getIdentificativoDominio();
String iuv = oldReceiptHeader.getIdentificativoUnivocoVersamento();

// retrieve the needed RPT
List<RPTContentDTO> rpts = ReceiptService.extractRequiredRPTs(sessionData, iuv, domainId);
int overrideId = 1;
for (RPTContentDTO rpt : rpts) {

// Re-generate the RT payload in order to actualize values and structural errors
// If newly-generated payload is not null, the data in 'receipt-rt' is updated with
// extracted data
String newlyGeneratedPayload =
regenerateReceiptPayload(
rtRequestEntity.getPartitionKey(),
rtRequestEntity.getReceiptType(),
sessionData,
rpt,
objectFactory);

String payload = newlyGeneratedPayload != null ? newlyGeneratedPayload : oldReceipt;

// update entity from 'receipt' container with retry 0 and newly-generated payload
String rptDomainId = rpt.getRpt().getDomain().getDomainId();
String overriddenIdempotencyKey =
String.format(
"%s_%s_%s",
idempotencyKeyComponents[0], idempotencyKeyComponents[1], rptDomainId);
String overriddenReceiptId = receiptId + "-" + overrideId;
rtRequestEntity.setId(overriddenReceiptId);
rtRequestEntity.setDomainId(domainId);
rtRequestEntity.setIdempotencyKey(overriddenIdempotencyKey);
rtRequestEntity.setSessionId(sessionId);
rtRequestEntity.setRetry(0);
rtRequestEntity.setPayload(AppBase64Util.base64Encode(ZipUtil.zip(payload)));
rtRetryRepository.save(rtRequestEntity);

String compositedIdForReceipt =
String.format("%s_%s", rtRequestEntity.getPartitionKey(), overriddenReceiptId);
serviceBusService.sendMessage(compositedIdForReceipt, null);

generateRE(
Constants.PAA_INVIA_RT,
WorkflowStatus.RT_SEND_RESCHEDULING_SUCCESS,
domainId,
iuv,
rpt.getCcp(),
sessionId,
String.format("Generated receipt: %s", overriddenReceiptId));
response.getReceiptStatus().add(Pair.of(overriddenReceiptId, "SCHEDULED"));
overrideId += 1;
}
// remove old receipt
rtRetryRepository.deleteById(
receiptId, new PartitionKey(rtRequestEntity.getPartitionKey()));
} catch (Exception e) {
handleExceptionRecoverSingleReceipt(receiptId, response, e, sessionId);
}
}

} catch (Exception e) {
private RPTRequestEntity findRptRequestEntityIfExists(String sessionId) {
Optional<RPTRequestEntity> rptRequestOpt = rptRequestRepository.findById(sessionId);
if (rptRequestOpt.isEmpty()) {
throw new AppException(
AppErrorCodeMessageEnum.ERROR,
String.format("No valid RPT request found with id [%s].", sessionId));
}

log.error("Reconciliation for receipt id [{}] ended unsuccessfully!", receiptId, e);
return rptRequestOpt.get();
}

generateRE(
Constants.PAA_INVIA_RT,
WorkflowStatus.RT_SEND_RESCHEDULING_FAILURE,
null,
null,
null,
sessionId,
null);
private static String[] getIdempotencyKeyComponents(RTRequestEntity rtRequestEntity) {
String idempotencyKey = rtRequestEntity.getIdempotencyKey();
String[] idempotencyKeyComponents = idempotencyKey.split("_");
if (idempotencyKeyComponents.length < 2) {
throw new AppException(
AppErrorCodeMessageEnum.ERROR,
String.format(
"Invalid idempotency key [%s]. It must be composed of sessionId, notice number and domain.",
idempotencyKey));
}
return idempotencyKeyComponents;
}

response
.getReceiptStatus()
.add(Pair.of(receiptId, String.format("FAILED: [%s]", e.getMessage())));
}
private RTRequestEntity findRtRequestEntityIfExists(String receiptId) {
Optional<RTRequestEntity> rtRequestEntityOpt = rtRetryRepository.findById(receiptId);
if (rtRequestEntityOpt.isEmpty()) {
throw new AppException(
AppErrorCodeMessageEnum.ERROR,
String.format("No valid receipt found with id [%s]", receiptId));
}

return response;
RTRequestEntity rtRequestEntity = rtRequestEntityOpt.get();
return rtRequestEntity;
}

private void handleExceptionRecoverSingleReceipt(String receiptId, RecoveryReceiptReportResponse response, Exception e, String sessionId) {
log.error("Reconciliation for receipt id [{}] ended unsuccessfully!", receiptId, e);

Check failure

Code scanning / CodeQL

Log Injection High

This log entry depends on a
user-provided value
.

generateRE(
Constants.PAA_INVIA_RT,
WorkflowStatus.RT_SEND_RESCHEDULING_FAILURE,
null,
null,
null,
sessionId,
null);

response.getReceiptStatus()
.add(Pair.of(receiptId, String.format("FAILED: [%s]", e.getMessage())));
}

private List<String> generateHeader(URI uri, StationDto station) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,18 @@
import it.gov.pagopa.wispconverter.util.CommonUtility;
import it.gov.pagopa.wispconverter.util.Constants;
import it.gov.pagopa.wispconverter.util.MDCUtil;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.List;
import javax.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.List;

/**
* This class is the consumer of the queue 'ecommerce-hang-timeout' of the service bus.
* When a schedule message trigger this class we'll expire the payment,
Expand All @@ -43,15 +41,17 @@ public class ECommerceHangTimeoutConsumer extends SBConsumer {
@Value("${azure.sb.queue.ecommerce-hang-timeout.name}")
private String queueName;

@Autowired
private ReceiptService receiptService;

@Autowired
private ReService reService;
private final ReceiptService receiptService;
private final ReService reService;

@Value("${disable-service-bus-receiver}")
private boolean disableServiceBusReceiver;

public ECommerceHangTimeoutConsumer(ReceiptService receiptService, ReService reService) {
this.receiptService = receiptService;
this.reService = reService;
}

@PostConstruct
public void post() {
if (StringUtils.isNotBlank(connectionString) && !connectionString.equals("-") && !disableServiceBusReceiver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
Expand All @@ -39,11 +38,16 @@ public class PaymentTimeoutConsumer extends SBConsumer {
@Value("${disable-service-bus-receiver}")
private boolean disableServiceBusReceiver;

@Autowired private ReceiptService receiptService;
private final ReceiptService receiptService;

@Autowired private ReService reService;
private final ReService reService;

@EventListener(ApplicationReadyEvent.class)
public PaymentTimeoutConsumer(ReceiptService receiptService, ReService reService) {
this.receiptService = receiptService;
this.reService = reService;
}

@EventListener(ApplicationReadyEvent.class)
public void initializeClient() {
if (receiverClient != null && !disableServiceBusReceiver) {
log.info("[Scheduled] Starting PaymentTimeoutConsumer {}", ZonedDateTime.now());
Expand Down
Loading

0 comments on commit e252df8

Please sign in to comment.