diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctions.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctions.java index 331642445..7c12a1a9d 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctions.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctions.java @@ -268,4 +268,17 @@ public String createDelegationForAggregation(@DurableActivityTrigger(name = "onb context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, CREATE_USERS_ACTIVITY, onboardingString)); return completionService.createDelegation(readOnboardingValue(objectMapper, onboardingString)); } + + /** + * This HTTP-triggered function retrieves onboarding given its identifier + * After that, It sends a message on topics through the event bus + */ + @FunctionName("TestSendEmail") + public HttpResponseMessage sendTestEmail( + @HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage> request, + final ExecutionContext context) { + context.getLogger().info("TestSendEmail trigger processed a request"); + completionService.sendTestEmail(context); + return request.createResponseBuilder(HttpStatus.OK).build(); + } } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionService.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionService.java index c1bbc7695..89d99dc60 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionService.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionService.java @@ -1,5 +1,6 @@ package it.pagopa.selfcare.onboarding.service; +import com.microsoft.azure.functions.ExecutionContext; import it.pagopa.selfcare.onboarding.dto.OnboardingAggregateOrchestratorInput; import it.pagopa.selfcare.onboarding.entity.Onboarding; import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflow; @@ -23,4 +24,6 @@ public interface CompletionService { String createDelegation(Onboarding onboarding); String createAggregateOnboardingRequest(OnboardingAggregateOrchestratorInput onboardingAggregateOrchestratorInput); + + void sendTestEmail(ExecutionContext context); } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefault.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefault.java index 76fafc59d..59e4b5b39 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefault.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefault.java @@ -1,5 +1,6 @@ package it.pagopa.selfcare.onboarding.service; +import com.microsoft.azure.functions.ExecutionContext; import it.pagopa.selfcare.onboarding.common.InstitutionPaSubunitType; import it.pagopa.selfcare.onboarding.common.InstitutionType; import it.pagopa.selfcare.onboarding.common.OnboardingStatus; @@ -336,4 +337,9 @@ public String createAggregateOnboardingRequest(OnboardingAggregateOrchestratorIn onboardingRepository.persistOrUpdate(onboardingToUpdate); return onboardingToUpdate.getId(); } + + @Override + public void sendTestEmail(ExecutionContext context) { + notificationService.sendTestEmail(context); + } } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationEventServiceDefault.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationEventServiceDefault.java index 4946c3b60..df0689a38 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationEventServiceDefault.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationEventServiceDefault.java @@ -98,6 +98,7 @@ public void send(ExecutionContext context, Onboarding onboarding, QueueEvent que prepareAndSendNotification(context, product, consumerConfig, onboarding, token.orElse(null), institution, queueEvent); } } catch (Exception e) { + telemetryClient.trackEvent(EVENT_ONBOARDING_FN_NAME, onboardingEventMap(onboarding), Map.of(EVENT_ONBOARDING_INSTTITUTION_FN_FAILURE, 1D)); throw new NotificationException(String.format("Impossible to send notification for onboarding with ID %s", onboarding.getId()), e); } } @@ -137,6 +138,12 @@ private void sendTestEnvProductsNotification(ExecutionContext context, Product p } } + public static Map onboardingEventMap(Onboarding onboarding) { + Map propertiesMap = new HashMap<>(); + Optional.ofNullable(onboarding.getId()).ifPresent(value -> propertiesMap.put("id", value)); + return propertiesMap; + } + public static Map notificationEventMap(NotificationToSend notificationToSend) { Map propertiesMap = new HashMap<>(); Optional.ofNullable(notificationToSend.getId()).ifPresent(value -> propertiesMap.put("id", value)); diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationService.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationService.java index 4afa25887..ad0994729 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationService.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationService.java @@ -1,6 +1,7 @@ package it.pagopa.selfcare.onboarding.service; +import com.microsoft.azure.functions.ExecutionContext; import it.pagopa.selfcare.onboarding.common.InstitutionType; import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflow; import it.pagopa.selfcare.product.entity.Product; @@ -27,4 +28,5 @@ public interface NotificationService { void sendCompletedEmailAggregate(String institutionName, List destinationMails); + void sendTestEmail(ExecutionContext context); } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationServiceDefault.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationServiceDefault.java index 041ac87cb..037230c51 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationServiceDefault.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/NotificationServiceDefault.java @@ -1,6 +1,7 @@ package it.pagopa.selfcare.onboarding.service; import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.azure.functions.ExecutionContext; import io.quarkus.mailer.Mail; import io.quarkus.mailer.Mailer; import it.pagopa.selfcare.azurestorage.AzureBlobClient; @@ -236,4 +237,20 @@ static class FileMailData { String contentType; } + @Override + public void sendTestEmail(ExecutionContext context) { + try { + context.getLogger().info("Sending Test email to " + senderMail); + String html = "TEST EMAIL"; + Mail mail = Mail + .withHtml(senderMail, html, html) + .setFrom(senderMail); + + mailer.send(mail); + context.getLogger().info("End of sending mail to {}, with subject " + senderMail + " with subject " + mail); + } catch (Exception e) { + context.getLogger().severe(String.format("%s: %s", ERROR_DURING_SEND_MAIL, e.getMessage())); + throw new GenericOnboardingException(ERROR_DURING_SEND_MAIL.getMessage()); + } + } } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java index cd4b1a0a9..42d795517 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java @@ -34,6 +34,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -264,9 +265,8 @@ public List countNotifications(String productId, String } - public NotificationCountResult countNotificationsByFilters(String productId, String from, String to, ExecutionContext context) { - Document queryAddEvent = createQuery(productId, List.of(OnboardingStatus.COMPLETED, OnboardingStatus.DELETED), from, to, ACTIVATED_AT_FIELD); - Document queryUpdateEvent = createQuery(productId, List.of(OnboardingStatus.DELETED), from, to, DELETED_AT_FIELD); + public NotificationCountResult countNotificationsByFilters(String productId, String from, String to, ExecutionContext context) {Document queryAddEvent = getQueryNotificationAdd(productId, from, to); + Document queryUpdateEvent = getQueryNotificationDelete(productId, from, to); long countAddEvents = repository.find(queryAddEvent).count(); long countUpdateEvents= repository.find(queryUpdateEvent).count(); @@ -276,12 +276,23 @@ public NotificationCountResult countNotificationsByFilters(String productId, Str return new NotificationCountResult(productId, total); } - private Document createQuery(String productId, List status, String from, String to, String dateField) { + private Document getQueryNotificationDelete(String productId, String from, String to) { + return createQuery(productId, List.of(OnboardingStatus.DELETED), from, to, DELETED_AT_FIELD); + } + + private Document getQueryNotificationAdd(String productId, String from, String to) { + return createQuery(productId, List.of(OnboardingStatus.COMPLETED, OnboardingStatus.DELETED), from, to, ACTIVATED_AT_FIELD); + } + + private Document createQuery(String productId, List status, String from, String to, String dateField, boolean workflowTypeExist) { Document query = new Document(); query.append("productId", productId); query.append("status", new Document("$in", status.stream().map(OnboardingStatus::name).toList())); - query.append("workflowType", new Document("$in", ALLOWED_WORKFLOWS_FOR_INSTITUTION_NOTIFICATIONS.stream().map(Enum::name).toList())); - + if (workflowTypeExist) { + query.append("workflowType", new Document("$in", ALLOWED_WORKFLOWS_FOR_INSTITUTION_NOTIFICATIONS.stream().map(Enum::name).toList())); + } else { + query.append("workflowType", new Document("$exists", false)); + } Document dateQuery = new Document(); Optional.ofNullable(from).ifPresent(value -> query.append(dateField, dateQuery.append("$gte", LocalDate.parse(from, DateTimeFormatter.ISO_LOCAL_DATE)))); Optional.ofNullable(to).ifPresent(value -> query.append(dateField, dateQuery.append("$lte", LocalDate.parse(to, DateTimeFormatter.ISO_LOCAL_DATE)))); @@ -291,6 +302,15 @@ private Document createQuery(String productId, List status, St return query; } + private Document createQuery(String productId, List status, String from, String to, String dateField) { + Document query = new Document(); + List workflowCriteria = new ArrayList<>(); + workflowCriteria.add(createQuery(productId, status, from, to, dateField, true)); + workflowCriteria.add(createQuery(productId, status, from, to, dateField, false)); + query.append("$or", workflowCriteria); + return query; + } + public List getOnboardingsToResend(ResendNotificationsFilters filters, int page, int pageSize) { return repository.find(createQueryByFilters(filters)).page(page, pageSize).list(); } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutor.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutor.java index 36b136232..655b0efcd 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutor.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutor.java @@ -81,6 +81,7 @@ default Optional onboardingCompletionUsersActivity(TaskOrchest final String onboardingString = getOnboardingString(objectMapper(), onboardingWorkflow.getOnboarding()); final String onboardingWorkflowString = getOnboardingWorkflowString(objectMapper(), onboardingWorkflow); ctx.callActivity(CREATE_USERS_ACTIVITY, onboardingString, optionsRetry(), String.class).await(); + ctx.callActivity(STORE_ONBOARDING_ACTIVATEDAT, onboardingString, optionsRetry(), String.class).await(); ctx.callActivity(SEND_MAIL_COMPLETION_ACTIVITY, onboardingWorkflowString, optionsRetry(), String.class).await(); return Optional.of(OnboardingStatus.COMPLETED); } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorConfirmation.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorConfirmation.java index a8620f49d..d37a802f7 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorConfirmation.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorConfirmation.java @@ -7,7 +7,6 @@ import it.pagopa.selfcare.onboarding.entity.Onboarding; import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflow; import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflowInstitution; -import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflowType; import java.util.Optional; diff --git a/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctionsTest.java b/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctionsTest.java index 1e027470a..1a5089a3c 100644 --- a/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctionsTest.java +++ b/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/functions/OnboardingFunctionsTest.java @@ -473,10 +473,11 @@ void onboardingsOrchestratorNewAdmin() { function.onboardingsOrchestrator(orchestrationContext, executionContext); ArgumentCaptor captorActivity = ArgumentCaptor.forClass(String.class); - verify(orchestrationContext, times(2)) + verify(orchestrationContext, times(3)) .callActivity(captorActivity.capture(), any(), any(),any()); assertEquals(CREATE_USERS_ACTIVITY, captorActivity.getAllValues().get(0)); - assertEquals(SEND_MAIL_COMPLETION_ACTIVITY, captorActivity.getAllValues().get(1)); + assertEquals(STORE_ONBOARDING_ACTIVATEDAT, captorActivity.getAllValues().get(1)); + assertEquals(SEND_MAIL_COMPLETION_ACTIVITY, captorActivity.getAllValues().get(2)); verify(service, times(1)) .updateOnboardingStatus(onboarding.getId(), OnboardingStatus.COMPLETED); } @@ -766,4 +767,22 @@ void createDelegationForAggregation() { verify(completionService, times(1)) .createDelegation(any()); } + + @Test + void sendTestEmail() { + @SuppressWarnings("unchecked") final HttpRequestMessage> req = mock(HttpRequestMessage.class); + + doAnswer((Answer) invocation -> { + HttpStatus status = (HttpStatus) invocation.getArguments()[0]; + return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status); + }).when(req).createResponseBuilder(any(HttpStatus.class)); + + when(executionContext.getLogger()).thenReturn(Logger.getGlobal()); + doNothing().when(completionService).sendTestEmail(executionContext); + + function.sendTestEmail(req, executionContext); + + verify(completionService, times(1)) + .sendTestEmail(executionContext); + } } \ No newline at end of file diff --git a/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefaultTest.java b/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefaultTest.java index ecac70d42..d946b2fe0 100644 --- a/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefaultTest.java +++ b/apps/onboarding-functions/src/test/java/it/pagopa/selfcare/onboarding/service/CompletionServiceDefaultTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.microsoft.azure.functions.ExecutionContext; import io.quarkus.mongodb.panache.common.PanacheUpdate; import io.quarkus.test.InjectMock; import io.quarkus.test.junit.QuarkusTest; @@ -39,6 +40,7 @@ import java.time.LocalDateTime; import java.util.*; +import java.util.logging.Logger; import static it.pagopa.selfcare.onboarding.service.OnboardingService.USERS_FIELD_LIST; import static org.junit.jupiter.api.Assertions.*; @@ -693,6 +695,18 @@ public static Onboarding createSampleOnboarding() { return onboarding; } + @Test + void sendTestEmail() { + ExecutionContext executionContext = mock(ExecutionContext.class); + when(executionContext.getLogger()).thenReturn(Logger.getGlobal()); + + doNothing().when(notificationService).sendTestEmail(executionContext); + + completionServiceDefault.sendTestEmail(executionContext); + + Mockito.verify(notificationService, times(1)) + .sendTestEmail(executionContext); + } } diff --git a/apps/onboarding-ms/pom.xml b/apps/onboarding-ms/pom.xml index 5278afca3..51446f7f1 100644 --- a/apps/onboarding-ms/pom.xml +++ b/apps/onboarding-ms/pom.xml @@ -1,331 +1,339 @@ - - 4.0.0 - - it.pagopa.selfcare - onboarding-apps - 0.0.1 - + + 4.0.0 + + it.pagopa.selfcare + onboarding-apps + 0.0.1 + - onboarding-ms - 1.0.0-SNAPSHOT - - 3.11.0 - 1.18.28 - 1.5.5.Final - 17 - UTF-8 - UTF-8 - quarkus-bom - io.quarkus.platform - 3.11.2 - true - 3.1.2 - 0.1.18 - 2.4.1 - - + onboarding-ms + 1.0.0-SNAPSHOT + + 3.11.0 + 1.18.28 + 1.5.5.Final + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.11.2 + true + 3.1.2 + 0.1.18 + 2.4.1 + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - - - - io.quarkus - quarkus-resteasy-reactive - - - io.quarkus - quarkus-arc - - - io.quarkiverse.openapi.generator - quarkus-openapi-generator - ${quarkus-openapi-generator.version} - - - io.quarkus - quarkus-junit5 - test - - - io.quarkus - quarkus-junit5-mockito - test - - - io.rest-assured - rest-assured - test - - - io.quarkus - quarkus-test-mongodb - - - org.projectlombok - lombok - ${lombok.version} - provided - - - io.quarkus - quarkus-hibernate-validator - - - io.quarkus - quarkus-resteasy-reactive-jackson - - - io.quarkus - quarkus-rest-client-reactive-jackson - - - io.quarkus - quarkus-smallrye-health - - - org.mapstruct - mapstruct - ${mapstruct.version} - - - io.quarkus - quarkus-smallrye-jwt - - - io.quarkus - quarkus-test-security - test - - - io.quarkus - quarkus-smallrye-openapi - - - io.quarkus - quarkus-mongodb-panache - - - io.quarkus - quarkus-smallrye-context-propagation - + + io.quarkus + quarkus-resteasy-reactive + + + io.quarkus + quarkus-arc + + + io.quarkiverse.openapi.generator + quarkus-openapi-generator + ${quarkus-openapi-generator.version} + + + io.quarkus + quarkus-junit5 + test + + + io.quarkus + quarkus-junit5-mockito + test + + + io.rest-assured + rest-assured + test + + + io.quarkus + quarkus-test-mongodb + + + org.projectlombok + lombok + ${lombok.version} + provided + + + io.quarkus + quarkus-hibernate-validator + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + io.quarkus + quarkus-rest-client-reactive-jackson + + + io.quarkus + quarkus-smallrye-health + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + io.quarkus + quarkus-smallrye-jwt + + + io.quarkus + quarkus-test-security + test + + + io.quarkus + quarkus-smallrye-openapi + + + io.quarkus + quarkus-mongodb-panache + + + io.quarkus + quarkus-smallrye-context-propagation + - - io.quarkus - quarkus-panache-mock - test - - - io.quarkus - quarkus-test-hibernate-reactive-panache - test - - - io.quarkus - quarkus-jacoco - test - - - io.quarkus - quarkus-test-security-jwt - test - - - it.pagopa.selfcare - onboarding-sdk-common - ${onboarding-sdk.version} - + + io.quarkus + quarkus-panache-mock + test + + + io.quarkus + quarkus-test-hibernate-reactive-panache + test + + + io.quarkus + quarkus-jacoco + test + + + io.quarkus + quarkus-test-security-jwt + test + + + it.pagopa.selfcare + onboarding-sdk-common + ${onboarding-sdk.version} + - - it.pagopa.selfcare - onboarding-sdk-azure-storage - ${onboarding-sdk.version} - - - it.pagopa.selfcare - onboarding-sdk-product - ${onboarding-sdk.version} - + + it.pagopa.selfcare + onboarding-sdk-azure-storage + ${onboarding-sdk.version} + + + it.pagopa.selfcare + onboarding-sdk-product + ${onboarding-sdk.version} + - - - eu.europa.ec.joinup.sd-dss - dss-test - 5.12.1 - test - - - - eu.europa.ec.joinup.sd-dss - dss-utils - 5.12.1 - - - eu.europa.ec.joinup.sd-dss - dss-model - 5.12.1 - compile - - - - eu.europa.ec.joinup.sd-dss - dss-service - 5.12.1 - - - - eu.europa.ec.joinup.sd-dss - dss-tsl-validation - 5.12.1 - - - - eu.europa.ec.joinup.sd-dss - dss-utils-google-guava - 5.12.1 - - - eu.europa.ec.joinup.sd-dss - dss-pades - 5.12.1 - - - eu.europa.ec.joinup.sd-dss - dss-pades-pdfbox - 5.12.1 - - - eu.europa.ec.joinup.sd-dss - dss-cades - 5.12.1 - - - eu.europa.ec.joinup.sd-dss - dss-utils-apache-commons - 5.12.1 - - - eu.europa.ec.joinup.sd-dss - dss-crl-parser-stream - 5.12.1 - + + + eu.europa.ec.joinup.sd-dss + dss-test + 5.12.1 + test + + + + eu.europa.ec.joinup.sd-dss + dss-utils + 5.12.1 + + + eu.europa.ec.joinup.sd-dss + dss-model + 5.12.1 + compile + + + + eu.europa.ec.joinup.sd-dss + dss-service + 5.12.1 + + + + eu.europa.ec.joinup.sd-dss + dss-tsl-validation + 5.12.1 + + + + eu.europa.ec.joinup.sd-dss + dss-utils-google-guava + 5.12.1 + + + eu.europa.ec.joinup.sd-dss + dss-pades + 5.12.1 + + + eu.europa.ec.joinup.sd-dss + dss-pades-pdfbox + 5.12.1 + + + eu.europa.ec.joinup.sd-dss + dss-cades + 5.12.1 + + + eu.europa.ec.joinup.sd-dss + dss-utils-apache-commons + 5.12.1 + + + eu.europa.ec.joinup.sd-dss + dss-crl-parser-stream + 5.12.1 + - - javax.xml.bind - jaxb-api - 2.3.1 - + + javax.xml.bind + jaxb-api + 2.3.1 + - - jakarta.activation - jakarta.activation-api - 2.1.0 - - - com.sun.xml.bind - jaxb-impl - 2.3.4 - + + jakarta.activation + jakarta.activation-api + 2.1.0 + + + com.sun.xml.bind + jaxb-impl + 2.3.4 + - - - com.opencsv - opencsv - 5.7.1 - + + + com.opencsv + opencsv + 5.7.1 + + + com.github.tomakehurst + wiremock-jre8-standalone + 2.35.1 + compile + - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus.platform.version} - true - - - - build - generate-code - generate-code-tests - - - - - - maven-compiler-plugin - ${compiler-plugin.version} - - - -parameters - - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - - - org.projectlombok - lombok - ${lombok.version} - - - org.projectlombok - lombok-mapstruct-binding - 0.2.0 - - - io.quarkus - quarkus-panache-common - ${quarkus.platform.version} - - - - - - maven-failsafe-plugin - ${surefire-plugin.version} - - - - integration-test - verify - - - - ${project.build.directory}/${project.build.finalName}-runner - org.jboss.logmanager.LogManager - ${maven.home} - - - - - - - - - - native - - - native - - - - false - native - - - + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + io.quarkus + quarkus-panache-common + ${quarkus.platform.version} + + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + + native + + + native + + + + false + native + + + diff --git a/apps/onboarding-ms/src/main/docs/openapi.json b/apps/onboarding-ms/src/main/docs/openapi.json index 72c801659..acb419a35 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.json +++ b/apps/onboarding-ms/src/main/docs/openapi.json @@ -680,6 +680,60 @@ } ] } }, + "/v1/onboarding/verify" : { + "head" : { + "tags" : [ "Onboarding Controller" ], + "summary" : "Verify if the onboarded product is already onboarded for the institution", + "parameters" : [ { + "name" : "origin", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "originId", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "productId", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "subunitCode", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "taxCode", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { } + } + }, + "401" : { + "description" : "Not Authorized" + }, + "403" : { + "description" : "Not Allowed" + } + }, + "security" : [ { + "SecurityScheme" : [ ] + } ] + } + }, "/v1/onboarding/{onboardingId}" : { "get" : { "tags" : [ "Onboarding Controller" ], diff --git a/apps/onboarding-ms/src/main/docs/openapi.yaml b/apps/onboarding-ms/src/main/docs/openapi.yaml index b3d6119a9..0ef776773 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.yaml +++ b/apps/onboarding-ms/src/main/docs/openapi.yaml @@ -471,6 +471,43 @@ paths: description: Not Allowed security: - SecurityScheme: [] + /v1/onboarding/verify: + head: + tags: + - Onboarding Controller + summary: Verify if the onboarded product is already onboarded for the institution + parameters: + - name: origin + in: query + schema: + type: string + - name: originId + in: query + schema: + type: string + - name: productId + in: query + schema: + type: string + - name: subunitCode + in: query + schema: + type: string + - name: taxCode + in: query + schema: + type: string + responses: + "200": + description: OK + content: + application/json: {} + "401": + description: Not Authorized + "403": + description: Not Allowed + security: + - SecurityScheme: [] /v1/onboarding/{onboardingId}: get: tags: diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/constants/CustomError.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/constants/CustomError.java index b1866b3de..283a3b1c2 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/constants/CustomError.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/constants/CustomError.java @@ -7,6 +7,8 @@ public enum CustomError { ROLES_NOT_ADMITTED_ERROR("0034","Roles %s are not admitted for this operation"), AOO_NOT_FOUND("0000","AOO %s not found"), UO_NOT_FOUND("0000","UO %s not found"), + ONBOARDING_INFO_FILTERS_ERROR("0052", "Invalid filters parameters to retrieve onboarding info"), + INSTITUTION_NOT_ONBOARDED_BY_FILTERS("0004", "Has not been found an onboarded Institution with the provided filters"), INSTITUTION_NOT_FOUND("0000","Institution with taxCode %s origin %s originId %s subunitCode %s not found"), USERS_UPDATE_NOT_ALLOWED("0025", "Invalid users information provided"); diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/OnboardingController.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/OnboardingController.java index a60391f6f..6a854c475 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/OnboardingController.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/OnboardingController.java @@ -5,11 +5,13 @@ import io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipal; import io.smallrye.mutiny.Uni; import it.pagopa.selfcare.onboarding.common.OnboardingStatus; +import it.pagopa.selfcare.onboarding.constants.CustomError; import it.pagopa.selfcare.onboarding.controller.request.*; import it.pagopa.selfcare.onboarding.controller.response.OnboardingGet; import it.pagopa.selfcare.onboarding.controller.response.OnboardingGetResponse; import it.pagopa.selfcare.onboarding.controller.response.OnboardingResponse; import it.pagopa.selfcare.onboarding.entity.Onboarding; +import it.pagopa.selfcare.onboarding.exception.ResourceNotFoundException; import it.pagopa.selfcare.onboarding.mapper.OnboardingMapper; import it.pagopa.selfcare.onboarding.model.OnboardingGetFilters; import it.pagopa.selfcare.onboarding.service.OnboardingService; @@ -346,4 +348,23 @@ public Uni onboardingAggregationCompletion(@Valid Onboarding .onItem().transformToUni(userId -> onboardingService .onboardingAggregationCompletion(fillUserId(onboardingMapper.toEntity(onboardingRequest), userId), onboardingRequest.getUsers())); } + + @HEAD + @Path("/verify") + @Operation(summary = "Verify if the onboarded product is already onboarded for the institution") + public Uni verifyOnboardingInfoByFilters(@QueryParam("productId") String productId, + @QueryParam("taxCode") String taxCode, + @QueryParam("origin") String origin, + @QueryParam("originId") String originId, + @QueryParam("subunitCode") String subunitCode) { + return onboardingService.verifyOnboarding(taxCode, subunitCode, origin, originId, OnboardingStatus.COMPLETED, productId) + .onItem().transform(onboardingList -> { + if (onboardingList.isEmpty()) { + throw new ResourceNotFoundException(CustomError.INSTITUTION_NOT_ONBOARDED_BY_FILTERS.getMessage(), + CustomError.INSTITUTION_NOT_ONBOARDED_BY_FILTERS.getCode()); + } else { + return Response.status(HttpStatus.SC_NO_CONTENT).build(); + } + }); + } } diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java index d3f42c0bf..cf116da6e 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingService.java @@ -42,6 +42,8 @@ public interface OnboardingService { Uni> institutionOnboardings(String taxCode, String subunitCode, String origin, String originId, OnboardingStatus status); + Uni> verifyOnboarding(String taxCode, String subunitCode, String origin, String originId, OnboardingStatus status, String productId); + Uni onboardingGet(String onboardingId); Uni onboardingGetWithUserInfo(String onboardingId); @@ -49,4 +51,5 @@ public interface OnboardingService { Uni updateOnboarding(String onboardingId, Onboarding onboarding); Uni checkManager(OnboardingUserRequest onboardingUserRequest); + } diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java index d72636a43..65ac3197e 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java @@ -82,7 +82,7 @@ public class OnboardingServiceDefault implements OnboardingService { public static final String UNABLE_TO_COMPLETE_THE_ONBOARDING_FOR_INSTITUTION_FOR_PRODUCT_DISMISSED = "Unable to complete the onboarding for institution with taxCode '%s' to product '%s', the product is dismissed."; public static final String USERS_FIELD_LIST = "fiscalCode,familyName,name,workContacts"; public static final String USERS_FIELD_TAXCODE = "fiscalCode"; - public static final String TIMEOUT_ORCHESTRATION_RESPONSE = "60"; + public static final String TIMEOUT_ORCHESTRATION_RESPONSE = "65"; private static final String ID_MAIL_PREFIX = "ID_MAIL#"; @RestClient @@ -904,6 +904,16 @@ public Uni> institutionOnboardings(String taxCode, Stri .collect().asList(); } + @Override + public Uni> verifyOnboarding(String taxCode, String subunitCode, String origin, String originId, OnboardingStatus status, String productId) { + Map queryParameter = QueryUtils.createMapForVerifyOnboardingQueryParameter(taxCode, subunitCode, origin, originId, status, productId); + Document query = QueryUtils.buildQuery(queryParameter); + return Onboarding.find(query).stream() + .map(Onboarding.class::cast) + .map(onboardingMapper::toResponse) + .collect().asList(); + } + @Override public Uni onboardingGet(String onboardingId) { return Onboarding.findByIdOptional(onboardingId) diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/util/QueryUtils.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/util/QueryUtils.java index f2f2c7044..cacc15112 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/util/QueryUtils.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/util/QueryUtils.java @@ -102,6 +102,20 @@ public static Map createMapForInstitutionOnboardingsQueryParamet return queryParameterMap; } + public static Map createMapForVerifyOnboardingQueryParameter(String taxCode, String subunitCode, String origin, String originId, OnboardingStatus status, String productId) { + Map queryParameterMap = new HashMap<>(); + + Optional.ofNullable(taxCode).ifPresent(value -> queryParameterMap.put(INSTITUTION_TAX_CODE, value)); + Optional.ofNullable(origin).ifPresent(value -> queryParameterMap.put(INSTITUTION_ORIGIN, value)); + Optional.ofNullable(originId).ifPresent(value -> queryParameterMap.put(INSTITUTION_ORIGIN_ID, value)); + Optional.ofNullable(status).ifPresent(value -> queryParameterMap.put(STATUS, value.name())); + Optional.ofNullable(productId).ifPresent(value -> queryParameterMap.put(PRODUCT, value)); + + queryParameterMap.put(INSTITUTION_SUBUNIT_CODE, subunitCode); + + return queryParameterMap; + } + public static Map createMapForOnboardingReject(String reasonForReject, String onboardingStatus) { Map queryParameterMap = new HashMap<>(); Optional.ofNullable(reasonForReject).ifPresent(value -> queryParameterMap.put("reasonForReject", value)); diff --git a/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/OnboardingControllerTest.java b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/OnboardingControllerTest.java index 08466f557..901d86d17 100644 --- a/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/OnboardingControllerTest.java +++ b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/OnboardingControllerTest.java @@ -620,6 +620,48 @@ void getInstitutionOnboardings() { .institutionOnboardings("taxCode", "subunitCode", "origin", "originId", OnboardingStatus.PENDING); } + @Test + @TestSecurity(user = "userJwt") + void verifyOnboardingNoContentType() { + OnboardingResponse onboardingResponse = dummyOnboardingResponse(); + List onboardingResponses = new ArrayList<>(); + onboardingResponses.add(onboardingResponse); + when(onboardingService.verifyOnboarding("taxCode", "subunitCode", "origin", "originId", OnboardingStatus.COMPLETED, "prod-interop")) + .thenReturn(Uni.createFrom().item(onboardingResponses)); + + Map queryParameterMap = getStringStringMapOnboardings(); + + given() + .when() + .queryParams(queryParameterMap) + .head("/verify") + .then() + .statusCode(204); + + verify(onboardingService, times(1)) + .verifyOnboarding("taxCode", "subunitCode", "origin", "originId", OnboardingStatus.COMPLETED, "prod-interop"); + } + + @Test + @TestSecurity(user = "userJwt") + void verifyOnboardingResourceNotFound() { + List onboardingResponses = new ArrayList<>(); + when(onboardingService.verifyOnboarding("taxCode", "subunitCode", "origin", "originId", OnboardingStatus.COMPLETED, "prod-interop")) + .thenReturn(Uni.createFrom().item(onboardingResponses)); + + Map queryParameterMap = getStringStringMapOnboardings(); + + given() + .when() + .queryParams(queryParameterMap) + .head("/verify") + .then() + .statusCode(404); + + verify(onboardingService, times(1)) + .verifyOnboarding("taxCode", "subunitCode", "origin", "originId", OnboardingStatus.COMPLETED, "prod-interop"); + } + private static Map getStringStringMap() { Map queryParameterMap = new HashMap<>(); queryParameterMap.put("productId", "prod-io"); @@ -637,6 +679,7 @@ private static Map getStringStringMapOnboardings() { queryParameterMap.put("origin", "origin"); queryParameterMap.put("originId", "originId"); queryParameterMap.put("status", "PENDING"); + queryParameterMap.put("productId", "prod-interop"); return queryParameterMap; } diff --git a/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java index 2e3803674..293b0d77b 100644 --- a/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java +++ b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java @@ -1581,6 +1581,23 @@ void testInstitutionOnboardings() { assertEquals(1, response.size()); } + @Test + void testVerifyOnboardingNonEmptyList() { + Onboarding onboarding = mock(Onboarding.class); + PanacheMock.mock(Onboarding.class); + ReactivePanacheQuery query = Mockito.mock(ReactivePanacheQuery.class); + when(query.stream()).thenReturn(Multi.createFrom().item(onboarding)); + when(Onboarding.find(any())).thenReturn(query); + UniAssertSubscriber> subscriber = onboardingService + .verifyOnboarding("taxCode", "subunitCode", "origin", "originId", OnboardingStatus.COMPLETED, "prod-interop") + .subscribe() + .withSubscriber(UniAssertSubscriber.create()); + + List response = subscriber.assertCompleted().awaitItem().getItem(); + assertFalse(response.isEmpty()); + assertEquals(1, response.size()); + } + @Nested @TestProfile(OnboardingTestProfile.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) diff --git a/infra/container_apps/hub_spid_login/env/uat/terraform.tfvars b/infra/container_apps/hub_spid_login/env/uat/terraform.tfvars index cc046da4d..a814584a2 100644 --- a/infra/container_apps/hub_spid_login/env/uat/terraform.tfvars +++ b/infra/container_apps/hub_spid_login/env/uat/terraform.tfvars @@ -1,7 +1,7 @@ prefix = "selc" env_short = "u" -suffix_increment = "-001" -cae_name = "cae-001" +suffix_increment = "-002" +cae_name = "cae-002" tags = { CreatedBy = "Terraform" diff --git a/infra/container_apps/onboarding-cdc/env/uat/terraform.tfvars b/infra/container_apps/onboarding-cdc/env/uat/terraform.tfvars index 0f508486a..41e72a8d0 100644 --- a/infra/container_apps/onboarding-cdc/env/uat/terraform.tfvars +++ b/infra/container_apps/onboarding-cdc/env/uat/terraform.tfvars @@ -1,7 +1,7 @@ prefix = "selc" env_short = "u" -suffix_increment = "-001" -cae_name = "cae-001" +suffix_increment = "-002" +cae_name = "cae-002" tags = { CreatedBy = "Terraform" diff --git a/infra/container_apps/onboarding-ms/env/uat/terraform.tfvars b/infra/container_apps/onboarding-ms/env/uat/terraform.tfvars index a884019c3..259ef3662 100644 --- a/infra/container_apps/onboarding-ms/env/uat/terraform.tfvars +++ b/infra/container_apps/onboarding-ms/env/uat/terraform.tfvars @@ -1,7 +1,7 @@ prefix = "selc" env_short = "u" -suffix_increment = "-001" -cae_name = "cae-001" +suffix_increment = "-002" +cae_name = "cae-002" tags = { CreatedBy = "Terraform" diff --git a/infra/functions/onboarding-functions/env/dev/terraform.tfvars b/infra/functions/onboarding-functions/env/dev/terraform.tfvars index e14bb7af4..212b4208d 100644 --- a/infra/functions/onboarding-functions/env/dev/terraform.tfvars +++ b/infra/functions/onboarding-functions/env/dev/terraform.tfvars @@ -53,6 +53,7 @@ app_settings = { "MAIL_SERVER_PASSWORD" = "@Microsoft.KeyVault(SecretUri=https://selc-d-kv.vault.azure.net/secrets/smtp-psw/)", "MAIL_SERVER_HOST" = "smtps.pec.aruba.it", "MAIL_SERVER_PORT" = "465", + "MAIL_SERVER_SSL" = "false" "MAIL_TEMPLATE_REGISTRATION_NOTIFICATION_ADMIN_PATH" = "contracts/template/mail/registration-notification-admin/1.0.0.json", "MAIL_TEMPLATE_NOTIFICATION_PATH" = "contracts/template/mail/onboarding-notification/1.0.0.json", "ADDRESS_EMAIL_NOTIFICATION_ADMIN" = "@Microsoft.KeyVault(SecretUri=https://selc-d-kv.vault.azure.net/secrets/portal-admin-operator-email/)", diff --git a/infra/functions/onboarding-functions/env/uat/terraform.tfvars b/infra/functions/onboarding-functions/env/uat/terraform.tfvars index 306ef4583..030bd6eb5 100644 --- a/infra/functions/onboarding-functions/env/uat/terraform.tfvars +++ b/infra/functions/onboarding-functions/env/uat/terraform.tfvars @@ -74,10 +74,10 @@ app_settings = { "MAIL_USER_CONFIRMATION_LINK" = "https://uat.selfcare.pagopa.it/onboarding/confirm?add-user=true&jwt=", "MAIL_ONBOARDING_REJECTION_LINK" = "https://uat.selfcare.pagopa.it/onboarding/cancel?jwt=", "MAIL_ONBOARDING_URL" = "https://uat.selfcare.pagopa.it/onboarding/", - "MS_CORE_URL" = "https://selc-u-ms-core-ca.proudglacier-20652b81.westeurope.azurecontainerapps.io", + "MS_CORE_URL" = "https://selc-u-ms-core-ca.mangopond-2a5d4d65.westeurope.azurecontainerapps.io", "JWT_BEARER_TOKEN" = "@Microsoft.KeyVault(SecretUri=https://selc-u-kv.vault.azure.net/secrets/jwt-bearer-token-functions/)", - "MS_USER_URL" = "https://selc-u-user-ms-ca.proudglacier-20652b81.westeurope.azurecontainerapps.io", - "MS_PARTY_REGISTRY_URL" = "https://selc-u-party-reg-proxy-ca.proudglacier-20652b81.westeurope.azurecontainerapps.io", + "MS_USER_URL" = "https://selc-u-user-ms-ca.mangopond-2a5d4d65.westeurope.azurecontainerapps.io", + "MS_PARTY_REGISTRY_URL" = "https://selc-u-party-reg-proxy-ca.mangopond-2a5d4d65.westeurope.azurecontainerapps.io", "USER_MS_SEND_MAIL" = "false", "EVENT_HUB_BASE_PATH" = "https://selc-u-eventhub-ns.servicebus.windows.net", "STANDARD_SHARED_ACCESS_KEY_NAME" = "selfcare-wo"