Skip to content

Commit

Permalink
Merge pull request #13 from pagopa/PAGOPA-627-from-httptrigger-to-GET
Browse files Browse the repository at this point in the history
[PAGOPA-627] get call: refactoring from httpTrigger to spring rest call
  • Loading branch information
jacopocarlini authored Jan 18, 2023
2 parents 0a0f5c7 + b3b508b commit a0586f7
Show file tree
Hide file tree
Showing 14 changed files with 404 additions and 219 deletions.
33 changes: 18 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
ARG JAVA_VERSION=11
#
# Build
#
FROM maven:3.8.4-jdk-11-slim as buildtime
WORKDIR /build
COPY . .
RUN mvn clean package -Dmaven.test.skip=true

FROM mcr.microsoft.com/azure-functions/java:4-java$JAVA_VERSION-build AS installer-env

COPY . /build/java-function-app
RUN cd /build/java-function-app && \
mkdir -p /home/site/wwwroot && \
mvn clean package -Dmaven.test.skip=true && \
cd ./target/azure-functions/ && \
cd $(ls -d */|head -n 1) && \
cp -a . /home/site/wwwroot
FROM adoptopenjdk/openjdk11:alpine-jre as builder
COPY --from=buildtime /build/target/*.jar application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM mcr.microsoft.com/azure-functions/java:4-java$JAVA_VERSION

ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
FROM ghcr.io/pagopa/docker-base-springboot-openjdk11:v1.0.1@sha256:bbbe948e91efa0a3e66d8f308047ec255f64898e7f9250bdb63985efd3a95dbf
COPY --chown=spring:spring --from=builder dependencies/ ./
COPY --chown=spring:spring --from=builder snapshot-dependencies/ ./
# https://github.com/moby/moby/issues/37965#issuecomment-426853382
RUN true
COPY --chown=spring:spring --from=builder spring-boot-loader/ ./
COPY --chown=spring:spring --from=builder application/ ./

COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]

EXPOSE 8080
EXPOSE 8080
69 changes: 62 additions & 7 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
"/cdis/sync": {
"get": {
"tags": [
"Import CDI API"
"Import CDI rest API"
],
"description": "Returns the list of ids of the created bundles",
"operationId": "importCDIFunction",
"summary": "import cdi",
"summary": "API to trigger the import of the CDIs and convert to bundles.",
"operationId": "syncCDI",
"responses": {
"200": {
"description": "OK",
"description": "Obtained bundle list.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
Expand All @@ -42,8 +41,64 @@
}
}
}
},
"401": {
"description": "Unauthorized",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
}
},
"403": {
"description": "Forbidden",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
}
},
"429": {
"description": "Too many requests",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
}
},
"500": {
"description": "Service unavailable.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemJson"
}
}
}
}
}
},
"security": [
{
"ApiKey": []
}
]
},
"parameters": [
{
Expand Down Expand Up @@ -233,4 +288,4 @@
}
}
}
}
}
8 changes: 0 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- needed for java.lang.NoClassDefFoundError: jakarta/servlet/http/HttpServletRequest
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
-->

<!-- Feign Client -->
<dependency>
Expand Down
165 changes: 5 additions & 160 deletions src/main/java/it/gov/pagopa/afm/utils/ImportCDIFunction.java
Original file line number Diff line number Diff line change
@@ -1,189 +1,34 @@
package it.gov.pagopa.afm.utils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import org.apache.commons.lang3.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.azure.cosmos.implementation.apachecommons.lang.StringUtils;

import feign.FeignException;
import it.gov.pagopa.afm.utils.entity.CDI;
import it.gov.pagopa.afm.utils.entity.Detail;
import it.gov.pagopa.afm.utils.entity.ServiceAmount;
import it.gov.pagopa.afm.utils.entity.StatusType;
import it.gov.pagopa.afm.utils.exception.AppError;
import it.gov.pagopa.afm.utils.exception.AppException;
import it.gov.pagopa.afm.utils.model.bundle.BundleRequest;
import it.gov.pagopa.afm.utils.model.bundle.BundleResponse;
import it.gov.pagopa.afm.utils.model.bundle.BundleType;
import it.gov.pagopa.afm.utils.model.bundle.CDIWrapper;
import it.gov.pagopa.afm.utils.model.bundle.PaymentMethodType;
import it.gov.pagopa.afm.utils.model.bundle.TouchpointType;
import it.gov.pagopa.afm.utils.service.CDIService;
import it.gov.pagopa.afm.utils.service.MarketPlaceClient;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Component
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class ImportCDIFunction implements Function<Mono<CDIWrapper>, Mono<List<BundleResponse>>>{

@Autowired(required=false)
private MarketPlaceClient marketPlaceClient;
public class ImportCDIFunction implements Function<Mono<CDIWrapper>, Mono<List<BundleResponse>>> {

@Autowired(required=false)
@Autowired(required = false)
private CDIService cdiService;


@Override
public Mono<List<BundleResponse>> apply(Mono<CDIWrapper> input) {

List<BundleResponse> bundleResponses = new ArrayList<>();

return input.map(wrapper -> {

// the status of the items is put on PROCESSING to identify that these records are not in a final state
// *** @CosmosDBTrigger doesn't need of this step -> remove when change to this kind of function ***
this.setCDIToProcessingStatus(wrapper.getCdiItems());

for (CDI cdi: wrapper.getCdiItems()) {
// processed only cdis not in FAILED status
if (null != cdi.getCdiStatus() && !cdi.getCdiStatus().equals(StatusType.FAILED)) {
String idPsp = cdi.getIdPsp();
List<BundleRequest> bundleRequestList = this.createBundlesByCDI(cdi);
try {
// create marketplace bundle
Optional.ofNullable(this.createBundleByList(idPsp, bundleRequestList)).ifPresent(bundleResponses::addAll);
// success -> delete the CDI
Optional.ofNullable(cdiService).ifPresent(result ->
{
cdiService.deleteCDI(cdi);
log.info(String.format("SUCCESS Bundles creation -> CDI deleted [idCdi=%s]", cdi.getIdCdi()));
});
}
catch (AppException e) {
log.error("Error during the creation of the MarketPlace Bundles [idPsp= "+idPsp+", idCdi="+cdi.getIdCdi()+"]", e);
// error -> set CDI status to failed
cdi.setCdiStatus(StatusType.FAILED);
cdi.setCdiErrorDesc(e.getMessage());
CDI updated = Optional.ofNullable(cdiService).map(result -> cdiService.updateCDI(cdi)).orElseGet(() -> CDI.builder().build());
log.info(String.format("CDI status updated [idCdi=%s, status=%s, errorDesc=%s]", updated.getIdCdi(), updated.getCdiStatus(), updated.getCdiErrorDesc()));
}

}
}
return bundleResponses;
});

}

public List<BundleRequest> createBundlesByCDI(CDI cdi) {
List<BundleRequest> bundleRequestList = new ArrayList<>();
if (!CollectionUtils.isEmpty(cdi.getDetails())) {
DateTimeFormatter dfDate = DateTimeFormatter.ofPattern("yyyy-MM-dd");
BundleRequest bundleRequest = new BundleRequest();
bundleRequest.setIdCdi(cdi.getIdCdi());
bundleRequest.setDigitalStamp(cdi.getDigitalStamp());
bundleRequest.setDigitalStampRestriction(Boolean.FALSE);
bundleRequest.setType(BundleType.GLOBAL);
bundleRequest.setTransferCategoryList(null);
bundleRequest.setValidityDateFrom(!StringUtils.isEmpty(cdi.getValidityDateFrom()) ? LocalDate.parse(cdi.getValidityDateFrom(), dfDate) : null);
bundleRequest.setValidityDateTo(null);
for (Detail d: cdi.getDetails()) {
bundleRequest.setIdChannel(d.getIdChannel());
bundleRequest.setIdBrokerPsp(d.getIdBrokerPsp());
bundleRequest.setName(d.getName());
bundleRequest.setDescription(d.getDescription());
bundleRequest.setPaymentType(d.getPaymentMethod());
for (ServiceAmount sa: d.getServiceAmount()) {
bundleRequest.setPaymentAmount(sa.getPaymentAmount());
bundleRequest.setMinPaymentAmount(sa.getMinPaymentAmount());
bundleRequest.setMaxPaymentAmount(sa.getMaxPaymentAmount());
this.addBundleByTouchpoint(d, bundleRequestList, bundleRequest);
}
}
}
return bundleRequestList;
}
public Mono<List<BundleResponse>> apply(Mono<CDIWrapper> input) {

private void addBundleByTouchpoint(Detail d, List<BundleRequest> bundleRequestList, BundleRequest bundleRequest) {
return input.map(wrapper -> Optional.ofNullable(cdiService).map(result -> cdiService.syncCDI())
.orElse(new ArrayList<>()));

boolean isNullTouchPoint = true;

if (d.getPaymentMethod().equalsIgnoreCase(PaymentMethodType.PO.name())) {
isNullTouchPoint = false;
BundleRequest bundleRequestClone = SerializationUtils.clone(bundleRequest);
bundleRequestClone.setTouchpoint(TouchpointType.PSP.name());
bundleRequestList.add(bundleRequestClone);
}
if ((d.getPaymentMethod().equalsIgnoreCase(PaymentMethodType.CP.name()) && d.getChannelCardsCart() && d.getChannelApp().equals(Boolean.FALSE)) ||
(d.getPaymentMethod().matches("(?i)"+PaymentMethodType.BBT+"|"+PaymentMethodType.BP+"|"+PaymentMethodType.MYBK+"|"+PaymentMethodType.AD) && d.getChannelApp().equals(Boolean.FALSE)) ||
(!d.getPaymentMethod().equalsIgnoreCase(PaymentMethodType.PPAL.name()) && d.getChannelApp())) {
isNullTouchPoint = false;
BundleRequest bundleRequestClone = SerializationUtils.clone(bundleRequest);
bundleRequestClone.setTouchpoint(TouchpointType.WISP.name());
bundleRequestList.add(bundleRequestClone);
}
if ((d.getPaymentMethod().equalsIgnoreCase(PaymentMethodType.CP.name()) && d.getChannelCardsCart() && d.getChannelApp().equals(Boolean.FALSE)) ||
(d.getPaymentMethod().equalsIgnoreCase(PaymentMethodType.PPAL.name()) && d.getChannelApp())) {
isNullTouchPoint = false;
BundleRequest bundleRequestClone = SerializationUtils.clone(bundleRequest);
bundleRequestClone.setTouchpoint(TouchpointType.IO.name());
bundleRequestList.add(bundleRequestClone);
}
if ((d.getPaymentMethod().equalsIgnoreCase(PaymentMethodType.CP.name()) && d.getChannelCardsCart() && d.getChannelApp().equals(Boolean.FALSE))) {
isNullTouchPoint = false;
BundleRequest bundleRequestClone = SerializationUtils.clone(bundleRequest);
bundleRequestClone.setTouchpoint(TouchpointType.CHECKOUT.name());
bundleRequestList.add(bundleRequestClone);
}
if (isNullTouchPoint) {
// default bundle with null touchpoint value
bundleRequestList.add(bundleRequest);
}

}


private List<BundleResponse> createBundleByList(String idPsp, List<BundleRequest> bundleRequestList) throws AppException{
List<BundleResponse> response = null;
try {
response = Optional.ofNullable(marketPlaceClient).map(result -> marketPlaceClient.createBundleByList(idPsp, bundleRequestList)).orElseGet(() -> null);
} catch (FeignException.BadRequest e) {
throw new AppException(AppError.BUNDLE_REQUEST_DATA_ERROR, e.getMessage());
} catch (FeignException.NotFound e) {
throw new AppException(AppError.BUNDLE_NOT_FOUND_ERROR, e.getMessage());
} catch (FeignException.Conflict e) {
throw new AppException(AppError.BUNDLE_CONFLICT_ERROR, e.getMessage());
} catch (FeignException.InternalServerError e) {
throw new AppException(AppError.INTERNAL_SERVER_ERROR, e.getMessage());
} catch (Exception e) {
throw new AppException(AppError.UNKNOWN, e.getMessage());
}
return response;
}

// remove when @CosmosDBTrigger function will be used
public void setCDIToProcessingStatus(List<CDI> items) {
for (CDI cdi: items) {
cdi.setCdiStatus(StatusType.PROCESSING);
CDI updated = Optional.ofNullable(cdiService).map(result -> cdiService.updateCDI(cdi)).orElseGet(() -> CDI.builder().build());
log.info(String.format("CDI status updated [idCdi=%s, status=%s]", updated.getIdCdi(), updated.getCdiStatus()));
}
}



}
5 changes: 2 additions & 3 deletions src/main/java/it/gov/pagopa/afm/utils/config/FeignConfig.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package it.gov.pagopa.afm.utils.config;

import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

@Slf4j
import feign.RequestInterceptor;

public class FeignConfig {

static final String HEADER_REQUEST_ID = "X-Request-Id";
Expand Down
Loading

0 comments on commit a0586f7

Please sign in to comment.