diff --git a/.github/workflows/pr_ms.yml b/.github/workflows/pr_ms.yml index 66d85b5d..7213e212 100644 --- a/.github/workflows/pr_ms.yml +++ b/.github/workflows/pr_ms.yml @@ -3,21 +3,15 @@ on: workflow_dispatch: pull_request: + branches: + - main + - releases/** types: + - opened + - edited - synchronize - reopened - ready_for_review - paths: - - '.github/workflows/pr_ms.yml' - - '.github/workflows/release_ms.yml' - - '.github/workflows/release_ms_pnpg.yml' - - '!.devops/**' - - '!helm/**' - - '!**.md' - - '!**ignore' - - '!infra/**' - - '!.terraform-version' - - '!CODEOWNERS' jobs: diff --git a/.github/workflows/release_ms.yml b/.github/workflows/release_ms.yml index a960e037..991953e4 100644 --- a/.github/workflows/release_ms.yml +++ b/.github/workflows/release_ms.yml @@ -1,6 +1,19 @@ name: Release ms-external-interceptor on: + push: + branches: + - main + - releases/* + paths: + - 'app/**' + - 'connector/**' + - 'connector-api/**' + - 'core/**' + - 'infra/**' + - 'web/**' + - 'pom.xml' + workflow_dispatch: inputs: env: @@ -11,19 +24,6 @@ on: - uat - prod - push: - branches: - - main - - releases/* - paths: - - '!.devops/**' - - '!helm/**' - - '!**.md' - - '!**ignore' - - '!infra/repository/**' - - '!.terraform-version' - - '!CODEOWNERS' - jobs: release_dev: diff --git a/Dockerfile.new b/Dockerfile.new index 9dfa915d..8afa1c38 100644 --- a/Dockerfile.new +++ b/Dockerfile.new @@ -1,10 +1,10 @@ -FROM maven:3-eclipse-temurin-17 AS builder +FROM maven:3-eclipse-temurin-17@sha256:0d328fa6843bb26b60cf44d69833f241ffe96218fb29fa19df7a6603863eaae7 AS builder COPY . . RUN mvn clean package -DskipTests=true -FROM openjdk:17-jdk AS runtime +FROM openjdk:17-jdk@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 AS runtime ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' diff --git a/app/src/test/java/it/pagopa/selfcare/external_interceptor/web/config/SwaggerConfigTest.java b/app/src/test/java/it/pagopa/selfcare/external_interceptor/web/config/SwaggerConfigTest.java index f7a22cd3..dfd353af 100644 --- a/app/src/test/java/it/pagopa/selfcare/external_interceptor/web/config/SwaggerConfigTest.java +++ b/app/src/test/java/it/pagopa/selfcare/external_interceptor/web/config/SwaggerConfigTest.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import it.pagopa.selfcare.external_interceptor.core.InterceptorService; - import it.pagopa.selfcare.external_interceptor.core.SchedulerService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -42,9 +41,6 @@ class SwaggerConfigTest { @MockBean private InterceptorService interceptorService; - @MockBean - private SchedulerService schedulerService; - @Autowired WebApplicationContext context; diff --git a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/Billing.java b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/Billing.java index 73ca865a..3f7efcad 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/Billing.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/Billing.java @@ -6,6 +6,6 @@ public class Billing { private String vatNumber; private String recipientCode; + private String taxCodeInvoicing; private boolean publicService; - } diff --git a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/BillingToSend.java b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/BillingToSend.java new file mode 100644 index 00000000..f9b3af56 --- /dev/null +++ b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/BillingToSend.java @@ -0,0 +1,10 @@ +package it.pagopa.selfcare.external_interceptor.connector.model.institution; + +import lombok.Data; + +@Data +public class BillingToSend { + private String vatNumber; + private String recipientCode; + private boolean publicService; +} diff --git a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/NotificationToSend.java b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/NotificationToSend.java index 10b7b097..32d0446e 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/NotificationToSend.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/institution/NotificationToSend.java @@ -21,7 +21,7 @@ public class NotificationToSend { private InstitutionToSend institution; private String fileName; private String contentType; - private Billing billing; + private BillingToSend billing; private UserToSend user; } diff --git a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/mapper/NotificationMapper.java b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/mapper/NotificationMapper.java index 5f8138d8..0d3cbd2f 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/mapper/NotificationMapper.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/mapper/NotificationMapper.java @@ -17,12 +17,14 @@ import java.util.UUID; -@Mapper(componentModel = "spring", imports = {UUID.class, RelationshipState.class}) +@Mapper(componentModel = "spring", imports = {UUID.class, RelationshipState.class }) public interface NotificationMapper { @Mapping(target = "id", expression = "java(UUID.randomUUID().toString())") @Mapping(target = "user", source = "inbound.user", qualifiedByName = "toUserToSend") @Mapping(target = "product", source = "productId") + @Mapping(target = "createdAt", expression = "java(inbound.getCreatedAt().atOffset(java.time.ZoneOffset.UTC))") + @Mapping(target = "updatedAt", expression = "java(inbound.getUpdatedAt().atOffset(java.time.ZoneOffset.UTC))") NotificationToSend createUserNotification(UserNotification inbound); @@ -34,6 +36,7 @@ public interface NotificationMapper { NotificationToSend createInstitutionNotification(Notification inbound); + @Named("toUserToSend") @Mapping(target = "roles", expression = "java(toUserRole(user.getProductRole()))") UserToSend toUserToSend(UserNotify user); diff --git a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserNotification.java b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserNotification.java index f296d0fd..c2151fe5 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserNotification.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserNotification.java @@ -3,7 +3,7 @@ import it.pagopa.selfcare.external_interceptor.connector.model.interceptor.QueueEvent; import lombok.Data; -import java.time.OffsetDateTime; +import java.time.LocalDateTime; @Data public class UserNotification { @@ -11,8 +11,8 @@ public class UserNotification { private String institutionId; private String productId; private String onboardingTokenId; - private OffsetDateTime createdAt; - private OffsetDateTime updatedAt; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; private QueueEvent eventType; private UserNotify user; } diff --git a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserProductDetails.java b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserProductDetails.java index 0a19d52c..d5b69cde 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserProductDetails.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/external_interceptor/connector/model/user/UserProductDetails.java @@ -6,5 +6,5 @@ public class UserProductDetails { private String id; private String institutionId; - private OnboardedUserProduct onboardedUserProductDetails; + private OnboardedUserProduct onboardedProductDetails; } diff --git a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptor.java b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptor.java index af266ba4..3e6b5eff 100644 --- a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptor.java +++ b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptor.java @@ -6,13 +6,10 @@ import it.pagopa.selfcare.commons.base.logging.LogUtils; import it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.KafkaSendService; import it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.KafkaSendStrategyFactory; -import it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.SendSapNotification; import it.pagopa.selfcare.external_interceptor.connector.model.constant.ProductId; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Notification; import it.pagopa.selfcare.external_interceptor.connector.model.user.UserNotification; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.support.Acknowledgment; import org.springframework.stereotype.Service; @@ -24,42 +21,11 @@ public class KafkaInterceptor { public static final String NOTIFICATION_CONVERSION_EXCEPTION = "Something went wrong while trying to convert the record"; private final ObjectMapper mapper; private final KafkaSendStrategyFactory sendStrategyFactory; - private final SendSapNotification sapSendService; - public KafkaInterceptor(ObjectMapper mapper, KafkaSendStrategyFactory sendStrategyFactory, @Qualifier("sapNotificator") SendSapNotification sapSendService) { + public KafkaInterceptor(ObjectMapper mapper, KafkaSendStrategyFactory sendStrategyFactory) { this.mapper = mapper; this.mapper.registerModule(new JavaTimeModule()); this.sendStrategyFactory = sendStrategyFactory; - this.sapSendService = sapSendService; - } - - @KafkaListener(topics = "${kafka-manager.external-interceptor.sc-contracts-read-topic}", containerFactory = "kafkaContractsListenerContainerFactoryGeneral") - public void interceptInstitutionGeneral(ConsumerRecord inboundRecord, Acknowledgment acknowledgment) { - log.trace("KafkaInterceptor GENERAL intercept start"); - log.debug(LogUtils.CONFIDENTIAL_MARKER, "KafKaInterceptor GENERAL incoming message = {}", inboundRecord); - try { - Notification notification = mapper.readValue(inboundRecord.value(), Notification.class); - KafkaSendService sendService = sendStrategyFactory.create(notification.getProduct()); - if(sendService!= null) - sendService.sendInstitutionNotification(notification, acknowledgment); - } catch (JsonProcessingException e) { - log.warn(NOTIFICATION_CONVERSION_EXCEPTION, e); - } - - log.trace("KafkaInterceptor GENERAL intercept end"); - } - - @KafkaListener(topics = "${kafka-manager.external-interceptor.sc-contracts-read-topic}", containerFactory = "kafkaContractsListenerContainerFactorySap") - public void interceptInstitutionSap(ConsumerRecord inboundRecord, Acknowledgment acknowledgment) { - log.trace("KafkaInterceptor SAP intercept start"); - log.debug(LogUtils.CONFIDENTIAL_MARKER, "KafKaInterceptor SAP incoming message = {}", inboundRecord); - try { - Notification notification = mapper.readValue(inboundRecord.value(), Notification.class); - sapSendService.sendInstitutionNotification(notification, acknowledgment); - } catch (JsonProcessingException e) { - log.warn(NOTIFICATION_CONVERSION_EXCEPTION, e); - } - log.trace("KafkaInterceptor SAP intercept end"); } @KafkaListener(topics = "${kafka-manager.external-interceptor.sc-users-read-topic}", containerFactory = "kafkaUserListenerContainerFactory") diff --git a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/KafkaSendService.java b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/KafkaSendService.java index 5160fd68..ff370b0c 100644 --- a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/KafkaSendService.java +++ b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/KafkaSendService.java @@ -6,7 +6,5 @@ import org.springframework.kafka.support.Acknowledgment; public interface KafkaSendService { - - void sendInstitutionNotification(Notification notification, Acknowledgment acknowledgment) throws JsonProcessingException; void sendUserNotification(UserNotification userNotification, Acknowledgment acknowledgment) throws JsonProcessingException; } diff --git a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotification.java b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotification.java index 2fb3dbdf..e4819d3f 100644 --- a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotification.java +++ b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotification.java @@ -44,22 +44,6 @@ public SendFdNotification(@Value("#{${external-interceptor.producer-topics}}") M } - @Override - public void sendInstitutionNotification(Notification notification, Acknowledgment acknowledgment) throws JsonProcessingException { - log.trace("sendInstitutionNotification start"); - log.debug(LogUtils.CONFIDENTIAL_MARKER, "send institution notification = {}", notification); - if (validateProductTopic(notification.getProduct())) { - NotificationToSend notificationToSend = notificationMapper.createInstitutionNotification(notification); - notificationToSend.setType(NotificationType.ADD_INSTITUTE); - String institutionNotification = mapper.writeValueAsString(notificationToSend); - String topic = producerAllowedTopics.get().get(notification.getProduct()); - String logSuccess = String.format("sent notification for token : %s, to FD", notification.getOnboardingTokenId()); - String logFailure = String.format("error during notification sending for token: %s, on FD ", notification.getOnboardingTokenId()); - sendNotification(institutionNotification, topic, logSuccess, logFailure, Optional.of(acknowledgment)); - } - log.trace("sendInstitutionNotification end"); - } - @Override public void sendUserNotification(UserNotification userNotification, Acknowledgment acknowledgment) throws JsonProcessingException { log.trace("sendUserNotification start"); @@ -70,7 +54,7 @@ public void sendUserNotification(UserNotification userNotification, Acknowledgme && (userNotification.getProductId().equals(PROD_FD.getValue()) || userNotification.getProductId().equals(PROD_FD_GARANTITO.getValue()))) { UserProductDetails userProduct = externalApiConnector.getUserOnboardedProductDetails(userNotification.getUser().getUserId(), userNotification.getInstitutionId(), userNotification.getProductId()); - if(userProduct.getOnboardedUserProductDetails() != null) { + if(userProduct.getOnboardedProductDetails() != null) { sendUpdateUserEvents(notificationToSend, userProduct); acknowledgment.acknowledge(); } @@ -92,9 +76,9 @@ private void sendUpdateUserEvents(NotificationToSend notification, UserProductDe List eventTypes = List.of(NotificationType.DELETE_USER, NotificationType.ACTIVE_USER); UserToSend userToSend = new UserToSend(); userToSend.setUserId(userProductDetails.getId()); - userToSend.setRole(userProductDetails.getOnboardedUserProductDetails().getRole()); - userToSend.setRoles(userProductDetails.getOnboardedUserProductDetails().getRoles()); - notification.setCreatedAt(userProductDetails.getOnboardedUserProductDetails().getCreatedAt()); + userToSend.setRole(userProductDetails.getOnboardedProductDetails().getRole()); + userToSend.setRoles(userProductDetails.getOnboardedProductDetails().getRoles()); + notification.setCreatedAt(userProductDetails.getOnboardedProductDetails().getCreatedAt()); eventTypes.forEach(type -> { notification.setType(type); notification.setUser(userToSend); diff --git a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendSapNotification.java b/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendSapNotification.java deleted file mode 100644 index 0ac95fcd..00000000 --- a/connector/kafka-manager/src/main/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendSapNotification.java +++ /dev/null @@ -1,149 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import it.pagopa.selfcare.commons.base.logging.LogUtils; -import it.pagopa.selfcare.commons.base.utils.InstitutionType; -import it.pagopa.selfcare.commons.base.utils.Origin; -import it.pagopa.selfcare.commons.base.utils.PricingPlan; -import it.pagopa.selfcare.commons.base.utils.ProductId; -import it.pagopa.selfcare.external_interceptor.connector.api.ExternalApiConnector; -import it.pagopa.selfcare.external_interceptor.connector.api.KafkaSapSendService; -import it.pagopa.selfcare.external_interceptor.connector.api.RegistryProxyConnector; -import it.pagopa.selfcare.external_interceptor.connector.exceptions.ResourceNotFoundException; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Notification; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.NotificationToSend; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.NotificationType; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapper; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.GeographicTaxonomies; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.HomogeneousOrganizationalArea; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.InstitutionProxyInfo; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.OrganizationUnit; -import it.pagopa.selfcare.external_interceptor.connector.model.user.UserNotification; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.support.Acknowledgment; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - -@Slf4j -@Service -@Qualifier("sapNotificator") -public class SendSapNotification extends KafkaSend implements KafkaSapSendService { - static final String DESCRIPTION_TO_REPLACE_REGEX = " - COMUNE"; - public static final String SC_CONTRACTS_SAP = "Sc-Contracts-Sap"; - private final Optional> allowedInstitutionTypes; - private final Optional> allowedProducts; - private final Optional> allowedOrigins; - - public SendSapNotification(@Autowired - @Qualifier("sapProducer") - KafkaTemplate kafkaTemplate, - NotificationMapper notificationMapper, - ObjectMapper mapper, - RegistryProxyConnector registryProxyConnector, - ExternalApiConnector externalApiConnector, - @Value("${external-interceptor.sap.allowed-institution-types}") Set allowedInstitutionTypes, - @Value("#{'${external-interceptor.scheduler.products-to-resend}'.split(',')}") List allowedProducts, - @Value("${external-interceptor.sap.allowed-origins}") Set allowedOrigins) { - super(kafkaTemplate, notificationMapper, mapper, registryProxyConnector, externalApiConnector); - this.allowedInstitutionTypes = Optional.ofNullable(allowedInstitutionTypes); - this.allowedProducts = Optional.ofNullable(allowedProducts); - this.allowedOrigins = Optional.ofNullable(allowedOrigins); - } - - @Override - public void sendInstitutionNotification(Notification notification, Acknowledgment acknowledgment) throws JsonProcessingException { - log.trace("sendInstitutionNotification start"); - if (checkAllowedNotification(notification)) { - log.debug(LogUtils.CONFIDENTIAL_MARKER, "send institution notification = {}", notification); - NotificationToSend notificationToSend = notificationMapper.createInstitutionNotification(notification); - setNotificationInstitutionLocationFields(notificationToSend); - setNotificationToSendInstitutionDescription(notificationToSend); - notificationToSend.setType(NotificationType.ADD_INSTITUTE); - String institutionNotification = mapper.writeValueAsString(notificationToSend); - String logSuccess = String.format("sent notification for token : %s, to SAP", notification.getOnboardingTokenId()); - String logFailure = String.format("error during notification sending for token %s: {}, on SAP ", notification.getOnboardingTokenId()); - sendNotification(institutionNotification, SC_CONTRACTS_SAP, logSuccess, logFailure, Optional.ofNullable(acknowledgment)); - log.trace("sendInstitutionNotification end"); - } - } - - private static void setNotificationToSendInstitutionDescription(NotificationToSend notificationToSend) { - if(notificationToSend.getInstitution().getRootParent() != null) { - notificationToSend.getInstitution().setDescription( - notificationToSend.getInstitution().getRootParent().getDescription() - + " - " + notificationToSend.getInstitution().getDescription()); - } - } - - private boolean checkAllowedNotification(Notification notification){ - return isProductAllowed(notification, allowedProducts) - && isInstitutionTypeAllowed(notification, allowedInstitutionTypes) - && isOriginAllowed(notification, allowedOrigins); - } - private boolean isProductAllowed(Notification notification, Optional> allowedProducts) { - return (allowedProducts.isPresent() && allowedProducts.get().contains(notification.getProduct())) || isProdIoFast(notification.getProduct(), notification.getPricingPlan()); - } - - private boolean isProdIoFast(String productId, String pricingPlan){ - return ProductId.PROD_IO.getValue().equals(productId) && PricingPlan.FA.name().equals(pricingPlan); - } - - private boolean isInstitutionTypeAllowed(Notification notification, Optional> allowedTypes) { - return allowedTypes.isPresent() && allowedTypes.get().contains(notification.getInstitution().getInstitutionType()); - } - - private boolean isOriginAllowed(Notification notification, Optional> allowedOrigins) { - return allowedOrigins.isPresent() && allowedOrigins.get().contains(Origin.fromValue(notification.getInstitution().getOrigin())); - } - - private void setNotificationInstitutionLocationFields(NotificationToSend notificationToSend) { - try { - GeographicTaxonomies geographicTaxonomies = null; - if (notificationToSend.getInstitution().getSubUnitType() != null && notificationToSend.getInstitution().getCity() == null) { - switch (Objects.requireNonNull(notificationToSend.getInstitution().getSubUnitType())) { - case "UO": - OrganizationUnit organizationUnit = registryProxyConnector.getUoById(notificationToSend.getInstitution().getSubUnitCode()); - notificationToSend.getInstitution().setIstatCode(organizationUnit.getMunicipalIstatCode()); - geographicTaxonomies = registryProxyConnector.getExtById(organizationUnit.getMunicipalIstatCode()); - break; - case "AOO": - HomogeneousOrganizationalArea homogeneousOrganizationalArea = registryProxyConnector.getAooById(notificationToSend.getInstitution().getSubUnitCode()); - notificationToSend.getInstitution().setIstatCode(homogeneousOrganizationalArea.getMunicipalIstatCode()); - geographicTaxonomies = registryProxyConnector.getExtById(homogeneousOrganizationalArea.getMunicipalIstatCode()); - break; - default: - InstitutionProxyInfo proxyInfo = registryProxyConnector.getInstitutionProxyById(notificationToSend.getInstitution().getTaxCode()); - geographicTaxonomies = registryProxyConnector.getExtById(proxyInfo.getIstatCode()); - notificationToSend.getInstitution().setIstatCode(proxyInfo.getIstatCode()); - } - } - if (geographicTaxonomies != null) { - notificationToSend.getInstitution().setCounty(geographicTaxonomies.getProvinceAbbreviation()); - notificationToSend.getInstitution().setCountry(geographicTaxonomies.getCountryAbbreviation()); - notificationToSend.getInstitution().setCity(geographicTaxonomies.getDescription().replace(DESCRIPTION_TO_REPLACE_REGEX, "")); - } - } catch (ResourceNotFoundException e) { - log.warn("Error while searching institution {} on IPA, {} ", notificationToSend.getInstitution().getDescription(), e.getMessage()); - notificationToSend.getInstitution().setIstatCode(null); - } - } - - @Override - public void sendUserNotification(UserNotification userNotification, Acknowledgment acknowledgment) throws JsonProcessingException { - - } - - @Override - public void sendOldEvents(Notification notification) throws JsonProcessingException { - sendInstitutionNotification(notification, null); - } -} diff --git a/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptorTest.java b/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptorTest.java index 43ea8cb7..1673f157 100644 --- a/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptorTest.java +++ b/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/KafkaInterceptorTest.java @@ -11,9 +11,6 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.KafkaSendStrategyFactory; import it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.SendFdNotification; -import it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.SendSapNotification; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Billing; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Institution; import it.pagopa.selfcare.external_interceptor.connector.model.institution.Notification; import it.pagopa.selfcare.external_interceptor.connector.model.user.RelationshipState; import it.pagopa.selfcare.external_interceptor.connector.model.user.UserNotification; @@ -62,8 +59,6 @@ public ObjectMapper objectMapper() { private KafkaInterceptor interceptor; private KafkaSendStrategyFactory sendStrategyFactory; - private SendSapNotification sapSendService; - private SendFdNotification fdNotificationService; @Spy @@ -77,9 +72,8 @@ public ObjectMapper objectMapper() { void setUp() { openMocks(this); fdNotificationService = mock(SendFdNotification.class); - sapSendService = mock(SendSapNotification.class); sendStrategyFactory = mock(KafkaSendStrategyFactory.class); - interceptor = new KafkaInterceptor(mapper, sendStrategyFactory, sapSendService); + interceptor = new KafkaInterceptor(mapper, sendStrategyFactory); } public KafkaInterceptorTest(){ objectMapper = new ObjectMapper(); @@ -94,89 +88,6 @@ public KafkaInterceptorTest(){ objectMapper.setTimeZone(TimeZone.getDefault()); } - - @Test - void interceptInstitutionGeneral() throws JsonProcessingException { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - Acknowledgment acknowledgment = new Acknowledgment() { - @Override - public void acknowledge() { - - } - }; - when(sendStrategyFactory.create(any())).thenReturn(fdNotificationService); - //when - assertDoesNotThrow( - () -> interceptor.interceptInstitutionGeneral(new ConsumerRecord<>("sc-Contracts", 0, 0, "notification", objectMapper.writeValueAsString(notification)), acknowledgment) - ); - //then - verify(sendStrategyFactory, times(1)).create("prod-fd"); - ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); - verify(fdNotificationService, times(1)).sendInstitutionNotification(notificationArgumentCaptor.capture(), eq(acknowledgment)); - Notification capturedNotification = notificationArgumentCaptor.getValue(); - reflectionEqualsByName(notification, capturedNotification); - } - - @Test - void interceptInstitutionGeneralDifferentProduct() throws JsonProcessingException { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-io"); - notification.setState("ACTIVE"); - Acknowledgment acknowledgment = new Acknowledgment() { - @Override - public void acknowledge() { - - } - }; - when(sendStrategyFactory.create(any())).thenReturn(null); - //when - assertDoesNotThrow( - () -> interceptor.interceptInstitutionGeneral(new ConsumerRecord<>("sc-Contracts", 0, 0, "notification", objectMapper.writeValueAsString(notification)), acknowledgment) - ); - //then - verify(sendStrategyFactory, times(1)).create("prod-io"); - verifyNoInteractions(fdNotificationService); - } - - @Test - void interceptInstitutionGeneral_exception() throws IOException { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - String notificationString = objectMapper.writeValueAsString(notification); - String newPayload = notificationString.replace("PA", "TEST"); - Acknowledgment acknowledgment = new Acknowledgment() { - @Override - public void acknowledge() { - - } - }; - when(sendStrategyFactory.create(any())).thenReturn(fdNotificationService); - //when - assertDoesNotThrow( - () -> interceptor.interceptInstitutionGeneral(new ConsumerRecord<>("sc-Contracts", 0, 0, "notification", newPayload), acknowledgment) - ); - //then - verifyNoInteractions( fdNotificationService, sendStrategyFactory); - } - @Test void interceptUserNotification() throws JsonProcessingException { //given @@ -270,58 +181,5 @@ public void acknowledge() { verifyNoInteractions(fdNotificationService); } - @Test - void interceptInstitutionSap() throws JsonProcessingException { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - Acknowledgment acknowledgment = new Acknowledgment() { - @Override - public void acknowledge() { - - } - }; - //when - assertDoesNotThrow( - () -> interceptor.interceptInstitutionSap(new ConsumerRecord<>("sc-Contracts", 0, 0, "notification", objectMapper.writeValueAsString(notification)), acknowledgment) - ); - //then - ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); - verify(sapSendService, times(1)).sendInstitutionNotification(notificationArgumentCaptor.capture(), eq(acknowledgment)); - Notification capturedNotification = notificationArgumentCaptor.getValue(); - reflectionEqualsByName(notification, capturedNotification); - } - - @Test - void interceptInstitutionSap_exception() throws IOException { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - String notificationString = objectMapper.writeValueAsString(notification); - String newPayload = notificationString.replace("PA", "TEST"); - Acknowledgment acknowledgment = new Acknowledgment() { - @Override - public void acknowledge() { - - } - }; - //when - assertDoesNotThrow( - () -> interceptor.interceptInstitutionSap(new ConsumerRecord<>("sc-Contracts", 0, 0, "notification", newPayload), acknowledgment) - ); - //then - verifyNoInteractions( fdNotificationService, sendStrategyFactory); - } - } diff --git a/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotificationTest.java b/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotificationTest.java deleted file mode 100644 index 041b6a69..00000000 --- a/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendFdNotificationTest.java +++ /dev/null @@ -1,354 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory; - -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import it.pagopa.selfcare.external_interceptor.connector.api.ExternalApiConnector; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Billing; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Institution; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Notification; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.NotificationToSend; -import it.pagopa.selfcare.external_interceptor.connector.model.interceptor.QueueEvent; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapper; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapperImpl; -import it.pagopa.selfcare.external_interceptor.connector.model.user.*; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.function.Executable; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.support.Acknowledgment; -import org.springframework.kafka.support.SendResult; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import java.util.HashMap; -import java.util.Map; -import java.util.TimeZone; - -import static it.pagopa.selfcare.commons.utils.TestUtils.checkNotNullFields; -import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; -import static org.mockito.MockitoAnnotations.openMocks; - -@ContextConfiguration(classes = {SendFdNotificationTest.Config.class, SendFdNotification.class, KafkaSend.class, NotificationMapperImpl.class}) -@ExtendWith(MockitoExtension.class) -class SendFdNotificationTest { - - public static class Config { - @Bean - @Primary - public ObjectMapper objectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(new Jdk8Module()); - mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - mapper.setTimeZone(TimeZone.getDefault()); - return mapper; - } - } - - private Map allowedTopics; - private KafkaTemplate kafkaTemplate; - @Mock - private ListenableFutureCallback> mockProducerCallback; - private ListenableFuture mockFuture; - private SendResult mockSendResult; - private Acknowledgment acknowledgment; - private ExternalApiConnector externalApiConnector; - - private SendFdNotification service; - - @Mock - private KafkaSend abstractService; - @Spy - private NotificationMapper notificationMapperSpy = new NotificationMapperImpl(); - @Spy - private ObjectMapper mapper = new ObjectMapper(); - - @Autowired - private ObjectMapper objectMapper; - - AutoCloseable closeable; - - @BeforeEach - void setUp() { - closeable = openMocks(this); - allowedTopics = new HashMap<>(); - allowedTopics.put("prod-fd", "selfcare-fd"); - kafkaTemplate = mock(KafkaTemplate.class); - mockFuture = mock(ListenableFuture.class); - acknowledgment = mock(Acknowledgment.class); - mockSendResult = mock(SendResult.class); - externalApiConnector = mock(ExternalApiConnector.class); - service = new SendFdNotification(allowedTopics, kafkaTemplate, notificationMapperSpy, mapper, externalApiConnector); - } - - @AfterEach - void close() throws Exception { - closeable.close(); - } - - @Test - void sendInstitutionNotification() throws JsonProcessingException { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - verify(acknowledgment, times(1)).acknowledge(); - checkNotNullFields(captured, "user"); - checkNotNullFields(captured.getInstitution()); - } - - @Test - void sendUserNotification_ok() throws JsonProcessingException { - //given - final UserNotification notification = mockInstance(new UserNotification()); - final UserNotify userNotify = mockInstance(new UserNotify()); - userNotify.setRelationshipStatus(RelationshipState.ACTIVE); - notification.setUser(userNotify); - notification.setProductId("prod-fd"); - - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - //when - Executable executable = () -> service.sendUserNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - verify(acknowledgment, times(1)).acknowledge(); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "institution", "billing", "state", "closedAt", "fileName", "contentType", "pricingPlan"); - } - - @Test - void failed_send() { - //given - final Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - final Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - RuntimeException ex = new RuntimeException("error"); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onFailure(ex); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); //when - assertDoesNotThrow( - () -> service.sendInstitutionNotification(notification, acknowledgment) - ); - //then - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - assertEquals("selfcare-fd", producerRecordArgumentCaptor.getValue().topic()); - verify(acknowledgment, times(1)).nack(60000); - } - - @Test - void productNotAllowed() { - //given - Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-io"); - notification.setState("ACTIVE"); - //when - assertDoesNotThrow( - () -> service.sendInstitutionNotification(notification, acknowledgment) - ); - //then - verifyNoInteractions(kafkaTemplate); - } - - @Test - void productMap_isEmpty() { - //given - Notification notification = mockInstance(new Notification()); - Institution institution = mockInstance(new Institution()); - Billing billing = mockInstance(new Billing()); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-fd"); - notification.setState("ACTIVE"); - allowedTopics = null; - service = new SendFdNotification(allowedTopics, kafkaTemplate, notificationMapperSpy, mapper, externalApiConnector); - //when - assertDoesNotThrow( - () -> service.sendInstitutionNotification(notification, acknowledgment) - ); - //then - verifyNoInteractions(kafkaTemplate); - } - - @Test - void productNotAllowed_users() { - //given - final UserNotification notification = mockInstance(new UserNotification()); - final UserNotify userNotify = mockInstance(new UserNotify()); - userNotify.setRelationshipStatus(RelationshipState.ACTIVE); - notification.setUser(userNotify); - notification.setProductId("prod-io"); - //when - assertDoesNotThrow( - () -> service.sendUserNotification(notification, acknowledgment) - ); - //then - verifyNoInteractions(kafkaTemplate); - } - - @Test - void productMap_isEmpty_users() { - //given - final UserNotification notification = mockInstance(new UserNotification()); - final UserNotify userNotify = mockInstance(new UserNotify()); - userNotify.setRelationshipStatus(RelationshipState.ACTIVE); - notification.setUser(userNotify); - notification.setProductId("prod-fd"); - allowedTopics = null; - service = new SendFdNotification(allowedTopics, kafkaTemplate, notificationMapperSpy, mapper, externalApiConnector); - //when - assertDoesNotThrow( - () -> service.sendUserNotification(notification, acknowledgment) - ); - //then - verifyNoInteractions(kafkaTemplate); - } - - @Test - void updateUserEvents() throws JsonProcessingException { - //given - final UserNotification notification = mockInstance(new UserNotification()); - notification.setEventType(QueueEvent.UPDATE); - final UserNotify userNotify = mockInstance(new UserNotify()); - userNotify.setRelationshipStatus(null); - notification.setUser(userNotify); - notification.setProductId("prod-fd"); - UserProductDetails userProductDetails = mockInstance(new UserProductDetails()); - OnboardedUserProduct onboardedUserProduct = mockInstance(new OnboardedUserProduct()); - userProductDetails.setOnboardedUserProductDetails(onboardedUserProduct); - - when(externalApiConnector.getUserOnboardedProductDetails(anyString(), anyString(), anyString())).thenReturn(userProductDetails); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - //when - Executable executable = () -> service.sendUserNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verify(externalApiConnector, times(1)).getUserOnboardedProductDetails(userNotify.getUserId(), notification.getInstitutionId(), notification.getProductId()); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(2)).send(producerRecordArgumentCaptor.capture()); - verify(acknowledgment, times(1)).acknowledge(); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "institution", "billing", "state", "closedAt", "fileName", "contentType", "pricingPlan"); - } - - @Test - void updateUserEvent_JsonException() throws JsonProcessingException { - //given - final UserNotification notification = mockInstance(new UserNotification()); - notification.setEventType(QueueEvent.UPDATE); - final UserNotify userNotify = mockInstance(new UserNotify()); - userNotify.setRelationshipStatus(null); - notification.setUser(userNotify); - notification.setProductId("prod-fd"); - UserProductDetails userProductDetails = mockInstance(new UserProductDetails()); - OnboardedUserProduct onboardedUserProduct = mockInstance(new OnboardedUserProduct()); - userProductDetails.setOnboardedUserProductDetails(onboardedUserProduct); - - when(externalApiConnector.getUserOnboardedProductDetails(anyString(), anyString(), anyString())).thenReturn(userProductDetails); - - when(mapper.writeValueAsString(any())).thenThrow(JsonProcessingException.class); - //when - Executable executable = () -> service.sendUserNotification(notification, acknowledgment); - //then - assertThrows(RuntimeException.class, executable); - ArgumentCaptor userCaptor = ArgumentCaptor.forClass(String.class); - verify(externalApiConnector, times(1)).getUserOnboardedProductDetails(userNotify.getUserId(), notification.getInstitutionId(), notification.getProductId()); - } - - @Test - void sendUpdateUser_emptyDetails() throws JsonProcessingException { - //given - final UserNotification notification = mockInstance(new UserNotification()); - notification.setEventType(QueueEvent.UPDATE); - final UserNotify userNotify = mockInstance(new UserNotify()); - userNotify.setRelationshipStatus(null); - notification.setUser(userNotify); - notification.setProductId("prod-fd"); - UserProductDetails userProductDetails = mockInstance(new UserProductDetails()); - userProductDetails.setOnboardedUserProductDetails(null); - - when(externalApiConnector.getUserOnboardedProductDetails(anyString(), anyString(), anyString())).thenReturn(userProductDetails); - //when - Executable executable = () -> service.sendUserNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verify(externalApiConnector, times(1)).getUserOnboardedProductDetails(userNotify.getUserId(), notification.getInstitutionId(), notification.getProductId()); - verifyNoInteractions(kafkaTemplate); - } - -} \ No newline at end of file diff --git a/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendSapNotificationTest.java b/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendSapNotificationTest.java deleted file mode 100644 index a6ffb207..00000000 --- a/connector/kafka-manager/src/test/java/it/pagopa/selfcare/external_interceptor/connector/kafka_manager/factory/SendSapNotificationTest.java +++ /dev/null @@ -1,521 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory; - -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import it.pagopa.selfcare.commons.base.utils.InstitutionType; -import it.pagopa.selfcare.commons.base.utils.Origin; -import it.pagopa.selfcare.external_interceptor.connector.api.ExternalApiConnector; -import it.pagopa.selfcare.external_interceptor.connector.api.RegistryProxyConnector; -import it.pagopa.selfcare.external_interceptor.connector.exceptions.ResourceNotFoundException; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.*; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapper; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapperImpl; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.GeographicTaxonomies; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.HomogeneousOrganizationalArea; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.InstitutionProxyInfo; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.OrganizationUnit; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.function.Executable; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.support.Acknowledgment; -import org.springframework.kafka.support.SendResult; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; - -import java.io.IOException; -import java.util.List; -import java.util.Set; -import java.util.TimeZone; - -import static it.pagopa.selfcare.commons.utils.TestUtils.checkNotNullFields; -import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; -import static it.pagopa.selfcare.external_interceptor.connector.kafka_manager.factory.KafkaSend.SCHEMA_VERSION; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; -import static org.mockito.MockitoAnnotations.openMocks; - -@ContextConfiguration(classes = {SendSapNotificationTest.Config.class, SendSapNotification.class, KafkaSend.class, NotificationMapperImpl.class}) -@ExtendWith(MockitoExtension.class) -class SendSapNotificationTest { - public static class Config { - @Bean - @Primary - public ObjectMapper objectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(new Jdk8Module()); - mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - mapper.setTimeZone(TimeZone.getDefault()); - return mapper; - } - } - - private KafkaTemplate kafkaTemplate; - @Mock - private KafkaSend abstractService; - @Spy - private NotificationMapper notificationMapperSpy = new NotificationMapperImpl(); - @Spy - private ObjectMapper mapper = new ObjectMapper(); - - private Acknowledgment acknowledgment; - private ListenableFuture mockFuture; - private SendResult mockSendResult; - private SendSapNotification service; - - private RegistryProxyConnector registryProxyConnector; - private ExternalApiConnector externalApiConnector; - AutoCloseable closeable; - - @Mock - private ListenableFutureCallback> mockProducerCallback; - - - @BeforeEach - void setUp() { - closeable = openMocks(this); - acknowledgment = mock(Acknowledgment.class); - kafkaTemplate = mock(KafkaTemplate.class); - mockFuture = mock(ListenableFuture.class); - mockSendResult = mock(SendResult.class); - registryProxyConnector = mock(RegistryProxyConnector.class); - externalApiConnector = mock(ExternalApiConnector.class); - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, Set.of(InstitutionType.PA), List.of("prod-io-premium", "prod-pn"), Set.of(Origin.IPA, Origin.SELC)); - } - - @AfterEach - void close() throws Exception { - closeable.close(); - } - - @Test - void sendInstitutionNotificationEc() throws JsonProcessingException { - //given - final Notification notification = createNotificationMock(); - Institution institution = mockInstance(new Institution(), "setCity", "setRootParent"); - institution.setSubUnitType("EC"); - institution.setOrigin("IPA"); - institution.setInstitutionType(InstitutionType.PA); - final Billing billing = createBillingMock(); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-io-premium"); - notification.setState("ACTIVE"); - InstitutionProxyInfo mockProxyInfo = mockInstance(new InstitutionProxyInfo()); - GeographicTaxonomies proxyTaxonomy = mockInstance(new GeographicTaxonomies()); - proxyTaxonomy.setCountry("proxyContry"); - proxyTaxonomy.setProvinceAbbreviation("proxyProvince"); - proxyTaxonomy.setDescription("proxyCity - COMUNE"); - proxyTaxonomy.setIstatCode(mockProxyInfo.getIstatCode()); - when(registryProxyConnector.getInstitutionProxyById(any())).thenReturn(mockProxyInfo); - when(registryProxyConnector.getExtById(any())).thenReturn(proxyTaxonomy); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - verify(acknowledgment, times(1)).acknowledge(); - verify(registryProxyConnector, times(1)).getInstitutionProxyById(institution.getTaxCode()); - verify(registryProxyConnector, times(1)).getExtById(mockProxyInfo.getIstatCode()); - verifyNoMoreInteractions(registryProxyConnector); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "user"); - checkNotNullFields(captured.getInstitution(), "rootParent"); - } - - @Test - void sendInstitutionNotificationUo() throws JsonProcessingException { - //given - final Notification notification = createNotificationMock(); - Institution institution = mockInstance(new Institution(), "setCity"); - institution.setSubUnitType("UO"); - institution.setOrigin("IPA"); - institution.setInstitutionType(InstitutionType.PA); - final Billing billing = createBillingMock(); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-pn"); - notification.setState("ACTIVE"); - OrganizationUnit mockUO = mockInstance(new OrganizationUnit()); - GeographicTaxonomies uoGeoTaxonomy = mockInstance(new GeographicTaxonomies()); - uoGeoTaxonomy.setCountry("uoCountry"); - uoGeoTaxonomy.setProvinceAbbreviation("uoProvince"); - uoGeoTaxonomy.setDescription("uoCity - COMUNE"); - uoGeoTaxonomy.setIstatCode(mockUO.getMunicipalIstatCode()); - when(registryProxyConnector.getUoById(any())).thenReturn(mockUO); - when(registryProxyConnector.getExtById(any())).thenReturn(uoGeoTaxonomy); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - verify(acknowledgment, times(1)).acknowledge(); - verify(registryProxyConnector, times(1)).getUoById(institution.getSubUnitCode()); - verify(registryProxyConnector, times(1)).getExtById(mockUO.getMunicipalIstatCode()); - verifyNoMoreInteractions(registryProxyConnector); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "user"); - checkNotNullFields(captured.getInstitution()); - } - - @Test - void sendInstitutionNotificationAoo() throws JsonProcessingException { - //given - final Notification notification = createNotificationMock(); - Institution institution = mockInstance(new Institution(), "setCity"); - institution.setSubUnitType("AOO"); - institution.setOrigin("IPA"); - institution.setInstitutionType(InstitutionType.PA); - final Billing billing = createBillingMock(); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-pn"); - notification.setState("ACTIVE"); - HomogeneousOrganizationalArea mockUO = mockInstance(new HomogeneousOrganizationalArea()); - GeographicTaxonomies uoGeoTaxonomy = mockInstance(new GeographicTaxonomies()); - uoGeoTaxonomy.setCountry("aooCountry"); - uoGeoTaxonomy.setProvinceAbbreviation("aooProvince"); - uoGeoTaxonomy.setDescription("aooCity - COMUNE"); - uoGeoTaxonomy.setIstatCode(mockUO.getMunicipalIstatCode()); - when(registryProxyConnector.getAooById(any())).thenReturn(mockUO); - when(registryProxyConnector.getExtById(any())).thenReturn(uoGeoTaxonomy); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - verify(acknowledgment, times(1)).acknowledge(); - verify(registryProxyConnector, times(1)).getAooById(institution.getSubUnitCode()); - verify(registryProxyConnector, times(1)).getExtById(mockUO.getMunicipalIstatCode()); - verifyNoMoreInteractions(registryProxyConnector); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "user"); - assertEquals("Sc-Contracts-Sap",producerRecordArgumentCaptor.getValue().topic()); - checkNotNullFields(captured.getInstitution()); - } - - @Test - void sendInstitutionNotification_NotFound() throws JsonProcessingException { - //given - final Notification notification = createNotificationMock(); - Institution institution = mockInstance(new Institution(), "setCity"); - institution.setSubUnitType("AOO"); - institution.setOrigin("IPA"); - institution.setInstitutionType(InstitutionType.PA); - final Billing billing = createBillingMock(); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-pn"); - notification.setState("ACTIVE"); - when(registryProxyConnector.getAooById(any())).thenThrow(ResourceNotFoundException.class); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture());; - verify(acknowledgment, times(1)).acknowledge(); - verify(registryProxyConnector, times(1)).getAooById(institution.getSubUnitCode()); - verifyNoMoreInteractions(registryProxyConnector); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "user"); - checkNotNullFields(captured.getInstitution(), "istatCode", "city", "country", "county"); - } - - @Test - void sendSapNotification_nullSubUnitType() throws IOException { - //given - final Notification notification = createNotificationMock(); - Institution institution = createInstitutionMock(); - institution.setSubUnitType(null); - institution.setOrigin("IPA"); - institution.setInstitutionType(InstitutionType.PA); - final Billing billing = createBillingMock(); - notification.setInstitution(institution); - notification.setBilling(billing); - notification.setProduct("prod-pn"); - notification.setState("ACTIVE"); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> recordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(recordArgumentCaptor.capture()); - verify(acknowledgment, times(1)).acknowledge(); - verifyNoInteractions(registryProxyConnector); - ProducerRecord captured = recordArgumentCaptor.getValue(); - assertNull(captured.headers().lastHeader(SCHEMA_VERSION)); - } - - @Test - void noExcludedInstitutionTypes() { - //given - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, null, List.of("prod-pn"), Set.of(Origin.IPA)); - final Notification notification = createNotificationMock(); - final Institution institution = createInstitutionMock(); - final OnboardedProduct onboardedProduct = createOnboardedProductMock(); - final Billing billing = createBillingMock(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setProduct("prod-pn"); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - - @Test - void allowedProductsNotPresent() { - //given - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, Set.of(InstitutionType.PA), null, Set.of(Origin.IPA)); - final Notification notification = createNotificationMock(); - final Institution institution = createInstitutionMock(); - final OnboardedProduct onboardedProduct = createOnboardedProductMock(); - final Billing billing = createBillingMock(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - institution.setInstitutionType(InstitutionType.PA); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - - @Test - void notificationInstitutionType_notPresent() { - //given - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, Set.of(InstitutionType.PA), List.of("prod-pn"), Set.of(Origin.IPA)); - final Notification notification = createNotificationMock(); - final Institution institution = createInstitutionMock(); - institution.setInstitutionType(InstitutionType.SA); - final OnboardedProduct onboardedProduct = createOnboardedProductMock(); - final Billing billing = createBillingMock(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - notification.setProduct("prod-pn"); - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - - @Test - void productNotAllowed() { - //given - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, Set.of(InstitutionType.PA), List.of("prod-pn"), Set.of(Origin.IPA)); - final Notification notification = createNotificationMock(); - final Institution institution = createInstitutionMock(); - institution.setInstitutionType(InstitutionType.SA); - final OnboardedProduct onboardedProduct = createOnboardedProductMock(); - final Billing billing = createBillingMock(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - notification.setProduct("prod-io"); - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - - @Test - void isProdIoFast(){ - //given - final Notification notification = createNotificationMock(); - notification.setPricingPlan("FA"); - final Institution institution = createInstitutionMock(); - institution.setInstitutionType(InstitutionType.SA); - final OnboardedProduct onboardedProduct = createOnboardedProductMock(); - final Billing billing = createBillingMock(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - notification.setProduct("prod-io"); - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - @Test - void allowedOriginsNotPresent() { - //given - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, Set.of(InstitutionType.PA), List.of("prod-pn"), null); - final Notification notification = new Notification(); - final Institution institution = new Institution(); - institution.setInstitutionType(InstitutionType.PA); - institution.setOrigin(Origin.IPA.getValue()); - final OnboardedProduct onboardedProduct = new OnboardedProduct(); - final Billing billing = new Billing(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - notification.setProduct("prod-pn"); - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - - @Test - void originNotAllowed(){ - //given - service = new SendSapNotification(kafkaTemplate, notificationMapperSpy, mapper, registryProxyConnector, externalApiConnector, Set.of(InstitutionType.PA, InstitutionType.GSP), List.of("prod-pn"), Set.of(Origin.IPA)); - final Notification notification = new Notification(); - final Institution institution = new Institution(); - institution.setInstitutionType(InstitutionType.GSP); - institution.setOrigin(Origin.SELC.getValue()); - final OnboardedProduct onboardedProduct = new OnboardedProduct(); - final Billing billing = new Billing(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - notification.setProduct("prod-pn"); - //when - Executable executable = () -> service.sendInstitutionNotification(notification, acknowledgment); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(kafkaTemplate); - } - - @Test - void sendOldEvents() throws JsonProcessingException { - //given - final Notification notification = createNotificationMock(); - final Institution institution = createInstitutionMock(); - institution.setOrigin("IPA"); - institution.setInstitutionType(InstitutionType.PA); - final OnboardedProduct onboardedProduct = createOnboardedProductMock(); - final Billing billing = createBillingMock(); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - notification.setInstitution(institution); - notification.setState("ACTIVE"); - notification.setProduct("prod-pn"); - when(kafkaTemplate.send(any(ProducerRecord.class))) - .thenReturn(mockFuture); - - doAnswer(invocationOnMock -> { - ListenableFutureCallback callback = invocationOnMock.getArgument(0); - callback.onSuccess(mockSendResult); - return null; - }).when(mockFuture).addCallback(any(ListenableFutureCallback.class)); - - //when - Executable executable = () -> service.sendOldEvents(notification); - //then - assertDoesNotThrow(executable); - ArgumentCaptor> producerRecordArgumentCaptor = ArgumentCaptor.forClass(ProducerRecord.class); - verify(kafkaTemplate, times(1)).send(producerRecordArgumentCaptor.capture()); - verifyNoMoreInteractions(registryProxyConnector); - NotificationToSend captured = mapper.readValue(producerRecordArgumentCaptor.getValue().value(), NotificationToSend.class); - checkNotNullFields(captured, "user"); - checkNotNullFields(captured.getInstitution(), "subUnitType"); - } - - - private static Notification createNotificationMock(){ - return mockInstance(new Notification()); - } - - private static Institution createInstitutionMock(){ - return mockInstance(new Institution()); - } - - private static Billing createBillingMock(){ - return mockInstance(new Billing()); - } - - private static OnboardedProduct createOnboardedProductMock(){ - return mockInstance(new OnboardedProduct()); - } -} \ No newline at end of file diff --git a/connector/rest/src/main/resources/config/application.properties b/connector/rest/src/main/resources/config/application.properties index e7d58e7c..07998391 100644 --- a/connector/rest/src/main/resources/config/application.properties +++ b/connector/rest/src/main/resources/config/application.properties @@ -45,7 +45,7 @@ feign.client.config.internal-api.errorDecoder=it.pagopa.selfcare.external_interc rest-client.external-api.serviceCode=external-api rest-client.external-api.base-url=${EXTERNAL_API_BACKEND_URL} -rest-client.external-api.getUserProductInfo.path=/users/{id}/onboarded-product +rest-client.external-api.getUserProductInfo.path=/v2/users/{id}/onboarded-product feign.client.config.external-api.connectTimeout=${EXTERNAL_API_CLIENT_CONNECT_TIMEOUT:${REST_CLIENT_CONNECT_TIMEOUT:5000}} feign.client.config.external-api.readTimeout=${EXTERNAL_API_CLIENT_READ_TIMEOUT:${REST_CLIENT_READ_TIMEOUT:10000}} feign.client.config.external-api.loggerLevel=${EXTERNAL_API_LOG_LEVEL:${REST_CLIENT_LOG_LEVEL:FULL}} diff --git a/core/src/main/java/it/pagopa/selfcare/external_interceptor/core/SchedulerService.java b/core/src/main/java/it/pagopa/selfcare/external_interceptor/core/SchedulerService.java deleted file mode 100644 index e9695706..00000000 --- a/core/src/main/java/it/pagopa/selfcare/external_interceptor/core/SchedulerService.java +++ /dev/null @@ -1,7 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.core; - -import java.util.Optional; - -public interface SchedulerService { - void startScheduler(Optional size); -} diff --git a/core/src/main/java/it/pagopa/selfcare/external_interceptor/core/SchedulerServiceImpl.java b/core/src/main/java/it/pagopa/selfcare/external_interceptor/core/SchedulerServiceImpl.java deleted file mode 100644 index d7007872..00000000 --- a/core/src/main/java/it/pagopa/selfcare/external_interceptor/core/SchedulerServiceImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.core; - -import com.fasterxml.jackson.core.JsonProcessingException; -import it.pagopa.selfcare.external_interceptor.connector.api.KafkaSapSendService; -import it.pagopa.selfcare.external_interceptor.connector.api.MsCoreConnector; -import it.pagopa.selfcare.external_interceptor.connector.api.RegistryProxyConnector; -import it.pagopa.selfcare.external_interceptor.connector.exceptions.ResourceNotFoundException; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Institution; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Notification; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.RootParent; -import it.pagopa.selfcare.external_interceptor.connector.model.interceptor.QueueEvent; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapper; -import it.pagopa.selfcare.external_interceptor.connector.model.ms_core.Token; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.GeographicTaxonomies; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.InstitutionProxyInfo; -import it.pagopa.selfcare.external_interceptor.connector.model.user.RelationshipState; -import it.pagopa.selfcare.external_interceptor.core.config.ScheduledConfig; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import java.time.OffsetDateTime; -import java.util.List; -import java.util.Optional; - -@Service -@Slf4j -public class SchedulerServiceImpl implements SchedulerService{ - private final MsCoreConnector msCoreConnector; - public static final int TOKEN_PAGE_SIZE = 100; - private Optional token_page_size_api = Optional.empty(); - private final KafkaSapSendService kafkaSapSendService; - private final Optional> productsToRetrieve; - private final ScheduledConfig configProperties; - private final NotificationMapper notificationMapper; - private final RegistryProxyConnector partyRegistryProxyConnector; - static final String DESCRIPTION_TO_REPLACE_REGEX = " - COMUNE"; - public SchedulerServiceImpl(MsCoreConnector msCoreConnector, - KafkaSapSendService kafkaSapSendService, - @Value("#{'${external-interceptor.scheduler.products-to-resend}'.split(',')}") List productsToRetrieve, - ScheduledConfig configProperties, - NotificationMapper notificationMapper, - RegistryProxyConnector partyRegistryProxyConnector) { - this.msCoreConnector = msCoreConnector; - this.kafkaSapSendService = kafkaSapSendService; - this.productsToRetrieve = Optional.ofNullable(productsToRetrieve); - this.configProperties = configProperties; - this.notificationMapper = notificationMapper; - this.partyRegistryProxyConnector = partyRegistryProxyConnector; - } - - @Scheduled(fixedDelayString = "${scheduler.fixed-delay.delay}") - void regenerateQueueNotifications() { - log.trace("regenerateQueueNotifications start"); - if (configProperties.getSendOldEvent() && productsToRetrieve.isPresent()) { - for (String productId : productsToRetrieve.get()) { - int page = 0; - boolean nextPage = true; - do { - List tokens = msCoreConnector.retrieveTokensByProductId(productId, page, token_page_size_api.orElse(TOKEN_PAGE_SIZE)); - log.debug("[KAFKA] TOKEN NUMBER {} PAGE {}", tokens.size(), page); - - sendSapNotifications(tokens); - page += 1; - if (tokens.size() < TOKEN_PAGE_SIZE) { - nextPage = false; - log.debug("[KAFKA] TOKEN TOTAL NUMBER {}", page * TOKEN_PAGE_SIZE + tokens.size()); - } - - } while (nextPage); - } - this.token_page_size_api = Optional.empty(); - configProperties.setScheduler(false); - } - log.info("Next scheduled check at {}", OffsetDateTime.now().plusSeconds(configProperties.getFixedDelay() / 1000)); - log.trace("regenerateQueueNotifications end"); - - } - - private void sendSapNotifications(List tokens) { - tokens.forEach(token -> { - if(RelationshipState.ACTIVE.equals(token.getStatus())) { - try { - Institution institution = msCoreConnector.getInstitutionById(token.getInstitutionId()); - RootParent rootParent = new RootParent(); - rootParent.setDescription(institution.getParentDescription()); - Notification toNotify = notificationMapper.toNotificationToSend(institution, token, QueueEvent.ADD); - setInstitutionLocationFields(institution); - toNotify.setInstitution(institution); - try { - kafkaSapSendService.sendOldEvents(toNotify); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } catch (ResourceNotFoundException e){ - log.warn("Error while searching institution {} on IPA, {} ", token.getInstitutionId(), e.getMessage()); - } - - } - }); - } - - private void setInstitutionLocationFields(Institution institution){ - try { - InstitutionProxyInfo institutionProxyInfo = partyRegistryProxyConnector.getInstitutionProxyById(institution.getExternalId()); - institution.setIstatCode(institutionProxyInfo.getIstatCode()); - GeographicTaxonomies geographicTaxonomies = partyRegistryProxyConnector.getExtById(institution.getIstatCode()); - institution.setCounty(geographicTaxonomies.getProvinceAbbreviation()); - institution.setCountry(geographicTaxonomies.getCountryAbbreviation()); - institution.setCity(geographicTaxonomies.getDescription().replace(DESCRIPTION_TO_REPLACE_REGEX, "")); - } catch (ResourceNotFoundException e) { - log.warn("[INSTITUTION NOT FOUND]Error while searching institution {}, {} ", institution.getExternalId(), e.getMessage()); - institution.setIstatCode(null); - } - } - - @Override - public void startScheduler(Optional size) { - this.token_page_size_api = size; - configProperties.setScheduler(true); - } -} diff --git a/core/src/test/java/it/pagopa/selfcare/external_interceptor/core/SchedulerServiceImplTest.java b/core/src/test/java/it/pagopa/selfcare/external_interceptor/core/SchedulerServiceImplTest.java deleted file mode 100644 index 3197ba3f..00000000 --- a/core/src/test/java/it/pagopa/selfcare/external_interceptor/core/SchedulerServiceImplTest.java +++ /dev/null @@ -1,187 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.core; - -import com.fasterxml.jackson.core.JsonProcessingException; -import it.pagopa.selfcare.external_interceptor.connector.api.KafkaSapSendService; -import it.pagopa.selfcare.external_interceptor.connector.api.MsCoreConnector; -import it.pagopa.selfcare.external_interceptor.connector.api.RegistryProxyConnector; -import it.pagopa.selfcare.external_interceptor.connector.exceptions.ResourceNotFoundException; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Billing; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.Institution; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.InstitutionUpdate; -import it.pagopa.selfcare.external_interceptor.connector.model.institution.OnboardedProduct; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapper; -import it.pagopa.selfcare.external_interceptor.connector.model.mapper.NotificationMapperImpl; -import it.pagopa.selfcare.external_interceptor.connector.model.ms_core.Token; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.GeographicTaxonomies; -import it.pagopa.selfcare.external_interceptor.connector.model.registry_proxy.InstitutionProxyInfo; -import it.pagopa.selfcare.external_interceptor.connector.model.user.RelationshipState; -import it.pagopa.selfcare.external_interceptor.core.config.ScheduledConfig; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.function.Executable; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.List; -import java.util.Optional; - -import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class SchedulerServiceImplTest { - - @InjectMocks - private SchedulerServiceImpl schedulerService; - @Mock - private KafkaSapSendService sapSendService; - @Mock - private MsCoreConnector msCoreConnector; - @Mock - private RegistryProxyConnector registryProxyConnector; - @Spy - private NotificationMapper notificationMapper = new NotificationMapperImpl(); - @Mock - private ScheduledConfig scheduledConfig; - - - @Test - void regenerateQueueNotification() throws JsonProcessingException { - //given - final Token token= mockInstance(new Token()); - token.setStatus(RelationshipState.ACTIVE); - final InstitutionUpdate institutionUpdate = mockInstance(new InstitutionUpdate()); - token.setInstitutionUpdate(institutionUpdate); - final Institution institution = mockInstance(new Institution()); - final OnboardedProduct onboardedProduct = mockInstance(new OnboardedProduct()); - final Billing billing = mockInstance(new Billing()); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - final String productId = "productId"; - - schedulerService = new SchedulerServiceImpl(msCoreConnector, sapSendService, List.of(productId), scheduledConfig, notificationMapper, registryProxyConnector); - - final InstitutionProxyInfo institutionProxyInfo = mockInstance(new InstitutionProxyInfo()); - final GeographicTaxonomies geographicTaxonomies = mockInstance(new GeographicTaxonomies()); - - when(msCoreConnector.getInstitutionById(anyString())).thenReturn(institution); - when(scheduledConfig.getSendOldEvent()).thenReturn(true); - when(msCoreConnector.retrieveTokensByProductId(anyString(), any(), any())).thenReturn(List.of(token)); - when(registryProxyConnector.getInstitutionProxyById(anyString())).thenReturn(institutionProxyInfo); - when(registryProxyConnector.getExtById(anyString())).thenReturn(geographicTaxonomies); - - //when - Executable executable = () -> schedulerService.regenerateQueueNotifications(); - //then - assertDoesNotThrow(executable); - verify(msCoreConnector, times(1)).retrieveTokensByProductId(productId, 0, 100 - ); - verify(msCoreConnector, times(1)).getInstitutionById(token.getInstitutionId()); - verify(registryProxyConnector, times(1)).getInstitutionProxyById(institution.getExternalId()); - verify(sapSendService, times(1)).sendOldEvents(any()); - verify(registryProxyConnector, times(1)).getExtById(institutionProxyInfo.getIstatCode()); - } - - @Test - void resourceNotFound_proxy() throws JsonProcessingException { - //given - final Token token= mockInstance(new Token()); - final InstitutionUpdate institutionUpdate = mockInstance(new InstitutionUpdate()); - token.setInstitutionUpdate(institutionUpdate); - final Institution institution = mockInstance(new Institution()); - final OnboardedProduct onboardedProduct = mockInstance(new OnboardedProduct()); - final Billing billing = mockInstance(new Billing()); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - final String productId = "productId"; - - schedulerService = new SchedulerServiceImpl(msCoreConnector, sapSendService, List.of(productId), scheduledConfig, notificationMapper, registryProxyConnector); - - final InstitutionProxyInfo institutionProxyInfo = mockInstance(new InstitutionProxyInfo()); - final GeographicTaxonomies geographicTaxonomies = mockInstance(new GeographicTaxonomies()); - - when(msCoreConnector.getInstitutionById(anyString())).thenReturn(institution); - when(scheduledConfig.getSendOldEvent()).thenReturn(true); - when(msCoreConnector.retrieveTokensByProductId(anyString(), any(), any())).thenReturn(List.of(token)); - when(registryProxyConnector.getInstitutionProxyById(anyString())).thenThrow(ResourceNotFoundException.class); - - //when - Executable executable = () -> schedulerService.regenerateQueueNotifications(); - //then - assertDoesNotThrow(executable); - verify(msCoreConnector, times(1)).retrieveTokensByProductId(productId, 0, 100); - verify(msCoreConnector, times(1)).getInstitutionById(token.getInstitutionId()); - verify(registryProxyConnector, times(1)).getInstitutionProxyById(institution.getExternalId()); - verify(sapSendService, times(1)).sendOldEvents(any()); - - } - - @Test - void resourceNotFound_msCore(){ - //given - final Token token= mockInstance(new Token()); - final InstitutionUpdate institutionUpdate = mockInstance(new InstitutionUpdate()); - token.setInstitutionUpdate(institutionUpdate); - final Institution institution = mockInstance(new Institution()); - final OnboardedProduct onboardedProduct = mockInstance(new OnboardedProduct()); - final Billing billing = mockInstance(new Billing()); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - final String productId = "productId"; - - schedulerService = new SchedulerServiceImpl(msCoreConnector, sapSendService, List.of(productId), scheduledConfig, notificationMapper, registryProxyConnector); - - final InstitutionProxyInfo institutionProxyInfo = mockInstance(new InstitutionProxyInfo()); - final GeographicTaxonomies geographicTaxonomies = mockInstance(new GeographicTaxonomies()); - - when(msCoreConnector.getInstitutionById(anyString())).thenThrow(ResourceNotFoundException.class); - when(scheduledConfig.getSendOldEvent()).thenReturn(true); - when(msCoreConnector.retrieveTokensByProductId(anyString(), any(), any())).thenReturn(List.of(token)); - - //when - Executable executable = () -> schedulerService.regenerateQueueNotifications(); - //then - assertDoesNotThrow(executable); - verifyNoInteractions(sapSendService, registryProxyConnector); - verify(msCoreConnector, times(1)).retrieveTokensByProductId(productId, 0, 100); - verify(msCoreConnector, times(1)).getInstitutionById(token.getInstitutionId()); - } - @Test - void sendSapNotification_notActive( ) throws JsonProcessingException { - //given - final Token token= mockInstance(new Token()); - token.setStatus(RelationshipState.PENDING); - final InstitutionUpdate institutionUpdate = mockInstance(new InstitutionUpdate()); - token.setInstitutionUpdate(institutionUpdate); - final Institution institution = mockInstance(new Institution()); - final OnboardedProduct onboardedProduct = mockInstance(new OnboardedProduct()); - final Billing billing = mockInstance(new Billing()); - onboardedProduct.setBilling(billing); - institution.setOnboarding(List.of(onboardedProduct)); - final String productId = "productId"; - when(scheduledConfig.getSendOldEvent()).thenReturn(true); - when(msCoreConnector.retrieveTokensByProductId(anyString(), any(), any())).thenReturn(List.of(token)); - schedulerService = new SchedulerServiceImpl(msCoreConnector, sapSendService, List.of(productId), scheduledConfig, notificationMapper, registryProxyConnector); - //when - Executable executable = () -> schedulerService.regenerateQueueNotifications(); - //then - assertDoesNotThrow(executable); - verify(msCoreConnector, times(1)).retrieveTokensByProductId(productId, 0, 100); - verifyNoMoreInteractions(msCoreConnector); - verifyNoInteractions( registryProxyConnector, notificationMapper, sapSendService); - } - - @Test - void startScheduler(){ - //when - schedulerService.startScheduler(Optional.of(1)); - //then - verify(scheduledConfig,times(1)).setScheduler(true); - } - -} \ No newline at end of file diff --git a/infra/container_apps/README.md b/infra/container_apps/README.md index 6cf55732..4705f81f 100644 --- a/infra/container_apps/README.md +++ b/infra/container_apps/README.md @@ -18,7 +18,7 @@ No providers. | Name | Source | Version | |------|--------|---------| -| [container\_app\_dashboard\_backend](#module\_container\_app\_dashboard\_backend) | github.com/pagopa/selfcare-commons//infra/terraform-modules/container_app_microservice | main | +| [container\_app\_ext\_interceptor](#module\_container\_app\_ext\_interceptor) | github.com/pagopa/selfcare-commons//infra/terraform-modules/container_app_microservice | main | ## Resources @@ -29,12 +29,14 @@ No resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [app\_settings](#input\_app\_settings) | n/a |
list(object({
name = string
value = string
}))
| n/a | yes | +| [cae\_name](#input\_cae\_name) | Container App Environment name | `string` | `"cae-cp"` | no | | [container\_app](#input\_container\_app) | Container App configuration |
object({
min_replicas = number
max_replicas = number

scale_rules = list(object({
name = string
custom = object({
metadata = map(string)
type = string
})
}))

cpu = number
memory = string
})
| n/a | yes | | [env\_short](#input\_env\_short) | Environment short name | `string` | n/a | yes | | [image\_tag](#input\_image\_tag) | Image tag to use for the container | `string` | `"latest"` | no | | [is\_pnpg](#input\_is\_pnpg) | (Optional) True if you want to apply changes to PNPG environment | `bool` | `false` | no | | [secrets\_names](#input\_secrets\_names) | KeyVault secrets to get values from | `map(string)` | n/a | yes | | [tags](#input\_tags) | n/a | `map(any)` | n/a | yes | +| [workload\_profile\_name](#input\_workload\_profile\_name) | Workload Profile name to use | `string` | `null` | no | ## Outputs diff --git a/infra/container_apps/env/dev/terraform.tfvars b/infra/container_apps/env/dev/terraform.tfvars index 1aa79b7e..4e4176f4 100644 --- a/infra/container_apps/env/dev/terraform.tfvars +++ b/infra/container_apps/env/dev/terraform.tfvars @@ -55,15 +55,15 @@ app_settings = [ }, { name = "USERVICE_PARTY_REGISTRY_PROXY_URL" - value = "https://selc-d-party-reg-proxy-ca.gentleflower-c63e62fe.westeurope.azurecontainerapps.io" + value = "https://selc-d-party-reg-proxy-ca.politewater-9af33050.westeurope.azurecontainerapps.io" }, { name = "EXTERNAL_API_BACKEND_URL" - value = "https://selc-d-external-api-backend-ca.gentleflower-c63e62fe.westeurope.azurecontainerapps.io" + value = "https://selc-d-ext-api-backend-ca.politewater-9af33050.westeurope.azurecontainerapps.io" }, { name = "MS_CORE_URL" - value = "https://selc-d-ms-core-ca.gentleflower-c63e62fe.westeurope.azurecontainerapps.io" + value = "https://selc-d-ms-core-ca.politewater-9af33050.westeurope.azurecontainerapps.io" }, { name = "PROD_FD_URL" diff --git a/infra/container_apps/env/prod/terraform.tfvars b/infra/container_apps/env/prod/terraform.tfvars index fc9ad394..c01b3ef4 100644 --- a/infra/container_apps/env/prod/terraform.tfvars +++ b/infra/container_apps/env/prod/terraform.tfvars @@ -70,15 +70,15 @@ app_settings = [ }, { name = "USERVICE_PARTY_REGISTRY_PROXY_URL" - value = "https://selc-p-party-reg-proxy-ca.bluedune-cc0f8752.westeurope.azurecontainerapps.io" + value = "https://selc-p-party-reg-proxy-ca.greensand-62fc96da.westeurope.azurecontainerapps.io" }, { name = "EXTERNAL_API_BACKEND_URL" - value = "https://selc-p-external-api-backend-ca.bluedune-cc0f8752.westeurope.azurecontainerapps.io" + value = "https://selc-d-ext-api-backend-ca.greensand-62fc96da.westeurope.azurecontainerapps.io" }, { name = "MS_CORE_URL" - value = "https://selc-p-ms-core-ca.bluedune-cc0f8752.westeurope.azurecontainerapps.io" + value = "https://selc-p-ms-core-ca.greensand-62fc96da.westeurope.azurecontainerapps.io" }, { name = "PROD_FD_URL" diff --git a/infra/container_apps/env/uat/terraform.tfvars b/infra/container_apps/env/uat/terraform.tfvars index 823ef72e..37fd0e4b 100644 --- a/infra/container_apps/env/uat/terraform.tfvars +++ b/infra/container_apps/env/uat/terraform.tfvars @@ -1,4 +1,6 @@ -env_short = "u" +env_short = "u" +suffix_increment = "-001" +cae_name = "cae-001" tags = { CreatedBy = "Terraform" @@ -57,15 +59,15 @@ app_settings = [ }, { name = "USERVICE_PARTY_REGISTRY_PROXY_URL" - value = "https://selc-u-party-reg-proxy-ca.calmsky-143987c1.westeurope.azurecontainerapps.io" + value = "https://selc-u-party-reg-proxy-ca.proudglacier-20652b81.westeurope.azurecontainerapps.io" }, { name = "EXTERNAL_API_BACKEND_URL" - value = "https://selc-u-external-api-backend-ca.calmsky-143987c1.westeurope.azurecontainerapps.io" + value = "https://selc-d-ext-api-backend-ca.proudglacier-20652b81.westeurope.azurecontainerapps.io" }, { name = "MS_CORE_URL" - value = "https://selc-u-ms-core-ca.calmsky-143987c1.westeurope.azurecontainerapps.io" + value = "https://selc-u-ms-core-ca.proudglacier-20652b81.westeurope.azurecontainerapps.io" }, { name = "PROD_FD_URL" diff --git a/infra/container_apps/locals.tf b/infra/container_apps/locals.tf new file mode 100644 index 00000000..167de2c5 --- /dev/null +++ b/infra/container_apps/locals.tf @@ -0,0 +1,7 @@ +locals { + pnpg_suffix = var.is_pnpg == true ? "-pnpg" : "" + project = "selc-${var.env_short}" + + container_app_environment_name = "${local.project}${local.pnpg_suffix}-${var.cae_name}" + ca_resource_group_name = "${local.project}-container-app${var.suffix_increment}-rg" +} \ No newline at end of file diff --git a/infra/container_apps/main.tf b/infra/container_apps/main.tf index 89d7ec83..12e8a6e0 100644 --- a/infra/container_apps/main.tf +++ b/infra/container_apps/main.tf @@ -8,18 +8,21 @@ provider "azurerm" { features {} } -module "container_app_dashboard_backend" { +module "container_app_ext_interceptor" { source = "github.com/pagopa/selfcare-commons//infra/terraform-modules/container_app_microservice?ref=main" is_pnpg = var.is_pnpg - env_short = var.env_short - container_app = var.container_app - container_app_name = "ext-interceptor" - image_name = "selfcare-ms-external-interceptor" - image_tag = var.image_tag - app_settings = var.app_settings - secrets_names = var.secrets_names + env_short = var.env_short + resource_group_name = local.ca_resource_group_name + container_app = var.container_app + container_app_name = "ext-interceptor" + container_app_environment_name = local.container_app_environment_name + image_name = "selfcare-ms-external-interceptor" + image_tag = var.image_tag + app_settings = var.app_settings + secrets_names = var.secrets_names + workload_profile_name = var.workload_profile_name tags = var.tags } diff --git a/infra/container_apps/variables.tf b/infra/container_apps/variables.tf index b9baf169..ee081bc6 100644 --- a/infra/container_apps/variables.tf +++ b/infra/container_apps/variables.tf @@ -55,3 +55,21 @@ variable "secrets_names" { type = map(string) description = "KeyVault secrets to get values from" } + +variable "workload_profile_name" { + type = string + description = "Workload Profile name to use" + default = null +} + +variable "cae_name" { + type = string + description = "Container App Environment name" + default = "cae-cp" +} + +variable "suffix_increment" { + type = string + description = "Suffix increment Container App Environment name" + default = "" +} diff --git a/web/src/main/java/it/pagopa/selfcare/external_interceptor/web/controller/SchedulerController.java b/web/src/main/java/it/pagopa/selfcare/external_interceptor/web/controller/SchedulerController.java deleted file mode 100644 index 14df3865..00000000 --- a/web/src/main/java/it/pagopa/selfcare/external_interceptor/web/controller/SchedulerController.java +++ /dev/null @@ -1,30 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.web.controller; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import it.pagopa.selfcare.external_interceptor.core.SchedulerService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; - -import java.util.Optional; - -@RestController -@Slf4j -@RequestMapping("/scheduler") -@Api(tags = "scheduler") -public class SchedulerController { - - private final SchedulerService schedulerService; - - public SchedulerController(SchedulerService schedulerService) { - this.schedulerService = schedulerService; - } - @ApiOperation(value = "", notes = "${swagger.external-interceptor.scheduler.api.start}") - @PostMapping(value = "") - @ResponseStatus(HttpStatus.ACCEPTED) - public void start(@RequestParam(name = "size", required = false) Optional size){ - log.trace("Scheduler Started"); - schedulerService.startScheduler(size); - } -} diff --git a/web/src/test/java/it/pagopa/selfcare/external_interceptor/web/controller/SchedulerControllerTest.java b/web/src/test/java/it/pagopa/selfcare/external_interceptor/web/controller/SchedulerControllerTest.java deleted file mode 100644 index 0b9edc1a..00000000 --- a/web/src/test/java/it/pagopa/selfcare/external_interceptor/web/controller/SchedulerControllerTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package it.pagopa.selfcare.external_interceptor.web.controller; - -import com.fasterxml.jackson.databind.ObjectMapper; -import it.pagopa.selfcare.external_interceptor.core.SchedulerService; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -import java.util.Optional; - -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@WebMvcTest(value = {SchedulerController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class) -@ContextConfiguration(classes = {SchedulerController.class}) -class SchedulerControllerTest { - private static final String BASE_URL = "/scheduler"; - @Autowired - protected MockMvc mvc; - @MockBean - private SchedulerService schedulerService; - - @Autowired - private ObjectMapper objectMapper; - - @Test - void startScheduler() throws Exception { - Integer size = 1; - mvc.perform(MockMvcRequestBuilders - .post(BASE_URL) - .param("size", String.valueOf(size))) - .andExpect(status().isAccepted()); - - Mockito.verify(schedulerService, Mockito.times(1)).startScheduler(Optional.of(size)); - } -} \ No newline at end of file