Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAGOPA-1903] fix: set handling of forwarder endpoints in paaInviaRT send #41

Merged
merged 2 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: pagopa-wisp-converter
description: A service that permits to handle nodoInviaRPT and nodoInviaCarrelloRPT request from WISP, interfacing them with GPD system
type: application
version: 0.77.0
appVersion: 0.0.36
version: 0.78.0
appVersion: 0.0.36-1-PAGOPA-1903-fix-url-paa-invia-rt
dependencies:
- name: microservice-chart
version: 3.0.0
Expand Down
2 changes: 1 addition & 1 deletion helm/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ microservice-chart:
fullnameOverride: ""
image:
repository: ghcr.io/pagopa/pagopa-wisp-converter
tag: "0.0.36"
tag: "0.0.36-1-PAGOPA-1903-fix-url-paa-invia-rt"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion helm/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ microservice-chart:
fullnameOverride: ""
image:
repository: ghcr.io/pagopa/pagopa-wisp-converter
tag: "0.0.36"
tag: "0.0.36-1-PAGOPA-1903-fix-url-paa-invia-rt"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion helm/values-uat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ microservice-chart:
fullnameOverride: ""
image:
repository: ghcr.io/pagopa/pagopa-wisp-converter
tag: "0.0.36"
tag: "0.0.36-1-PAGOPA-1903-fix-url-paa-invia-rt"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion openapi/openapi.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion openapi/openapi_redirect.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"openapi": "3.0.1",
"info": {
"title": "WISP-Converter-redirect",
"version": "0.0.36"
"version": "0.0.36-1-PAGOPA-1903-fix-url-paa-invia-rt"
},
"servers": [
{
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<groupId>it.gov.pagopa</groupId>
<artifactId>wisp-converter</artifactId>
<version>0.0.36</version>
<version>0.0.36-1-PAGOPA-1903-fix-url-paa-invia-rt</version>
<name>pagoPA WISP Converter</name>
<description>A service that permits to handle nodoInviaRPT and nodoInviaCarrelloRPT request from WISP, converting them in NMU payments.</description>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import lombok.ToString;
import org.springframework.data.annotation.Id;

import java.util.List;

@Container(containerName = "receipt")
@Data
@ToString(exclude = "payload")
Expand All @@ -30,6 +32,8 @@ public class RTRequestEntity {

private String url;

private List<String> headers;

private Integer retry;

private String idempotencyKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import it.gov.pagopa.wispconverter.util.ReUtil;
import jakarta.xml.soap.SOAPMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.data.util.Pair;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
Expand All @@ -21,6 +22,7 @@

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Service
@RequiredArgsConstructor
Expand All @@ -32,23 +34,24 @@ public class PaaInviaRTSenderService {

private final JaxbElementUtil jaxbElementUtil;

public void sendToCreditorInstitution(String url, String payload) {
public void sendToCreditorInstitution(String url, List<Pair<String, String>> headers, String payload) {

try {

// Generating the REST client and send the passed request payload to the passed URL
RestClient client = restClientBuilder.build();
RestClient.RequestBodySpec bodySpec = client.post()
.uri(URI.create(url))
.body(payload);
for (Pair<String, String> header : headers) {
bodySpec.header(header.getFirst(), header.getSecond());
}

// Save an RE event in order to track the communication with creditor institution
generateREForRequestToCreditorInstitution(url, payload);
generateREForRequestToCreditorInstitution(url, headers, payload);

// Communicating with creditor institution sending the paaInviaRT request
ResponseEntity<String> response = client.post()
.uri(URI.create(url))
.header("SOAPAction", "paaInviaRT")
.body(payload)
.retrieve()
.toEntity(String.class);
ResponseEntity<String> response = bodySpec.retrieve().toEntity(String.class);

// check SOAP response and extract body if it is valid
String bodyPayload = response.getBody();
Expand Down Expand Up @@ -112,10 +115,13 @@ private PaaInviaRTRisposta checkResponseValidity(ResponseEntity<String> response
}


private void generateREForRequestToCreditorInstitution(String uri, String body) {
private void generateREForRequestToCreditorInstitution(String uri, List<Pair<String, String>> headers, String body) {

StringBuilder headerBuilder = new StringBuilder();
headers.forEach(header -> headerBuilder.append(", ").append(header.getFirst()).append(": [\"").append(header.getSecond()).append("\"]"));

// setting data in MDC for next use
ReEventDto reEvent = ReUtil.createREForClientInterfaceInRequestEvent("POST", uri, "SOAPAction: paaInviaRT", body, ClientEnum.CREDITOR_INSTITUTION_ENDPOINT, OutcomeEnum.SEND);
ReEventDto reEvent = ReUtil.createREForClientInterfaceInRequestEvent("POST", uri, headerBuilder.toString(), body, ClientEnum.CREDITOR_INSTITUTION_ENDPOINT, OutcomeEnum.SEND);
reService.addRe(reEvent);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
Expand Down Expand Up @@ -75,6 +77,9 @@ public class ReceiptService {
@Value("${wisp-converter.station-in-gpd.partial-path}")
private String stationInGpdPartialPath;

@Value("${wisp-converter.station-in-forwarder.partial-path}")
private String stationInForwarderPartialPath;

@Value("${wisp-converter.rt-send.scheduling-time-in-hours}")
private Integer schedulingTimeInHours;

Expand Down Expand Up @@ -258,6 +263,7 @@ From station identifier (the common one defined, not the payment reference), ret
null,
null
);
List<Pair<String, String>> headers = CommonUtility.constructHeadersForPaaInviaRT(url, station, stationInForwarderPartialPath);

// idempotency key creation to check if the rt has already been sent
String idempotencyKey = sessionData.getCommonFields().getSessionId() + "_" + noticeNumber;
Expand All @@ -277,7 +283,7 @@ From station identifier (the common one defined, not the payment reference), ret
try {

// send the receipt to the creditor institution via the URL set in the station configuration
paaInviaRTSenderService.sendToCreditorInstitution(url, rawPayload);
paaInviaRTSenderService.sendToCreditorInstitution(url, headers, rawPayload);

// generate a new event in RE for store the successful sending of the receipt
generateREForSentRT(sessionData, iuv, noticeNumber);
Expand All @@ -290,7 +296,7 @@ From station identifier (the common one defined, not the payment reference), ret
generateREForNotSentRT(sessionData, iuv, noticeNumber, e.getMessage());

// because of the not sent receipt, it is necessary to schedule a retry of the sending process for this receipt
scheduleRTSend(sessionData, url, rawPayload, station, iuv, noticeNumber, idempotencyKey, receiptType);
scheduleRTSend(sessionData, url, headers, rawPayload, station, iuv, noticeNumber, idempotencyKey, receiptType);

idempotencyStatus = IdempotencyStatusEnum.FAILED;
}
Expand Down Expand Up @@ -415,18 +421,24 @@ private String generatePayloadAsRawString(IntestazionePPT header, String signatu
}


private void scheduleRTSend(SessionDataDTO sessionData, String url, String payload, StationDto station,
private void scheduleRTSend(SessionDataDTO sessionData, String url, List<Pair<String, String>> headers, String payload, StationDto station,
String iuv, String noticeNumber, String idempotencyKey, ReceiptTypeEnum receiptType) {

try {

List<String> formattedHeaders = new LinkedList<>();
for (Pair<String, String> header : headers) {
formattedHeaders.add(header.getFirst() + ":" + header.getSecond());
}

// generate the RT to be persisted in storage, then save in the same storage
RTRequestEntity rtRequestEntity = RTRequestEntity.builder()
.id(station.getBrokerCode() + "_" + UUID.randomUUID())
.primitive(PAA_INVIA_RT)
.partitionKey(LocalDate.ofInstant(Instant.now(), ZoneId.systemDefault()).toString())
.payload(AppBase64Util.base64Encode(ZipUtil.zip(payload)))
.url(url)
.headers(formattedHeaders)
.retry(0)
.idempotencyKey(idempotencyKey)
.receiptType(receiptType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
import it.gov.pagopa.wispconverter.util.*;
import jakarta.xml.soap.SOAPMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Component;

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

@Component
@Slf4j
Expand Down Expand Up @@ -127,7 +128,7 @@ private void resendRTToCreditorInstitution(String receiptId, RTRequestEntity rec
MDCUtil.setSessionDataInfoInMDC(header, idempotencyKeySections[2]);

String rawPayload = new String(unzippedPayload);
paaInviaRTSenderService.sendToCreditorInstitution(receipt.getUrl(), rawPayload);
paaInviaRTSenderService.sendToCreditorInstitution(receipt.getUrl(), extractHeaders(receipt.getHeaders()), rawPayload);
rtCosmosService.deleteRTRequestEntity(receipt);
log.info("Sent receipt [{}]", receiptId);

Expand All @@ -148,6 +149,17 @@ private void resendRTToCreditorInstitution(String receiptId, RTRequestEntity rec
}
}

private List<Pair<String, String>> extractHeaders(List<String> headers) {
List<Pair<String, String>> headerPairs = new LinkedList<>();
for (String rawHeader : headers) {
String[] keys = rawHeader.split(":");
if (keys.length == 2) {
headerPairs.add(Pair.of(keys[0], keys[1]));
}
}
return headerPairs;
}

private void reScheduleReceiptSend(RTRequestEntity receipt, String receiptId, String compositedIdForReceipt) {

// because of the not sent receipt, it is necessary to schedule a retry of the sending process for this receipt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import it.gov.pagopa.wispconverter.service.model.session.SessionDataDTO;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.data.util.Pair;

import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
Expand Down Expand Up @@ -85,6 +88,18 @@ public static String constructUrl(String protocol, String hostname, int port, St
}
}

public static List<Pair<String, String>> constructHeadersForPaaInviaRT(String startingUrl, StationDto station, String stationInForwarderPartialPath) {
List<Pair<String, String>> headers = new LinkedList<>();
headers.add(Pair.of("SOAPAction", "paaInviaRT"));
if (startingUrl.contains(stationInForwarderPartialPath)) {
ServiceDto stationService = station.getService();
headers.add(Pair.of("X-Host-Url", stationService.getTargetHost() == null ? "ND" : stationService.getTargetHost()));
headers.add(Pair.of("X-Host-Port", stationService.getTargetPort() == null ? "ND" : String.valueOf(stationService.getTargetPort())));
headers.add(Pair.of("X-Host-Path", stationService.getTargetPath() == null ? "ND" : stationService.getTargetPath()));
}
return headers;
}

public static String getConfigKeyValueCache(Map<String, it.gov.pagopa.gen.wispconverter.client.cache.model.ConfigurationKeyDto> configurations, String key) {
try {
return configurations.get(key).getValue();
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ wisp-converter.aux-digit=3
wisp-converter.segregation-code=48
wisp-converter.payment-position-valid-status=VALID
wisp-converter.station-in-gpd.partial-path=${STATION_IN_GPD_PARTIAL_PATH:gpd-payments/api/v1}
wisp-converter.station-in-forwarder.partial-path=${STATION_IN_FORWARDER_PARTIAL_PATH:pagopa-node-forwarder/api/v1/forward}
wisp-converter.cached-requestid-mapping.ttl.minutes=${CACHED_REQUESTID_MAPPING_TTL_MINUTES:1440}
wisp-converter.poste-italiane.abi-code=07601
wisp-converter.rt-send.max-retries=${RT_SEND_MAX_RETRIES:48}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertTrue;
Expand All @@ -43,6 +44,7 @@ private RTRequestEntity getStoredReceipt(int retries, String rawtype, String url
.retry(retries)
.receiptType(type)
.url(url)
.headers(List.of("soapaction:paaInviaRT"))
.idempotencyKey("idpa_uuid_nav")
.build();
}
Expand Down Expand Up @@ -204,7 +206,7 @@ void sendToPa_onError_reschedulable(String receiptType) {
when(ccs.getConfigData()).thenReturn(TestUtils.configData("mystation"));

PaaInviaRTSenderService paaInviaRTSenderService = mock(PaaInviaRTSenderService.class);
doThrow(new AppException(AppErrorCodeMessageEnum.PARSING_GENERIC_ERROR)).when(paaInviaRTSenderService).sendToCreditorInstitution(any(), any());
doThrow(new AppException(AppErrorCodeMessageEnum.PARSING_GENERIC_ERROR)).when(paaInviaRTSenderService).sendToCreditorInstitution(any(), any(), any());

ReflectionTestUtils.setField(rtConsumer, "rtCosmosService", rtCosmosService);
ReflectionTestUtils.setField(rtConsumer, "paaInviaRTSenderService", paaInviaRTSenderService);
Expand Down Expand Up @@ -261,7 +263,7 @@ void sendToPa_onError_notReschedulable(String receiptType) {
when(ccs.getConfigData()).thenReturn(TestUtils.configData("mystation"));

PaaInviaRTSenderService paaInviaRTSenderService = mock(PaaInviaRTSenderService.class);
doThrow(new AppException(AppErrorCodeMessageEnum.PARSING_GENERIC_ERROR)).when(paaInviaRTSenderService).sendToCreditorInstitution(any(), any());
doThrow(new AppException(AppErrorCodeMessageEnum.PARSING_GENERIC_ERROR)).when(paaInviaRTSenderService).sendToCreditorInstitution(any(), any(), any());

ReflectionTestUtils.setField(rtConsumer, "rtCosmosService", rtCosmosService);
ReflectionTestUtils.setField(rtConsumer, "paaInviaRTSenderService", paaInviaRTSenderService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void sendOkReceipt_notSent() throws Exception {

// mocking error response from creditor institution
doThrow(new AppException(AppErrorCodeMessageEnum.RECEIPT_GENERATION_ERROR_RESPONSE_FROM_CREDITOR_INSTITUTION, "PAA_ERRORE_RESPONSE", "PAA_ERRORE_RESPONSE", "Errore PA"))
.when(paaInviaRTSenderService).sendToCreditorInstitution(anyString(), anyString());
.when(paaInviaRTSenderService).sendToCreditorInstitution(anyString(), any(), anyString());

mvc.perform(MockMvcRequestBuilders.post("/receipt/ok")
.accept(MediaType.APPLICATION_JSON)
Expand All @@ -226,7 +226,7 @@ void sendOkReceipt_notSent() throws Exception {
assertNotNull(result.getResponse());
});

verify(paaInviaRTSenderService, times(1)).sendToCreditorInstitution(anyString(), anyString());
verify(paaInviaRTSenderService, times(1)).sendToCreditorInstitution(anyString(), any(), anyString());
}

@ParameterizedTest
Expand Down Expand Up @@ -422,7 +422,7 @@ void sendKoReceipt_notSent() throws Exception {
.paymentToken("token01")
.build());
doThrow(new AppException(AppErrorCodeMessageEnum.RECEIPT_GENERATION_ERROR_RESPONSE_FROM_CREDITOR_INSTITUTION, "PAA_ERRORE_RESPONSE", "PAA_ERRORE_RESPONSE", "Errore PA"))
.when(paaInviaRTSenderService).sendToCreditorInstitution(anyString(), anyString());
.when(paaInviaRTSenderService).sendToCreditorInstitution(anyString(), any(), anyString());

mvc.perform(MockMvcRequestBuilders.post("/receipt/ko")
.accept(MediaType.APPLICATION_JSON)
Expand All @@ -435,6 +435,6 @@ void sendKoReceipt_notSent() throws Exception {
assertNotNull(result.getResponse());
});

verify(paaInviaRTSenderService, times(1)).sendToCreditorInstitution(anyString(), anyString());
verify(paaInviaRTSenderService, times(1)).sendToCreditorInstitution(anyString(), any(), anyString());
}
}
Loading
Loading