From b41c60c84bd872aecdd64ab8b82120744fc487e1 Mon Sep 17 00:00:00 2001 From: pierpaolodidato89 <137791912+pierpaolodidato89@users.noreply.github.com> Date: Mon, 1 Jul 2024 08:45:21 +0200 Subject: [PATCH 1/6] [SELC-5149] feat: Fix execution pending state for completion workflow (#370) Co-authored-by: pierpaolo.didato@emeal.nttdata.com --- .../selfcare/onboarding/workflow/WorkflowExecutor.java | 7 ++++--- .../onboarding/workflow/WorkflowExecutorConfirmation.java | 2 +- .../workflow/WorkflowExecutorContractRegistration.java | 2 +- .../WorkflowExecutorContractRegistrationAggregator.java | 2 +- .../onboarding/workflow/WorkflowExecutorForApprove.java | 2 +- .../onboarding/workflow/WorkflowExecutorForApprovePt.java | 2 +- apps/onboarding-ms/src/main/docs/openapi.json | 2 +- apps/onboarding-ms/src/main/docs/openapi.yaml | 1 + 8 files changed, 11 insertions(+), 9 deletions(-) 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 8a90f746f..972999183 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 @@ -71,9 +71,10 @@ default void createTestEnvironmentsOnboarding(TaskOrchestrationContext ctx, Onbo } } - default Optional onboardingCompletionActivity(TaskOrchestrationContext ctx, Onboarding onboarding) { - String onboardingWithInstitutionIdString = createInstitutionAndOnboarding(ctx, onboarding); - ctx.callActivity(SEND_MAIL_COMPLETION_ACTIVITY, onboardingWithInstitutionIdString, optionsRetry(), String.class).await(); + default Optional onboardingCompletionActivity(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { + Onboarding onboarding = onboardingWorkflow.getOnboarding(); + createInstitutionAndOnboarding(ctx, onboarding); + ctx.callActivity(SEND_MAIL_COMPLETION_ACTIVITY, getOnboardingWorkflowString(objectMapper(), onboardingWorkflow), 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 f88231dbe..a8620f49d 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 @@ -27,7 +27,7 @@ public Optional executeToBeValidatedState(TaskOrchestrationCon @Override public Optional executePendingState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { - return onboardingCompletionActivity(ctx, onboardingWorkflow.getOnboarding()); + return onboardingCompletionActivity(ctx, onboardingWorkflow); } @Override diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistration.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistration.java index 9827a7723..ec2c32991 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistration.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistration.java @@ -32,7 +32,7 @@ public Optional executeToBeValidatedState(TaskOrchestrationCon @Override public Optional executePendingState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { - return onboardingCompletionActivity(ctx, onboardingWorkflow.getOnboarding()); + return onboardingCompletionActivity(ctx, onboardingWorkflow); } @Override diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java index 537918a08..ea0c643dd 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java @@ -34,7 +34,7 @@ public Optional executeToBeValidatedState(TaskOrchestrationCon @Override public Optional executePendingState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { - return onboardingCompletionActivity(ctx, onboardingWorkflow.getOnboarding()); + return onboardingCompletionActivity(ctx, onboardingWorkflow); } @Override diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprove.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprove.java index 4fe21543b..6c53420ac 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprove.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprove.java @@ -35,7 +35,7 @@ public Optional executeToBeValidatedState(TaskOrchestrationCon @Override public Optional executePendingState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { - return onboardingCompletionActivity(ctx, onboardingWorkflow.getOnboarding()); + return onboardingCompletionActivity(ctx, onboardingWorkflow); } @Override diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprovePt.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprovePt.java index 3de3fcec2..80911b2db 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprovePt.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorForApprovePt.java @@ -27,7 +27,7 @@ public Optional executeRequestState(TaskOrchestrationContext c @Override public Optional executeToBeValidatedState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { - return onboardingCompletionActivity(ctx, onboardingWorkflow.getOnboarding()); + return onboardingCompletionActivity(ctx, onboardingWorkflow); } @Override diff --git a/apps/onboarding-ms/src/main/docs/openapi.json b/apps/onboarding-ms/src/main/docs/openapi.json index 10afe7944..a3820271e 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.json +++ b/apps/onboarding-ms/src/main/docs/openapi.json @@ -1936,7 +1936,7 @@ } }, "TokenType" : { - "enum" : [ "INSTITUTION", "LEGALS" ], + "enum" : [ "INSTITUTION", "LEGALS", "USER" ], "type" : "string" }, "UserOnboardingResponse" : { diff --git a/apps/onboarding-ms/src/main/docs/openapi.yaml b/apps/onboarding-ms/src/main/docs/openapi.yaml index cff752774..c8a6af6f8 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.yaml +++ b/apps/onboarding-ms/src/main/docs/openapi.yaml @@ -1409,6 +1409,7 @@ components: enum: - INSTITUTION - LEGALS + - USER type: string UserOnboardingResponse: type: object From b3ca3fa1bf43ef19996c3b4b376ba6e2405d9739 Mon Sep 17 00:00:00 2001 From: andrea-putzu <106688558+andrea-putzu@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:05:43 +0200 Subject: [PATCH 2/6] [SELC-4448] Migrating IP from AKS to FN (#374) --- .../env/uat/terraform.tfvars | 2 +- .../onboarding-functions/functions.tf | 25 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/infra/functions/onboarding-functions/env/uat/terraform.tfvars b/infra/functions/onboarding-functions/env/uat/terraform.tfvars index 19e39737b..33452ed12 100644 --- a/infra/functions/onboarding-functions/env/uat/terraform.tfvars +++ b/infra/functions/onboarding-functions/env/uat/terraform.tfvars @@ -92,7 +92,7 @@ app_settings = { "SAP_ALLOWED_ORIGINS" = "IPA,SELC" "MINUTES_THRESHOLD_FOR_UPDATE_NOTIFICATION" = "5" "BYPASS_CHECK_ORGANIZATION" = "false" - "PROD_FD_URL" = "https://fid00001fe.siachain.sv.sia.eu:30008" + "PROD_FD_URL" = "https://fid00001fe.siachain.ti.sia.eu:30008" "FD_TOKEN_GRANT_TYPE" = "@Microsoft.KeyVault(SecretUri=https://selc-u-kv.vault.azure.net/secrets/prod-fd-grant-type/)" "FD_TOKEN_CLIENT_ID" = "@Microsoft.KeyVault(SecretUri=https://selc-u-kv.vault.azure.net/secrets/prod-fd-client-id/)" "FD_TOKEN_CLIENT_SECRET" = "@Microsoft.KeyVault(SecretUri=https://selc-u-kv.vault.azure.net/secrets/prod-fd-client-secret/)" diff --git a/infra/functions/onboarding-functions/functions.tf b/infra/functions/onboarding-functions/functions.tf index 8dcba085f..0eb81d880 100644 --- a/infra/functions/onboarding-functions/functions.tf +++ b/infra/functions/onboarding-functions/functions.tf @@ -63,22 +63,37 @@ resource "azurerm_key_vault_access_policy" "keyvault_functions_access_policy" { } data "azurerm_resource_group" "nat_rg" { - name = "${local.base_domain_name}-nat-rg" + name = "${local.base_domain_name}-nat-rg" } -data "azurerm_public_ip" "functions_pip_outboud" { +data "azurerm_resource_group" "vnet_rg" { + name = "${local.base_domain_name}-vnet-rg" +} + + +data "azurerm_public_ip" "aks_pip_outbound" { + resource_group_name = data.azurerm_resource_group.vnet_rg.name + name = "${local.base_domain_name}-aksoutbound-pip-01" //selc-d-aksoutbound-pip-01 +} + +data "azurerm_public_ip" "pip_outbound" { + resource_group_name = data.azurerm_resource_group.nat_rg.name + name = "${local.base_domain_name}-pip-outbound" //selc-d-pip-outbound +} + +data "azurerm_public_ip" "functions_pip_outbound" { resource_group_name = data.azurerm_resource_group.nat_rg.name - name = "${local.app_name}-pip-outbound" + name = "${local.app_name}-pip-outbound" //selc-d-onboarding-fn-pip-outbound } data "azurerm_nat_gateway" "nat_gateway" { - name = "${local.base_domain_name}-nat_gw" + name = "${local.base_domain_name}-nat_gw" //selc-d-nat_gw resource_group_name = data.azurerm_resource_group.nat_rg.name } resource "azurerm_nat_gateway_public_ip_association" "functions_pip_nat_gateway" { nat_gateway_id = data.azurerm_nat_gateway.nat_gateway.id - public_ip_address_id = data.azurerm_public_ip.functions_pip_outboud.id + public_ip_address_id = var.is_pnpg == true ? data.azurerm_public_ip.functions_pip_outbound.id : data.azurerm_public_ip.aks_pip_outbound.id } resource "azurerm_subnet_nat_gateway_association" "functions_subnet_nat_gateway" { From 79eee7c33a7cc5c11e96d80ac95908455a4f5539 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo <113031535+flaminiaScarciofolo@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:54:09 +0200 Subject: [PATCH 3/6] [SELC-5116] Feat: Added API to verify aggregatesCsv (#357) --- apps/onboarding-ms/pom.xml | 10 +- apps/onboarding-ms/src/main/docs/openapi.json | 192 ++++++++++++++++++ apps/onboarding-ms/src/main/docs/openapi.yaml | 129 ++++++++++++ .../controller/AggregatesController.java | 41 ++++ .../onboarding/mapper/OnboardingMapper.java | 6 + .../model/AggregatesCsvResponse.java | 40 ++++ .../onboarding/model/CsvAggregate.java | 27 +++ .../selfcare/onboarding/model/RowError.java | 41 ++++ .../model/VerifyAggregateResponse.java | 18 ++ .../onboarding/service/AggregatesService.java | 12 ++ .../service/AggregatesServiceDefault.java | 179 ++++++++++++++++ .../onboarding/service/OnboardingService.java | 4 +- .../controller/AggregatesControllerTest.java | 48 +++++ .../service/AggregatesServiceDefaultTest.java | 67 ++++++ .../src/test/resources/aggregates.csv | 10 + 15 files changed, 818 insertions(+), 6 deletions(-) create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/AggregatesController.java create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/AggregatesCsvResponse.java create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/CsvAggregate.java create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/RowError.java create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/VerifyAggregateResponse.java create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesService.java create mode 100644 apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefault.java create mode 100644 apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/AggregatesControllerTest.java create mode 100644 apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefaultTest.java create mode 100644 apps/onboarding-ms/src/test/resources/aggregates.csv diff --git a/apps/onboarding-ms/pom.xml b/apps/onboarding-ms/pom.xml index 206845919..40fcd3c8e 100644 --- a/apps/onboarding-ms/pom.xml +++ b/apps/onboarding-ms/pom.xml @@ -236,14 +236,14 @@ jaxb-impl 2.3.4 + + - it.pagopa.selfcare - onboarding-sdk-common - 0.1.16 - compile + com.opencsv + opencsv + 5.7.1 - diff --git a/apps/onboarding-ms/src/main/docs/openapi.json b/apps/onboarding-ms/src/main/docs/openapi.json index a3820271e..db7b5ef3b 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.json +++ b/apps/onboarding-ms/src/main/docs/openapi.json @@ -12,6 +12,8 @@ "description" : "Auto generated value" } ], "tags" : [ { + "name" : "Aggregates Controller" + }, { "name" : "Notification Controller" }, { "name" : "Onboarding" @@ -21,6 +23,49 @@ "name" : "support" } ], "paths" : { + "/v1/aggregates/verification" : { + "post" : { + "tags" : [ "Aggregates Controller" ], + "summary" : "", + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "required" : [ "aggregates" ], + "type" : "object", + "properties" : { + "aggregates" : { + "format" : "binary", + "type" : "string" + } + } + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/VerifyAggregateResponse" + } + } + } + }, + "401" : { + "description" : "Not Authorized" + }, + "403" : { + "description" : "Not Allowed" + } + }, + "security" : [ { + "SecurityScheme" : [ ] + } ] + } + }, "/v1/notification/resend" : { "post" : { "tags" : [ "Notification Controller" ], @@ -1149,6 +1194,20 @@ } } }, + "DataProtectionOfficer" : { + "type" : "object", + "properties" : { + "address" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "pec" : { + "type" : "string" + } + } + }, "DataProtectionOfficerRequest" : { "type" : "object", "properties" : { @@ -1185,6 +1244,86 @@ } } }, + "Institution" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "institutionType" : { + "$ref" : "#/components/schemas/InstitutionType" + }, + "taxCode" : { + "type" : "string" + }, + "subunitCode" : { + "type" : "string" + }, + "subunitType" : { + "$ref" : "#/components/schemas/InstitutionPaSubunitType" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "originId" : { + "type" : "string" + }, + "city" : { + "type" : "string" + }, + "country" : { + "type" : "string" + }, + "county" : { + "type" : "string" + }, + "description" : { + "type" : "string" + }, + "digitalAddress" : { + "type" : "string" + }, + "address" : { + "type" : "string" + }, + "zipCode" : { + "type" : "string" + }, + "geographicTaxonomies" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/GeographicTaxonomy" + } + }, + "rea" : { + "type" : "string" + }, + "shareCapital" : { + "type" : "string" + }, + "businessRegisterPlace" : { + "type" : "string" + }, + "supportEmail" : { + "type" : "string" + }, + "supportPhone" : { + "type" : "string" + }, + "imported" : { + "type" : "boolean" + }, + "paymentServiceProvider" : { + "$ref" : "#/components/schemas/PaymentServiceProvider" + }, + "dataProtectionOfficer" : { + "$ref" : "#/components/schemas/DataProtectionOfficer" + }, + "parentDescription" : { + "type" : "string" + } + } + }, "InstitutionBaseRequest" : { "required" : [ "institutionType", "digitalAddress" ], "type" : "object", @@ -1869,6 +2008,26 @@ "enum" : [ "MANAGER", "DELEGATE", "SUB_DELEGATE", "OPERATOR", "ADMIN_EA" ], "type" : "string" }, + "PaymentServiceProvider" : { + "type" : "object", + "properties" : { + "abiCode" : { + "type" : "string" + }, + "businessRegisterNumber" : { + "type" : "string" + }, + "legalRegisterNumber" : { + "type" : "string" + }, + "legalRegisterName" : { + "type" : "string" + }, + "vatNumberGroup" : { + "type" : "boolean" + } + } + }, "PaymentServiceProviderRequest" : { "type" : "object", "properties" : { @@ -1897,6 +2056,22 @@ } } }, + "RowError" : { + "required" : [ "row", "cf" ], + "type" : "object", + "properties" : { + "row" : { + "format" : "int32", + "type" : "integer" + }, + "cf" : { + "type" : "string" + }, + "reason" : { + "type" : "string" + } + } + }, "TokenResponse" : { "type" : "object", "properties" : { @@ -2001,6 +2176,23 @@ "type" : "string" } } + }, + "VerifyAggregateResponse" : { + "type" : "object", + "properties" : { + "aggregates" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Institution" + } + }, + "errors" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/RowError" + } + } + } } }, "securitySchemes" : { diff --git a/apps/onboarding-ms/src/main/docs/openapi.yaml b/apps/onboarding-ms/src/main/docs/openapi.yaml index c8a6af6f8..ec8212e46 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.yaml +++ b/apps/onboarding-ms/src/main/docs/openapi.yaml @@ -9,11 +9,41 @@ servers: - url: http://0.0.0.0:8080 description: Auto generated value tags: +- name: Aggregates Controller - name: Notification Controller - name: Onboarding - name: Onboarding Controller - name: support paths: + /v1/aggregates/verification: + post: + tags: + - Aggregates Controller + summary: "" + requestBody: + content: + multipart/form-data: + schema: + required: + - aggregates + type: object + properties: + aggregates: + format: binary + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/VerifyAggregateResponse" + "401": + description: Not Authorized + "403": + description: Not Allowed + security: + - SecurityScheme: [] /v1/notification/resend: post: tags: @@ -812,6 +842,15 @@ components: type: string publicServices: type: boolean + DataProtectionOfficer: + type: object + properties: + address: + type: string + email: + type: string + pec: + type: string DataProtectionOfficerRequest: type: object properties: @@ -835,6 +874,59 @@ components: type: string desc: type: string + Institution: + type: object + properties: + id: + type: string + institutionType: + $ref: "#/components/schemas/InstitutionType" + taxCode: + type: string + subunitCode: + type: string + subunitType: + $ref: "#/components/schemas/InstitutionPaSubunitType" + origin: + $ref: "#/components/schemas/Origin" + originId: + type: string + city: + type: string + country: + type: string + county: + type: string + description: + type: string + digitalAddress: + type: string + address: + type: string + zipCode: + type: string + geographicTaxonomies: + type: array + items: + $ref: "#/components/schemas/GeographicTaxonomy" + rea: + type: string + shareCapital: + type: string + businessRegisterPlace: + type: string + supportEmail: + type: string + supportPhone: + type: string + imported: + type: boolean + paymentServiceProvider: + $ref: "#/components/schemas/PaymentServiceProvider" + dataProtectionOfficer: + $ref: "#/components/schemas/DataProtectionOfficer" + parentDescription: + type: string InstitutionBaseRequest: required: - institutionType @@ -1362,6 +1454,19 @@ components: - OPERATOR - ADMIN_EA type: string + PaymentServiceProvider: + type: object + properties: + abiCode: + type: string + businessRegisterNumber: + type: string + legalRegisterNumber: + type: string + legalRegisterName: + type: string + vatNumberGroup: + type: boolean PaymentServiceProviderRequest: type: object properties: @@ -1380,6 +1485,19 @@ components: properties: reasonForReject: type: string + RowError: + required: + - row + - cf + type: object + properties: + row: + format: int32 + type: integer + cf: + type: string + reason: + type: string TokenResponse: type: object properties: @@ -1452,6 +1570,17 @@ components: $ref: "#/components/schemas/PartyRole" productRole: type: string + VerifyAggregateResponse: + type: object + properties: + aggregates: + type: array + items: + $ref: "#/components/schemas/Institution" + errors: + type: array + items: + $ref: "#/components/schemas/RowError" securitySchemes: SecurityScheme: type: http diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/AggregatesController.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/AggregatesController.java new file mode 100644 index 000000000..29060608d --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/AggregatesController.java @@ -0,0 +1,41 @@ +package it.pagopa.selfcare.onboarding.controller; + +import io.quarkus.security.Authenticated; +import io.smallrye.mutiny.Uni; +import it.pagopa.selfcare.onboarding.model.VerifyAggregateResponse; +import it.pagopa.selfcare.onboarding.service.AggregatesService; +import jakarta.inject.Inject; +import jakarta.validation.constraints.NotNull; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import lombok.AllArgsConstructor; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; +import org.jboss.resteasy.reactive.RestForm; + +import java.io.File; + +@Authenticated +@Path("/v1/aggregates") +@Tag(name = "Aggregates Controller") +@AllArgsConstructor +public class AggregatesController { + + @Inject + AggregatesService aggregatesService; + + @Operation(summary = "Validate the data related to the aggregated entities present in a CSV file") + @POST + @Path("/verification") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Uni verifyAggregatesCsv(@NotNull @RestForm("aggregates") File file){ + + return aggregatesService.validateAggregatesCsv(file); + } + + +} diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java index 7de920945..d1026d56b 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java @@ -7,6 +7,8 @@ import it.pagopa.selfcare.onboarding.controller.response.OnboardingResponse; import it.pagopa.selfcare.onboarding.entity.Onboarding; import it.pagopa.selfcare.onboarding.entity.User; +import it.pagopa.selfcare.onboarding.model.AggregatesCsvResponse; +import it.pagopa.selfcare.onboarding.model.VerifyAggregateResponse; import org.mapstruct.Context; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -113,4 +115,8 @@ default OffsetDateTime toOffsetDateTime(java.time.LocalDateTime localDateTime) { return localDateTime.atOffset(java.time.ZoneOffset.UTC); } + + @Mapping(target = "errors", source = "rowErrorList") + @Mapping(target = "aggregates", source = "validAggregates") + VerifyAggregateResponse toVerifyAggregateResponse(AggregatesCsvResponse aggregatesCsvResponse); } diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/AggregatesCsvResponse.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/AggregatesCsvResponse.java new file mode 100644 index 000000000..ab7bc9978 --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/AggregatesCsvResponse.java @@ -0,0 +1,40 @@ +package it.pagopa.selfcare.onboarding.model; + +import java.util.ArrayList; +import java.util.List; + +public class AggregatesCsvResponse { + private List csvAggregateList; + private List validAggregates = new ArrayList<>(); + private List rowErrorList; + + public AggregatesCsvResponse(List csvAggregateList, List rowErrorList) { + this.csvAggregateList = csvAggregateList; + this.rowErrorList = rowErrorList; + } + + public List getCsvAggregateList() { + return csvAggregateList; + } + + public void setCsvAggregateList(List csvAggregateList) { + this.csvAggregateList = csvAggregateList; + } + + public List getValidAggregates() { + return validAggregates; + } + + public void setValidAggregates(List validAggregates) { + this.validAggregates = validAggregates; + } + + public List getRowErrorList() { + return rowErrorList; + } + + public void setRowErrorList(List rowErrorList) { + this.rowErrorList = rowErrorList; + } + +} diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/CsvAggregate.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/CsvAggregate.java new file mode 100644 index 000000000..12f734b72 --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/CsvAggregate.java @@ -0,0 +1,27 @@ +package it.pagopa.selfcare.onboarding.model; + +import com.opencsv.bean.CsvBindByPosition; +import lombok.Data; + +@Data +public class CsvAggregate { + + @CsvBindByPosition(position = 0) + private String taxCode; + @CsvBindByPosition(position = 1) + private String description; + @CsvBindByPosition(position = 2) + private String subunitCode; + @CsvBindByPosition(position = 3) + private String subunitType; + @CsvBindByPosition(position = 4) + private String geoTaxonomy; + @CsvBindByPosition(position = 5) + private String address; + @CsvBindByPosition(position = 6) + private String originId; + + private Integer rowNumber; + + +} diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/RowError.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/RowError.java new file mode 100644 index 000000000..7661f0556 --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/RowError.java @@ -0,0 +1,41 @@ +package it.pagopa.selfcare.onboarding.model; + +import jakarta.validation.constraints.NotNull; + +public class RowError { + @NotNull + private Integer row; + @NotNull + private String cf; + private String reason; + + public RowError(Integer row, String cf, String reason) { + this.row = row; + this.cf = cf; + this.reason = reason; + } + + public Integer getRow() { + return row; + } + + public void setRow(Integer row) { + this.row = row; + } + + public String getCf() { + return cf; + } + + public void setCf(String cf) { + this.cf = cf; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } +} diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/VerifyAggregateResponse.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/VerifyAggregateResponse.java new file mode 100644 index 000000000..e8a032d80 --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/model/VerifyAggregateResponse.java @@ -0,0 +1,18 @@ +package it.pagopa.selfcare.onboarding.model; + +import it.pagopa.selfcare.onboarding.entity.Institution; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class VerifyAggregateResponse { + + private List aggregates; + private List errors; + +} diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesService.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesService.java new file mode 100644 index 000000000..ffbe3506e --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesService.java @@ -0,0 +1,12 @@ +package it.pagopa.selfcare.onboarding.service; + +import io.smallrye.mutiny.Uni; +import it.pagopa.selfcare.onboarding.common.InstitutionType; +import it.pagopa.selfcare.onboarding.model.VerifyAggregateResponse; + +import java.io.File; + +public interface AggregatesService { + + Uni validateAggregatesCsv(File file); +} diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefault.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefault.java new file mode 100644 index 000000000..37d2231cc --- /dev/null +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefault.java @@ -0,0 +1,179 @@ +package it.pagopa.selfcare.onboarding.service; + +import com.opencsv.bean.CsvToBean; +import com.opencsv.bean.CsvToBeanBuilder; +import com.opencsv.enums.CSVReaderNullFieldIndicator; +import io.smallrye.mutiny.Multi; +import io.smallrye.mutiny.Uni; +import it.pagopa.selfcare.onboarding.exception.InvalidRequestException; +import it.pagopa.selfcare.onboarding.exception.ResourceNotFoundException; +import it.pagopa.selfcare.onboarding.mapper.OnboardingMapper; +import it.pagopa.selfcare.onboarding.model.AggregatesCsvResponse; +import it.pagopa.selfcare.onboarding.model.CsvAggregate; +import it.pagopa.selfcare.onboarding.model.RowError; +import it.pagopa.selfcare.onboarding.model.VerifyAggregateResponse; +import it.pagopa.selfcare.onboarding.util.InstitutionPaSubunitType; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.jboss.logging.Logger; +import org.openapi.quarkus.party_registry_proxy_json.api.AooApi; +import org.openapi.quarkus.party_registry_proxy_json.api.InstitutionApi; +import org.openapi.quarkus.party_registry_proxy_json.api.UoApi; + +import java.io.BufferedReader; +import java.io.File; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +import static com.opencsv.ICSVParser.DEFAULT_QUOTE_CHARACTER; + +@ApplicationScoped +@Slf4j +public class AggregatesServiceDefault implements AggregatesService{ + + private static final Logger LOG = Logger.getLogger(AggregatesServiceDefault.class); + + @Inject + OnboardingMapper onboardingMapper; + + @RestClient + @Inject + AooApi aooApi; + + @RestClient + @Inject + InstitutionApi institutionApi; + + @RestClient + @Inject + UoApi uoApi; + + public static final String ERROR_READING_CSV = "Error reading CSV: "; + public static final String MALFORMED_ROW = "Riga malformata"; + public static final String ERROR_IPA = "Codice fiscale non presente su IPA"; + public static final String ERROR_TAXCODE = "Il codice fiscale è obbligatorio"; + public static final String ERROR_DESCRIPTION = "La ragione sociale è obbligatoria"; + public static final String ERROR_SUBUNIT_TYPE = "SubunitType non valido"; + + @Override + public Uni validateAggregatesCsv(File file){ + AggregatesCsvResponse aggregatesCsvResponse = readItemsFromCsv(file); + List csvAggregates = aggregatesCsvResponse.getCsvAggregateList(); + return Multi.createFrom().iterable(csvAggregates) + .onItem().transformToUniAndMerge(csvAggregate -> checkCsvAggregateAndFillAggregateOrErrorList(csvAggregate, aggregatesCsvResponse)) + .collect().asList() + .onItem().transform(list -> onboardingMapper.toVerifyAggregateResponse(aggregatesCsvResponse)) + .onItem().invoke(() -> LOG.infof("CSV file validated end: %s valid row and %s invalid row", + aggregatesCsvResponse.getValidAggregates().size(), + aggregatesCsvResponse.getRowErrorList().size())); + } + + private Uni checkCsvAggregateAndFillAggregateOrErrorList(CsvAggregate csvAggregate, AggregatesCsvResponse aggregatesCsvResponse) { + return checkCsvAggregate(csvAggregate) + .onItem().invoke(() -> aggregatesCsvResponse.getValidAggregates().add(csvAggregate)) + .onFailure(ResourceNotFoundException.class).recoverWithUni(throwable -> mapToErrorRow(csvAggregate, throwable, aggregatesCsvResponse)) + .onFailure(InvalidRequestException.class).recoverWithUni(throwable -> mapToErrorRow(csvAggregate, throwable, aggregatesCsvResponse)); + } + + private static Uni mapToErrorRow(CsvAggregate csvAggregate, Throwable throwable, AggregatesCsvResponse aggregatesCsvResponse) { + aggregatesCsvResponse.getRowErrorList().add(new RowError(csvAggregate.getRowNumber(), "", throwable.getMessage())); + return Uni.createFrom().voidItem(); + } + + private Uni checkCsvAggregate(CsvAggregate csvAggregate) { + return checkRequiredFields(csvAggregate) + .onItem().transformToUni(unused -> checkSubunitType(csvAggregate)); + } + + private Uni checkSubunitType(CsvAggregate csvAggregate) { + if (StringUtils.isEmpty(csvAggregate.getSubunitType())) { + return institutionApi.findInstitutionUsingGET(csvAggregate.getTaxCode(), null, null) + .onFailure(this::checkIfNotFound).recoverWithUni(Uni.createFrom().failure(new ResourceNotFoundException(ERROR_IPA))) + .replaceWith(Uni.createFrom().voidItem()); + } else if (InstitutionPaSubunitType.AOO.name().equals(csvAggregate.getSubunitType())) { + return aooApi.findByUnicodeUsingGET(csvAggregate.getSubunitCode(), null) + .onFailure(this::checkIfNotFound).recoverWithUni(Uni.createFrom().failure(new ResourceNotFoundException(ERROR_IPA))) + .replaceWith(Uni.createFrom().voidItem()); + } else if (InstitutionPaSubunitType.UO.name().equals(csvAggregate.getSubunitType())) { + return uoApi.findByUnicodeUsingGET1(csvAggregate.getSubunitCode(), null) + .onFailure(this::checkIfNotFound).recoverWithUni(Uni.createFrom().failure(new ResourceNotFoundException(ERROR_IPA))) + .replaceWith(Uni.createFrom().voidItem()); + } else { + return Uni.createFrom().failure(new InvalidRequestException(ERROR_SUBUNIT_TYPE)); + } + } + + private boolean checkIfNotFound(Throwable throwable) { + return throwable instanceof WebApplicationException webApplicationException && webApplicationException.getResponse().getStatus() == 404; + } + + private Uni checkRequiredFields(CsvAggregate csvAggregate) { + if (StringUtils.isEmpty(csvAggregate.getTaxCode())) { + return Uni.createFrom().failure(new InvalidRequestException(ERROR_TAXCODE)); + } else if (StringUtils.isEmpty(csvAggregate.getDescription())) { + return Uni.createFrom().failure(new InvalidRequestException(ERROR_DESCRIPTION)); + } + return Uni.createFrom().voidItem(); + } + + public AggregatesCsvResponse readItemsFromCsv(File file) { + List resultList = new ArrayList<>(); + List errors = new ArrayList<>(); + + try { + byte[] fileBytes = Files.readAllBytes(file.toPath()); + StringReader stringReader = new StringReader(new String(fileBytes, StandardCharsets.UTF_8)); + BufferedReader bufferedReader = new BufferedReader(stringReader); + String skip = bufferedReader.readLine(); + log.info("Skip header: " + skip); + int lineNumber = 1; + String nextLine; + + while ((nextLine = bufferedReader.readLine()) != null) { + parseLine(nextLine, lineNumber, resultList, errors); + lineNumber++; + } + + return new AggregatesCsvResponse(resultList, errors); + + } catch (Exception e) { + log.error(ERROR_READING_CSV + e.getMessage(), e); + throw new InvalidRequestException(ERROR_READING_CSV + e.getMessage()); + } + } + + private void parseLine(String nextLine, int lineNumber, List resultList, List errors) { + try { + StringReader lineReader = new StringReader(nextLine); + CsvToBean csvToBean = getAggregateCsvToBean(new BufferedReader(lineReader)); + List csvAggregateList = csvToBean.parse(); + if (!csvAggregateList.isEmpty()) { + CsvAggregate csvAggregate = csvAggregateList.get(0); + csvAggregate.setRowNumber(lineNumber); + resultList.add(csvAggregateList.get(0)); + } + log.debug("Row " + lineNumber + ": "); + } catch (Exception e) { + log.error("Error to the row " + lineNumber + ": " + e.getMessage()); + errors.add(new RowError(lineNumber, "", MALFORMED_ROW)); + } + } + + private CsvToBean getAggregateCsvToBean(BufferedReader bufferedReader) { + CsvToBeanBuilder csvToBeanBuilder = new CsvToBeanBuilder<>(bufferedReader); + csvToBeanBuilder.withType(CsvAggregate.class); + csvToBeanBuilder.withSeparator(';'); + csvToBeanBuilder.withQuoteChar(DEFAULT_QUOTE_CHARACTER); + csvToBeanBuilder.withOrderedResults(true); + csvToBeanBuilder.withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_SEPARATORS); + csvToBeanBuilder.withThrowExceptions(false); + return csvToBeanBuilder.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 c0936e0cf..049a3143a 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 @@ -2,7 +2,9 @@ import io.smallrye.mutiny.Uni; import it.pagopa.selfcare.onboarding.common.OnboardingStatus; -import it.pagopa.selfcare.onboarding.controller.request.*; +import it.pagopa.selfcare.onboarding.controller.request.OnboardingImportContract; +import it.pagopa.selfcare.onboarding.controller.request.OnboardingUserRequest; +import it.pagopa.selfcare.onboarding.controller.request.UserRequest; import it.pagopa.selfcare.onboarding.controller.response.OnboardingGet; import it.pagopa.selfcare.onboarding.controller.response.OnboardingGetResponse; import it.pagopa.selfcare.onboarding.controller.response.OnboardingResponse; diff --git a/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/AggregatesControllerTest.java b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/AggregatesControllerTest.java new file mode 100644 index 000000000..7c3a2f5db --- /dev/null +++ b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/controller/AggregatesControllerTest.java @@ -0,0 +1,48 @@ +package it.pagopa.selfcare.onboarding.controller; + +import io.quarkus.test.InjectMock; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.common.http.TestHTTPEndpoint; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.mongodb.MongoTestResource; +import io.quarkus.test.security.TestSecurity; +import io.restassured.http.ContentType; +import io.smallrye.mutiny.Uni; +import it.pagopa.selfcare.onboarding.model.VerifyAggregateResponse; +import it.pagopa.selfcare.onboarding.service.AggregatesService; +import org.junit.jupiter.api.Test; + +import java.io.File; + +import static io.restassured.RestAssured.given; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@QuarkusTest +@TestHTTPEndpoint(AggregatesController.class) +@QuarkusTestResource(MongoTestResource.class) +public class AggregatesControllerTest { + + @InjectMock + AggregatesService aggregatesService; + + @Test + @TestSecurity(user = "userJwt") + void verifyAggregatesCsv_succeeds() { + File testFile = new File("src/test/resources/aggregates.csv"); + + when(aggregatesService.validateAggregatesCsv(any())) + .thenReturn(Uni.createFrom().item(new VerifyAggregateResponse())); + + given() + .when() + .contentType(ContentType.MULTIPART) + .multiPart("aggregates", testFile) + .post("/verification") + .then() + .statusCode(200); + + verify(aggregatesService, times(1)) + .validateAggregatesCsv(any()); + } +} diff --git a/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefaultTest.java b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefaultTest.java new file mode 100644 index 000000000..a1ea4ab30 --- /dev/null +++ b/apps/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/AggregatesServiceDefaultTest.java @@ -0,0 +1,67 @@ +package it.pagopa.selfcare.onboarding.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.test.InjectMock; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.vertx.RunOnVertxContext; +import io.smallrye.mutiny.Uni; +import io.smallrye.mutiny.helpers.test.UniAssertSubscriber; +import it.pagopa.selfcare.onboarding.exception.ResourceNotFoundException; +import it.pagopa.selfcare.onboarding.mapper.OnboardingMapper; +import it.pagopa.selfcare.onboarding.model.VerifyAggregateResponse; +import jakarta.inject.Inject; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.junit.jupiter.api.Test; +import org.openapi.quarkus.party_registry_proxy_json.api.AooApi; +import org.openapi.quarkus.party_registry_proxy_json.api.InstitutionApi; +import org.openapi.quarkus.party_registry_proxy_json.api.UoApi; +import org.openapi.quarkus.party_registry_proxy_json.model.AOOResource; +import org.openapi.quarkus.party_registry_proxy_json.model.InstitutionResource; +import org.openapi.quarkus.party_registry_proxy_json.model.UOResource; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +import static org.mockito.Mockito.when; + +@QuarkusTest +public class AggregatesServiceDefaultTest { + + @Inject + AggregatesServiceDefault aggregatesServiceDefault; + + @Inject + OnboardingMapper onboardingMapper; + + @RestClient + @InjectMock + AooApi aooApi; + + @RestClient + @InjectMock + InstitutionApi institutionApi; + + @RestClient + @InjectMock + UoApi uoApi; + + @Test + @RunOnVertxContext + void validateAggregates(){ + File testFile = new File("src/test/resources/aggregates.csv"); + + when(aooApi.findByUnicodeUsingGET("1437190414", null)).thenReturn(Uni.createFrom().item(new AOOResource())); + when(institutionApi.findInstitutionUsingGET("00297110389", null, null)).thenReturn(Uni.createFrom().item(new InstitutionResource())); + when(uoApi.findByUnicodeUsingGET1("4551120274", null)).thenReturn(Uni.createFrom().item(new UOResource())); + + when(aooApi.findByUnicodeUsingGET("AQ66",null)).thenThrow(ResourceNotFoundException.class); + when(institutionApi.findInstitutionUsingGET("345645", null, null)).thenThrow(ResourceNotFoundException.class); + when(uoApi.findByUnicodeUsingGET1("AQ66",null)).thenThrow(ResourceNotFoundException.class); + + aggregatesServiceDefault.validateAggregatesCsv(testFile) + .subscribe().withSubscriber(UniAssertSubscriber.create()) + .assertCompleted(); + } + +} diff --git a/apps/onboarding-ms/src/test/resources/aggregates.csv b/apps/onboarding-ms/src/test/resources/aggregates.csv new file mode 100644 index 000000000..617bdb5fb --- /dev/null +++ b/apps/onboarding-ms/src/test/resources/aggregates.csv @@ -0,0 +1,10 @@ +codice fiscale,Ragione Sociale,subunitCode,subunitType,Area Geografica,Sede,Codice IPA +1437190414;Servizi turistici e culturali;AQ66UML;AOO;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA +00297110389;SAN LEO 2000 SERVIZI TURISTICI SRL;;;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA +4551120274;Progetto Tiburtina;KNDJE4;UO;;Via Torino 186;00L7M4KW +4551120275;;;;;Via Torino 186;00L7M4KW +;Servizi turistici e culturali;AQ66UML;AOO;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA +4551120275;Servizi turistici e culturali;AQ66;AOO;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA +4551120275;Servizi turistici e culturali;AQ66;UO;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA +345645;Servizi turistici e culturali;;;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA +345645;Servizi turistici e culturali;123;AEO;;PIAZZA DANTE ALIGHIERI 14;02IKT4NA From 15f921d667be8a8ce1b6994b2891c4ec0f6ef974 Mon Sep 17 00:00:00 2001 From: Giulia Tremolada <124147597+giulia-tremolada@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:02:17 +0200 Subject: [PATCH 4/6] [SELC-5095] feat: executePendingState in WorkflowExecutorContractRegistrationAggregator (#352) --- apps/onboarding-functions/host.json | 3 +- .../entity/OnboardingWorkflowAggregator.java | 2 +- .../functions/OnboardingFunctions.java | 8 +++- .../onboarding/mapper/OnboardingMapper.java | 6 +++ .../selfcare/onboarding/utils/Utils.java | 11 +++++ .../onboarding/workflow/WorkflowExecutor.java | 1 - ...xecutorContractRegistrationAggregator.java | 29 +++++++++--- .../functions/OnboardingFunctionsTest.java | 44 +++++++++++++++++++ 8 files changed, 94 insertions(+), 10 deletions(-) diff --git a/apps/onboarding-functions/host.json b/apps/onboarding-functions/host.json index c0dfb483d..4e4c298e2 100644 --- a/apps/onboarding-functions/host.json +++ b/apps/onboarding-functions/host.json @@ -8,7 +8,8 @@ }, "extensions": { "durableTask": { - "hubName": "JavaTestHub" + "hubName": "JavaTestHub", + "maxConcurrentActivityFunctions": 10 } }, "extensionBundle": { diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/entity/OnboardingWorkflowAggregator.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/entity/OnboardingWorkflowAggregator.java index 953b4a9a2..1eb8a7250 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/entity/OnboardingWorkflowAggregator.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/entity/OnboardingWorkflowAggregator.java @@ -36,7 +36,7 @@ public String emailRegistrationPath(MailTemplatePathConfig config) { @Override public String getEmailCompletionPath(MailTemplatePathConfig config) { - return config.completePathAggregate(); + return config.completePath(); } @Override 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 53fe4d8dc..d88560457 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 @@ -14,6 +14,7 @@ import it.pagopa.selfcare.onboarding.config.RetryPolicyConfig; 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.service.CompletionService; import it.pagopa.selfcare.onboarding.service.OnboardingService; import it.pagopa.selfcare.onboarding.workflow.*; @@ -38,14 +39,17 @@ public class OnboardingFunctions { private final CompletionService completionService; private final ObjectMapper objectMapper; private final TaskOptions optionsRetry; + private final OnboardingMapper onboardingMapper; public OnboardingFunctions(OnboardingService service, ObjectMapper objectMapper, RetryPolicyConfig retryPolicyConfig, - CompletionService completionService) { + CompletionService completionService, + OnboardingMapper onboardingMapper) { this.service = service; this.objectMapper = objectMapper; this.completionService = completionService; + this.onboardingMapper = onboardingMapper; final int maxAttempts = retryPolicyConfig.maxAttempts(); final Duration firstRetryInterval = Duration.ofSeconds(retryPolicyConfig.firstRetryInterval()); RetryPolicy retryPolicy = new RetryPolicy(maxAttempts, firstRetryInterval); @@ -139,7 +143,7 @@ public void onboardingsOrchestrator( switch (onboarding.getWorkflowType()) { case CONTRACT_REGISTRATION -> workflowExecutor = new WorkflowExecutorContractRegistration(objectMapper, optionsRetry); - case CONTRACT_REGISTRATION_AGGREGATOR -> workflowExecutor = new WorkflowExecutorContractRegistrationAggregator(objectMapper, optionsRetry); + case CONTRACT_REGISTRATION_AGGREGATOR -> workflowExecutor = new WorkflowExecutorContractRegistrationAggregator(objectMapper, optionsRetry, onboardingMapper); case FOR_APPROVE -> workflowExecutor = new WorkflowExecutorForApprove(objectMapper, optionsRetry); case FOR_APPROVE_PT -> workflowExecutor = new WorkflowExecutorForApprovePt(objectMapper, optionsRetry); case CONFIRMATION -> workflowExecutor = new WorkflowExecutorConfirmation(objectMapper, optionsRetry); diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java index 416702229..078e32cac 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/mapper/OnboardingMapper.java @@ -1,6 +1,7 @@ package it.pagopa.selfcare.onboarding.mapper; import it.pagopa.selfcare.onboarding.dto.OnboardingAggregateOrchestratorInput; +import it.pagopa.selfcare.onboarding.entity.AggregateInstitution; import it.pagopa.selfcare.onboarding.entity.Institution; import it.pagopa.selfcare.onboarding.entity.Onboarding; import org.mapstruct.Mapper; @@ -18,6 +19,9 @@ public interface OnboardingMapper { @Mapping(target = "activatedAt", ignore = true) Onboarding mapToOnboarding(OnboardingAggregateOrchestratorInput input); + @Mapping(target = "aggregate", expression = "java(mapFromAggregateInstitution(aggregateInstitution))") + OnboardingAggregateOrchestratorInput mapToOnboardingAggregateOrchestratorInput(Onboarding onboarding, AggregateInstitution aggregateInstitution); + /** * We need to create an explicit method to map the aggregate into the institution field of the new onboarding entity * because the data related to institutionType and origin must be retrieved from the aggregator, @@ -31,4 +35,6 @@ default Institution mapInstitution(Institution aggregate, Institution institutio } return aggregate; } + + Institution mapFromAggregateInstitution(AggregateInstitution aggregateInstitution); } diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/utils/Utils.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/utils/Utils.java index 2fd4ab2d6..d9a7799f4 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/utils/Utils.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/utils/Utils.java @@ -85,4 +85,15 @@ public static AckPayloadRequest readAckPayloadValue(ObjectMapper objectMapper, S public static boolean isNotInstitutionOnboarding(Onboarding onboarding) { return !ALLOWED_WORKFLOWS_FOR_INSTITUTION_NOTIFICATIONS.contains(onboarding.getWorkflowType()); } + + public static String getOnboardingAggregateString(ObjectMapper objectMapper, OnboardingAggregateOrchestratorInput onboarding) { + + String onboardingAggregateString; + try { + onboardingAggregateString = objectMapper.writeValueAsString(onboarding); + } catch (JsonProcessingException e) { + throw new FunctionOrchestratedException(e); + } + return onboardingAggregateString; + } } 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 972999183..36b136232 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 @@ -15,7 +15,6 @@ import static it.pagopa.selfcare.onboarding.functions.utils.ActivityName.*; import static it.pagopa.selfcare.onboarding.utils.Utils.*; - public interface WorkflowExecutor { Optional executeRequestState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow); diff --git a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java index ea0c643dd..5f6fd77de 100644 --- a/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java +++ b/apps/onboarding-functions/src/main/java/it/pagopa/selfcare/onboarding/workflow/WorkflowExecutorContractRegistrationAggregator.java @@ -1,22 +1,27 @@ package it.pagopa.selfcare.onboarding.workflow; import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.durabletask.Task; import com.microsoft.durabletask.TaskOptions; import com.microsoft.durabletask.TaskOrchestrationContext; import it.pagopa.selfcare.onboarding.common.OnboardingStatus; +import it.pagopa.selfcare.onboarding.dto.OnboardingAggregateOrchestratorInput; +import it.pagopa.selfcare.onboarding.entity.AggregateInstitution; import it.pagopa.selfcare.onboarding.entity.Onboarding; import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflow; import it.pagopa.selfcare.onboarding.entity.OnboardingWorkflowAggregator; +import it.pagopa.selfcare.onboarding.mapper.OnboardingMapper; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import static it.pagopa.selfcare.onboarding.entity.OnboardingWorkflowType.AGGREGATOR; import static it.pagopa.selfcare.onboarding.functions.utils.ActivityName.*; -import static it.pagopa.selfcare.onboarding.utils.Utils.getOnboardingString; -import static it.pagopa.selfcare.onboarding.utils.Utils.getOnboardingWorkflowString; +import static it.pagopa.selfcare.onboarding.utils.Utils.*; + +public record WorkflowExecutorContractRegistrationAggregator(ObjectMapper objectMapper, TaskOptions optionsRetry, OnboardingMapper onboardingMapper) implements WorkflowExecutor { -public record WorkflowExecutorContractRegistrationAggregator(ObjectMapper objectMapper, TaskOptions optionsRetry) implements WorkflowExecutor { - @Override public Optional executeRequestState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { String onboardingString = getOnboardingString(objectMapper, onboardingWorkflow.getOnboarding()); @@ -34,7 +39,21 @@ public Optional executeToBeValidatedState(TaskOrchestrationCon @Override public Optional executePendingState(TaskOrchestrationContext ctx, OnboardingWorkflow onboardingWorkflow) { - return onboardingCompletionActivity(ctx, onboardingWorkflow); + String onboardingWithInstitutionIdString = createInstitutionAndOnboarding(ctx, onboardingWorkflow.getOnboarding()); + Onboarding onboarding = readOnboardingValue(objectMapper(), onboardingWithInstitutionIdString); + + List> parallelTasks = new ArrayList<>(); + + for (AggregateInstitution aggregate : onboarding.getAggregates()) { + OnboardingAggregateOrchestratorInput onboardingAggregate = onboardingMapper.mapToOnboardingAggregateOrchestratorInput(onboarding, aggregate); + final String onboardingAggregateString = getOnboardingAggregateString(objectMapper(), onboardingAggregate); + parallelTasks.add(ctx.callSubOrchestrator(ONBOARDINGS_AGGREGATE_ORCHESTRATOR, onboardingAggregateString, String.class)); + } + + ctx.allOf(parallelTasks).await(); + + ctx.callActivity(SEND_MAIL_COMPLETION_ACTIVITY, getOnboardingWorkflowString(objectMapper(), onboardingWorkflow), optionsRetry, String.class).await(); + return Optional.of(OnboardingStatus.COMPLETED); } @Override 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 606ba57d5..7466d887b 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 @@ -14,9 +14,11 @@ import it.pagopa.selfcare.onboarding.HttpResponseMessageMock; import it.pagopa.selfcare.onboarding.common.OnboardingStatus; import it.pagopa.selfcare.onboarding.common.WorkflowType; +import it.pagopa.selfcare.onboarding.entity.AggregateInstitution; import it.pagopa.selfcare.onboarding.entity.Institution; 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.service.CompletionService; import it.pagopa.selfcare.onboarding.service.NotificationEventService; import it.pagopa.selfcare.onboarding.service.OnboardingService; @@ -58,6 +60,9 @@ public class OnboardingFunctionsTest { @InjectMock NotificationEventService notificationEventService; + @Inject + OnboardingMapper onboardingMapper; + final String onboardinString = "{\"onboardingId\":\"onboardingId\"}"; final String onboardingWorkflowString = "{\"type\":\"INSTITUTION\",\"onboarding\":{\"id\":\"id\",\"productId\":null,\"testEnvProductIds\":null,\"workflowType\":null,\"institution\":null,\"users\":null,\"aggregates\":null,\"pricingPlan\":null,\"billing\":null,\"signContract\":null,\"expiringDate\":null,\"status\":null,\"userRequestUid\":null,\"workflowInstanceId\":null,\"createdAt\":null,\"updatedAt\":null,\"activatedAt\":null,\"deletedAt\":null,\"reasonForReject\":null,\"isAggregator\":null}}"; @@ -166,6 +171,44 @@ void onboardingOrchestratorContractRegistrationAggregator(){ function.onboardingsOrchestrator(orchestrationContext, executionContext); } + @Test + void onboardingOrchestratorContractRegistrationAggregator_Pending(){ + Onboarding onboarding = new Onboarding(); + onboarding.setId("onboardingId"); + onboarding.setStatus(OnboardingStatus.PENDING); + AggregateInstitution aggregate1 = new AggregateInstitution(); + aggregate1.setTaxCode("code1"); + AggregateInstitution aggregate2 = new AggregateInstitution(); + aggregate1.setTaxCode("code2"); + AggregateInstitution aggregate3 = new AggregateInstitution(); + aggregate1.setTaxCode("code3"); + onboarding.setAggregates(List.of(aggregate1, aggregate2, aggregate3)); + Institution institution = new Institution(); + institution.setId("id"); + onboarding.setInstitution(institution); + onboarding.setWorkflowType(WorkflowType.CONTRACT_REGISTRATION_AGGREGATOR); + + TaskOrchestrationContext orchestrationContext = mockTaskOrchestrationContext(onboarding); + function.onboardingsOrchestrator(orchestrationContext, executionContext); + + ArgumentCaptor captorActivity = ArgumentCaptor.forClass(String.class); + Mockito.verify(orchestrationContext, times(5)) + .callActivity(captorActivity.capture(), any(), any(),any()); + assertEquals(CREATE_INSTITUTION_ACTIVITY, captorActivity.getAllValues().get(0)); + assertEquals(CREATE_ONBOARDING_ACTIVITY, captorActivity.getAllValues().get(1)); + assertEquals(CREATE_USERS_ACTIVITY, captorActivity.getAllValues().get(2)); + assertEquals(STORE_ONBOARDING_ACTIVATEDAT, captorActivity.getAllValues().get(3)); + assertEquals(SEND_MAIL_COMPLETION_ACTIVITY, captorActivity.getAllValues().get(4)); + + Mockito.verify(orchestrationContext, times(3)) + .callSubOrchestrator(eq(ONBOARDINGS_AGGREGATE_ORCHESTRATOR), any(), any()); + + Mockito.verify(service, times(1)) + .updateOnboardingStatus(onboarding.getId(), OnboardingStatus.COMPLETED); + + function.onboardingsOrchestrator(orchestrationContext, executionContext); + } + @Test void onboardingsOrchestratorNewAdminRequest() { Onboarding onboarding = new Onboarding(); @@ -492,6 +535,7 @@ TaskOrchestrationContext mockTaskOrchestrationContext(Onboarding onboarding) { Task task = mock(Task.class); when(orchestrationContext.callActivity(any(),any(),any(),any())).thenReturn(task); + when(orchestrationContext.callSubOrchestrator(any(),any())).thenReturn(task); when(task.await()).thenReturn("example"); when(orchestrationContext.allOf(anyList())).thenReturn(task); return orchestrationContext; From 38a4a5949f86ee82ae7e126b2868a9ccf49ee138 Mon Sep 17 00:00:00 2001 From: pierpaolodidato89 <137791912+pierpaolodidato89@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:35:32 +0200 Subject: [PATCH 5/6] [SELC-5215] feat: Removed validation containts on request for check manager API --- apps/onboarding-ms/src/main/docs/openapi.json | 6 ++---- apps/onboarding-ms/src/main/docs/openapi.yaml | 7 ++----- .../controller/request/OnboardingUserRequest.java | 2 -- .../onboarding/service/OnboardingServiceDefault.java | 3 +-- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/apps/onboarding-ms/src/main/docs/openapi.json b/apps/onboarding-ms/src/main/docs/openapi.json index db7b5ef3b..01d200dd2 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.json +++ b/apps/onboarding-ms/src/main/docs/openapi.json @@ -26,7 +26,7 @@ "/v1/aggregates/verification" : { "post" : { "tags" : [ "Aggregates Controller" ], - "summary" : "", + "summary" : "Validate the data related to the aggregated entities present in a CSV file", "requestBody" : { "content" : { "multipart/form-data" : { @@ -1967,7 +1967,7 @@ "type" : "string" }, "OnboardingUserRequest" : { - "required" : [ "productId", "origin", "originId", "users" ], + "required" : [ "productId", "users" ], "type" : "object", "properties" : { "productId" : { @@ -1981,11 +1981,9 @@ "type" : "string" }, "origin" : { - "minLength" : 1, "type" : "string" }, "originId" : { - "minLength" : 1, "type" : "string" }, "taxCode" : { diff --git a/apps/onboarding-ms/src/main/docs/openapi.yaml b/apps/onboarding-ms/src/main/docs/openapi.yaml index ec8212e46..750ba453b 100644 --- a/apps/onboarding-ms/src/main/docs/openapi.yaml +++ b/apps/onboarding-ms/src/main/docs/openapi.yaml @@ -19,7 +19,8 @@ paths: post: tags: - Aggregates Controller - summary: "" + summary: Validate the data related to the aggregated entities present in a CSV + file requestBody: content: multipart/form-data: @@ -1410,8 +1411,6 @@ components: OnboardingUserRequest: required: - productId - - origin - - originId - users type: object properties: @@ -1423,10 +1422,8 @@ components: subunitCode: type: string origin: - minLength: 1 type: string originId: - minLength: 1 type: string taxCode: type: string diff --git a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/request/OnboardingUserRequest.java b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/request/OnboardingUserRequest.java index fb610ef81..ef80d8bee 100644 --- a/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/request/OnboardingUserRequest.java +++ b/apps/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/controller/request/OnboardingUserRequest.java @@ -16,10 +16,8 @@ public class OnboardingUserRequest { private String subunitCode; - @NotEmpty(message = "origin is required") private String origin; - @NotEmpty(message = "originId is required") private String originId; private String taxCode; 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 d13e4735e..4e5120a87 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 @@ -1043,8 +1043,7 @@ public Uni checkManager(OnboardingUserRequest onboardingUserRequest) { items.stream().map(onboarding -> onboarding.getUsers().stream() .filter(userToOnboard -> PartyRole.MANAGER == userToOnboard.getRole()) .map(User::getId) - .findAny().orElse(null)) - .toList()) + .findAny().orElse(null)).toList()) .onItem().transformToUni(uuids -> { if (uuids.contains(uuid.toString())) { return Uni.createFrom().item(true); From ab774468aa2573399352d9430a1de788bb24fa13 Mon Sep 17 00:00:00 2001 From: "renovate-pagopa[bot]" <164534245+renovate-pagopa[bot]@users.noreply.github.com> Date: Wed, 3 Jul 2024 08:47:28 +0200 Subject: [PATCH 6/6] Pin dependencies (#346) Co-authored-by: renovate-pagopa[bot] <164534245+renovate-pagopa[bot]@users.noreply.github.com> --- apps/onboarding-functions/src/main/docker/Dockerfile.jvm | 2 +- .../src/main/docker/Dockerfile.legacy-jar | 2 +- apps/onboarding-functions/src/main/docker/Dockerfile.native | 2 +- .../src/main/docker/Dockerfile.native-micro | 2 +- apps/onboarding-ms/Dockerfile | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/onboarding-functions/src/main/docker/Dockerfile.jvm b/apps/onboarding-functions/src/main/docker/Dockerfile.jvm index fd592d714..3d89c9f7c 100644 --- a/apps/onboarding-functions/src/main/docker/Dockerfile.jvm +++ b/apps/onboarding-functions/src/main/docker/Dockerfile.jvm @@ -77,7 +77,7 @@ # accessed directly. (example: "foo.example.com,bar.example.com") # ### -FROM registry.access.redhat.com/ubi8/openjdk-11:1.15 +FROM registry.access.redhat.com/ubi8/openjdk-11:1.15@sha256:5d3a4fbc094c2c29bf7ee0b9715e08d156d8c86a9d56f5e974439077756891f5 ENV LANGUAGE='en_US:en' diff --git a/apps/onboarding-functions/src/main/docker/Dockerfile.legacy-jar b/apps/onboarding-functions/src/main/docker/Dockerfile.legacy-jar index 621f69e4a..e2a23822f 100644 --- a/apps/onboarding-functions/src/main/docker/Dockerfile.legacy-jar +++ b/apps/onboarding-functions/src/main/docker/Dockerfile.legacy-jar @@ -77,7 +77,7 @@ # accessed directly. (example: "foo.example.com,bar.example.com") # ### -FROM registry.access.redhat.com/ubi8/openjdk-11:1.15 +FROM registry.access.redhat.com/ubi8/openjdk-11:1.15@sha256:5d3a4fbc094c2c29bf7ee0b9715e08d156d8c86a9d56f5e974439077756891f5 ENV LANGUAGE='en_US:en' diff --git a/apps/onboarding-functions/src/main/docker/Dockerfile.native b/apps/onboarding-functions/src/main/docker/Dockerfile.native index 28ba5e4c2..3a5cd1490 100644 --- a/apps/onboarding-functions/src/main/docker/Dockerfile.native +++ b/apps/onboarding-functions/src/main/docker/Dockerfile.native @@ -14,7 +14,7 @@ # docker run -i --rm -p 8080:8080 quarkus/onboarding-functions # ### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6@sha256:33931dce809712888d1a8061bfa676963f517daca993984afed3251bc1fb5987 WORKDIR /work/ RUN chown 1001 /work \ && chmod "g+rwX" /work \ diff --git a/apps/onboarding-functions/src/main/docker/Dockerfile.native-micro b/apps/onboarding-functions/src/main/docker/Dockerfile.native-micro index a2f329ccc..096118a85 100644 --- a/apps/onboarding-functions/src/main/docker/Dockerfile.native-micro +++ b/apps/onboarding-functions/src/main/docker/Dockerfile.native-micro @@ -17,7 +17,7 @@ # docker run -i --rm -p 8080:8080 quarkus/onboarding-functions # ### -FROM quay.io/quarkus/quarkus-micro-image:2.0 +FROM quay.io/quarkus/quarkus-micro-image:2.0@sha256:c6775a8521dd4f724039f9cb7659f407cc15d7dc32c509f02da2add0f4de154a WORKDIR /work/ RUN chown 1001 /work \ && chmod "g+rwX" /work \ diff --git a/apps/onboarding-ms/Dockerfile b/apps/onboarding-ms/Dockerfile index bc08ad6f2..f20d3a6d4 100644 --- a/apps/onboarding-ms/Dockerfile +++ b/apps/onboarding-ms/Dockerfile @@ -1,5 +1,5 @@ -# syntax=docker/dockerfile:1.6 -FROM maven:3-eclipse-temurin-17 AS builder +# syntax=docker/dockerfile:1.6@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021 +FROM maven:3-eclipse-temurin-17@sha256:6ca4f2d4c7a8affa4a7cdec526dd2aa5d433ddd63f8ed3337a543408136b174e AS builder WORKDIR /src COPY --link ./pom.xml . @@ -20,7 +20,7 @@ COPY ./apps/onboarding-ms/src/main/ ./src/main/ WORKDIR /src RUN mvn --projects :onboarding-ms --also-make clean package -DskipTests -FROM openjdk:17-jdk AS runtime +FROM openjdk:17-jdk@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 AS runtime ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"