From 9695e03b45d20b264b80a5d356918dd65942882b Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 12:28:09 +0100 Subject: [PATCH 01/20] replace product api with sdk --- onboarding-ms/pom.xml | 13 +- .../onboarding/conf/OnboardingMsConfig.java | 34 + .../service/OnboardingServiceDefault.java | 105 +- onboarding-ms/src/main/openapi/product.json | 1561 ----------------- .../src/main/resources/application.properties | 10 +- .../service/OnboardingServiceDefaultTest.java | 89 +- 6 files changed, 142 insertions(+), 1670 deletions(-) create mode 100644 onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/conf/OnboardingMsConfig.java delete mode 100644 onboarding-ms/src/main/openapi/product.json diff --git a/onboarding-ms/pom.xml b/onboarding-ms/pom.xml index c43a76dda..d5469b57f 100644 --- a/onboarding-ms/pom.xml +++ b/onboarding-ms/pom.xml @@ -22,7 +22,7 @@ 3.4.2 true 3.1.2 - 0.0.4 + 0.1.0 @@ -134,6 +134,17 @@ 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} + diff --git a/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/conf/OnboardingMsConfig.java b/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/conf/OnboardingMsConfig.java new file mode 100644 index 000000000..338137132 --- /dev/null +++ b/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/conf/OnboardingMsConfig.java @@ -0,0 +1,34 @@ +package it.pagopa.selfcare.onboarding.conf; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import it.pagopa.selfcare.azurestorage.AzureBlobClient; +import it.pagopa.selfcare.azurestorage.AzureBlobClientDefault; +import it.pagopa.selfcare.product.service.ProductService; +import it.pagopa.selfcare.product.service.ProductServiceDefault; +import jakarta.enterprise.context.ApplicationScoped; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +@ApplicationScoped +public class OnboardingMsConfig { + + @ConfigProperty(name = "onboarding-ms.blob-storage.container-product") + String containerProduct; + + @ConfigProperty(name = "onboarding-ms.blob-storage.filepath-product") + String filepathProduct; + + @ConfigProperty(name = "onboarding-ms.blob-storage.connection-string-product") + String connectionStringProduct; + + @ApplicationScoped + public ProductService productService(ObjectMapper objectMapper){ + AzureBlobClient azureBlobClient = new AzureBlobClientDefault(connectionStringProduct, containerProduct); + String productJsonString = azureBlobClient.getFileAsText(filepathProduct); + try { + return new ProductServiceDefault(productJsonString, objectMapper); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Found an issue when trying to serialize product json string!!"); + } + } +} diff --git a/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java b/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java index 083f12327..24ef53dc2 100644 --- a/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java +++ b/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java @@ -15,6 +15,10 @@ import it.pagopa.selfcare.onboarding.exception.UpdateNotAllowedException; import it.pagopa.selfcare.onboarding.mapper.OnboardingMapper; import it.pagopa.selfcare.onboarding.service.strategy.OnboardingValidationStrategy; +import it.pagopa.selfcare.product.entity.Product; +import it.pagopa.selfcare.product.entity.ProductRoleInfo; +import it.pagopa.selfcare.product.exception.ProductNotFoundException; +import it.pagopa.selfcare.product.service.ProductService; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.WebApplicationException; @@ -24,9 +28,6 @@ import org.jboss.resteasy.reactive.ClientWebApplicationException; import org.openapi.quarkus.core_json.api.OnboardingApi; import org.openapi.quarkus.onboarding_functions_json.api.OrchestrationApi; -import org.openapi.quarkus.product_json.api.ProductApi; -import org.openapi.quarkus.product_json.model.ProductRoleInfoOperations; -import org.openapi.quarkus.product_json.model.ProductRoleInfoRes; import org.openapi.quarkus.user_registry_json.api.UserApi; import org.openapi.quarkus.user_registry_json.model.*; @@ -39,7 +40,6 @@ @ApplicationScoped public class OnboardingServiceDefault implements OnboardingService { - protected static final String PRODUCT_NOT_FOUND = "Product %s not found!"; protected static final String ATLEAST_ONE_PRODUCT_ROLE_REQUIRED = "At least one Product role related to %s Party role is required"; protected static final String MORE_THAN_ONE_PRODUCT_ROLE_AVAILABLE = "More than one Product role related to %s Party role is available. Cannot automatically set the Product role"; private static final String ONBOARDING_NOT_ALLOWED_ERROR_MESSAGE_TEMPLATE = "Institution with external id '%s' is not allowed to onboard '%s' product"; @@ -52,10 +52,6 @@ public class OnboardingServiceDefault implements OnboardingService { @Inject UserApi userRegistryApi; - @RestClient - @Inject - ProductApi productApi; - @RestClient @Inject OnboardingApi onboardingApi; @@ -69,9 +65,13 @@ public class OnboardingServiceDefault implements OnboardingService { @Inject OnboardingValidationStrategy onboardingValidationStrategy; + @Inject + ProductService productService; @ConfigProperty(name = "onboarding.expiring-date") Integer onboardingExpireDate; + @ConfigProperty(name = "onboarding.orchestration.enabled") + Boolean onboardingOrchestrationEnabled; @Override public Uni onboarding(OnboardingDefaultRequest onboardingRequest) { @@ -105,40 +105,49 @@ public Uni fillUsersAndOnboarding(Onboarding onboarding, Lis public Uni persistAndStartOrchestrationOnboarding(Onboarding onboarding) { final List onboardings = new ArrayList<>(); onboardings.add(onboarding); - return Panache.withTransaction(() -> Onboarding.persistOrUpdate(onboardings) - .onItem().transformToUni(saved -> orchestrationApi.apiStartOnboardingOrchestrationGet(onboarding.getId().toHexString()) - .replaceWith(onboarding))); + + if(onboardingOrchestrationEnabled) { + return Panache.withTransaction(() -> Onboarding.persistOrUpdate(onboardings) + .onItem().transformToUni(saved -> orchestrationApi.apiStartOnboardingOrchestrationGet(onboarding.getId().toHexString()) + .replaceWith(onboarding))); + } else { + return Onboarding.persistOrUpdate(onboardings) + .replaceWith(onboarding); + } } public Uni checkProductAndReturnOnboarding(Onboarding onboarding) { - /* Verify already onboarding for product and product parent */ + final Product product; - return productApi.getProductIsValidUsingGET(onboarding.getProductId()) - .onFailure(ClientWebApplicationException.class).recoverWithUni(ex -> ((WebApplicationException)ex).getResponse().getStatus() == 404 - ? Uni.createFrom().failure(new InvalidRequestException(String.format(PRODUCT_NOT_FOUND, onboarding.getProductId()), DEFAULT_ERROR.getCode())) - : Uni.createFrom().failure(new RuntimeException(ex.getMessage()))) - /* if product is not valid, throw an exception */ - .onItem().ifNull().failWith(new OnboardingNotAllowedException(String.format(UNABLE_TO_COMPLETE_THE_ONBOARDING_FOR_INSTITUTION_FOR_PRODUCT_DISMISSED, + try { + product = Optional.of(productService.getProductIsValid(onboarding.getProductId())) + .orElseThrow(() -> new OnboardingNotAllowedException(String.format(UNABLE_TO_COMPLETE_THE_ONBOARDING_FOR_INSTITUTION_FOR_PRODUCT_DISMISSED, onboarding.getInstitution().getTaxCode(), - onboarding.getProductId()), DEFAULT_ERROR.getCode())) - /* if PT and product is not delegable, throw an exception */ - .onItem().transformToUni(productResource -> InstitutionType.PT == onboarding.getInstitution().getInstitutionType() && !productResource.getDelegable() - ? Uni.createFrom().failure(new OnboardingNotAllowedException(String.format(ONBOARDING_NOT_ALLOWED_ERROR_MESSAGE_NOT_DELEGABLE, - onboarding.getInstitution().getTaxCode(), - onboarding.getProductId()), DEFAULT_ERROR.getCode())) - : Uni.createFrom().item(productResource)) - .onItem().invoke(product -> { - if(Objects.nonNull(product.getProductOperations())) - validateProductRole(onboarding.getUsers(), product.getProductOperations().getRoleMappings()); - else validateProductRoleRes(onboarding.getUsers(), product.getRoleMappings()); - }) - .onItem().transformToUni(product -> Objects.nonNull(product.getProductOperations()) - ? checkIfAlreadyOnboardingAndValidateAllowedMap(product.getProductOperations().getId(), onboarding.getInstitution().getTaxCode(), onboarding.getInstitution().getSubunitCode()) + onboarding.getProductId()), DEFAULT_ERROR.getCode())); + } catch (ProductNotFoundException | IllegalArgumentException e){ + throw new OnboardingNotAllowedException(String.format(UNABLE_TO_COMPLETE_THE_ONBOARDING_FOR_INSTITUTION_FOR_PRODUCT_DISMISSED, + onboarding.getInstitution().getTaxCode(), + onboarding.getProductId()), DEFAULT_ERROR.getCode()); + } + + /* if PT and product is not delegable, throw an exception */ + if(InstitutionType.PT == onboarding.getInstitution().getInstitutionType() && !product.isDelegable()) { + throw new OnboardingNotAllowedException(String.format(ONBOARDING_NOT_ALLOWED_ERROR_MESSAGE_NOT_DELEGABLE, + onboarding.getInstitution().getTaxCode(), + onboarding.getProductId()), DEFAULT_ERROR.getCode()); + } + + validateProductRole(onboarding.getUsers(), Objects.nonNull(product.getParent()) + ? product.getParent().getRoleMappings() + : product.getRoleMappings()); + + /* Verify already onboarding for product and product parent */ + return (Objects.nonNull(product.getParent()) + ? checkIfAlreadyOnboardingAndValidateAllowedMap(product.getParentId(), onboarding.getInstitution().getTaxCode(), onboarding.getInstitution().getSubunitCode()) .onItem().transformToUni( ignore -> checkIfAlreadyOnboardingAndValidateAllowedMap(product.getId(), onboarding.getInstitution().getTaxCode(), onboarding.getInstitution().getSubunitCode())) : checkIfAlreadyOnboardingAndValidateAllowedMap(product.getId(), onboarding.getInstitution().getTaxCode(), onboarding.getInstitution().getSubunitCode()) - ) - .replaceWith(onboarding); + ).replaceWith(onboarding); } private Uni checkIfAlreadyOnboardingAndValidateAllowedMap(String productId, String institutionTaxCode, String institutionSubuniCode) { @@ -160,36 +169,18 @@ private Uni checkIfAlreadyOnboardingAndValidateAllowedMap(String produc .replaceWith(Boolean.TRUE); } - private void validateProductRole(List users, Map roleMappings) { - try { - if(Objects.isNull(roleMappings) || roleMappings.isEmpty()) - throw new IllegalArgumentException("Role mappings is required"); - users.forEach(userInfo -> { - if(Objects.isNull(roleMappings.get(userInfo.getRole().name()))) - throw new IllegalArgumentException(String.format(ATLEAST_ONE_PRODUCT_ROLE_REQUIRED, userInfo.getRole())); - if(Objects.isNull((roleMappings.get(userInfo.getRole().name()).getRoles()))) - throw new IllegalArgumentException(String.format(ATLEAST_ONE_PRODUCT_ROLE_REQUIRED, userInfo.getRole())); - if(roleMappings.get(userInfo.getRole().name()).getRoles().size() != 1) - throw new IllegalArgumentException(String.format(MORE_THAN_ONE_PRODUCT_ROLE_AVAILABLE, userInfo.getRole())); - userInfo.setProductRole(roleMappings.get(userInfo.getRole().name()).getRoles().get(0).getCode()); - }); - } catch (IllegalArgumentException e){ - throw new OnboardingNotAllowedException(e.getMessage(), DEFAULT_ERROR.getCode()); - } - } - - private void validateProductRoleRes(List users, Map roleMappings) { + private void validateProductRole(List users, Map roleMappings) { try { if(Objects.isNull(roleMappings) || roleMappings.isEmpty()) throw new IllegalArgumentException("Role mappings is required"); users.forEach(userInfo -> { - if(Objects.isNull(roleMappings.get(userInfo.getRole().name()))) + if(Objects.isNull(roleMappings.get(userInfo.getRole()))) throw new IllegalArgumentException(String.format(ATLEAST_ONE_PRODUCT_ROLE_REQUIRED, userInfo.getRole())); - if(Objects.isNull((roleMappings.get(userInfo.getRole().name()).getRoles()))) + if(Objects.isNull((roleMappings.get(userInfo.getRole()).getRoles()))) throw new IllegalArgumentException(String.format(ATLEAST_ONE_PRODUCT_ROLE_REQUIRED, userInfo.getRole())); - if(roleMappings.get(userInfo.getRole().name()).getRoles().size() != 1) + if(roleMappings.get(userInfo.getRole()).getRoles().size() != 1) throw new IllegalArgumentException(String.format(MORE_THAN_ONE_PRODUCT_ROLE_AVAILABLE, userInfo.getRole())); - userInfo.setProductRole(roleMappings.get(userInfo.getRole().name()).getRoles().get(0).getCode()); + userInfo.setProductRole(roleMappings.get(userInfo.getRole()).getRoles().get(0).getCode()); }); } catch (IllegalArgumentException e){ throw new OnboardingNotAllowedException(e.getMessage(), DEFAULT_ERROR.getCode()); diff --git a/onboarding-ms/src/main/openapi/product.json b/onboarding-ms/src/main/openapi/product.json deleted file mode 100644 index 8586f48ba..000000000 --- a/onboarding-ms/src/main/openapi/product.json +++ /dev/null @@ -1,1561 +0,0 @@ -{ - "openapi" : "3.0.3", - "info" : { - "title" : "selc-product", - "description" : "The services described in this section deal with the management of the Product entity, providing the necessary methods for its creation, consultation and activation.", - "version" : "0.0.1-SNAPSHOT" - }, - "servers" : [ { - "url" : "{url}:{port}{basePath}", - "variables" : { - "url" : { - "default" : "http://localhost" - }, - "port" : { - "default" : "80" - }, - "basePath" : { - "default" : "" - } - } - } ], - "tags" : [ { - "name" : "product", - "description" : "Product's endpoints for CRUD operations" - } ], - "paths" : { - "/products/" : { - "get" : { - "tags" : [ "product" ], - "summary" : "getProducts", - "description" : "Service that returns the list of PagoPA products", - "operationId" : "getProductsUsingGET", - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "post" : { - "tags" : [ "product" ], - "summary" : "createProduct", - "description" : "Service that allows the insert of a new occurrence for the Product entity", - "operationId" : "createProductUsingPOST", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/CreateProductDto" - } - } - } - }, - "responses" : { - "201" : { - "description" : "Created", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/tree" : { - "get" : { - "tags" : [ "product" ], - "summary" : "getProductsTree", - "description" : "Service that returns the list of PagoPA products tree", - "operationId" : "getProductsTreeUsingGET", - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ProductTreeResource" - } - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}" : { - "get" : { - "tags" : [ "product" ], - "summary" : "getProduct", - "description" : "Service that returns the information for a single product given its product id", - "operationId" : "getProductUsingGET", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - }, { - "name" : "institutionType", - "in" : "query", - "description" : "Institution's type", - "required" : false, - "style" : "form", - "schema" : { - "type" : "string", - "enum" : [ "GSP", "PA", "PG", "PSP", "PT", "SCP" ] - } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "put" : { - "tags" : [ "product" ], - "summary" : "updateProduct", - "description" : "Service that allows the update of a previously inserted occurrence of the Product entity", - "operationId" : "updateProductUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateProductDto" - } - } - } - }, - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "delete" : { - "tags" : [ "product" ], - "summary" : "deleteProduct", - "description" : "Service that allows the deactivation of a specific product by an Admin user", - "operationId" : "deleteProductUsingDELETE", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}/depict-image" : { - "put" : { - "tags" : [ "product" ], - "summary" : "saveProductDepictImage", - "description" : "Service that allows the update of a Product depiction image", - "operationId" : "saveProductDepictImageUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "required" : [ "depictImage" ], - "type" : "object", - "properties" : { - "depictImage" : { - "type" : "string", - "description" : "Product's depict image", - "format" : "binary" - } - } - } - } - } - }, - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}/logo" : { - "put" : { - "tags" : [ "product" ], - "summary" : "saveProductLogo", - "description" : "Service that allows the update of a Product logo", - "operationId" : "saveProductLogoUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "multipart/form-data" : { - "schema" : { - "required" : [ "logo" ], - "type" : "object", - "properties" : { - "logo" : { - "type" : "string", - "description" : "Product's logo image", - "format" : "binary" - } - } - } - } - } - }, - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}/role-mappings" : { - "get" : { - "tags" : [ "product" ], - "summary" : "getProductRoles", - "description" : "Service that returns the information about mappings between Party's and Product's role", - "operationId" : "getProductRolesUsingGET", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ProductRoleInfoRes" - } - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}/status/{status}" : { - "put" : { - "tags" : [ "product" ], - "summary" : "updateProductStatus", - "description" : "Service that allows to update the product status", - "operationId" : "updateProductStatusUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - }, { - "name" : "status", - "in" : "path", - "description" : "Product's status", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string", - "enum" : [ "ACTIVE", "INACTIVE", "PHASE_OUT", "TESTING" ] - } - } ], - "responses" : { - "200" : { - "description" : "OK" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}/sub-products" : { - "put" : { - "tags" : [ "product" ], - "summary" : "updateSubProduct", - "description" : "Service that allows the update of a previously inserted occurrence of the Product entity", - "operationId" : "updateSubProductUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateSubProductDto" - } - } - } - }, - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "post" : { - "tags" : [ "product" ], - "summary" : "createSubProduct", - "description" : "Service that allows the insert of a new occurrence for the Product entity", - "operationId" : "createSubProductUsingPOST", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/CreateSubProductDto" - } - } - } - }, - "responses" : { - "201" : { - "description" : "Created", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/products/{id}/valid" : { - "get" : { - "tags" : [ "product" ], - "summary" : "getProductIsValid", - "description" : "Service that returns the information for a single product given its product id", - "operationId" : "getProductIsValidUsingGET", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Product's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - } - }, - "components" : { - "schemas" : { - "BackOfficeConfigurations" : { - "title" : "BackOfficeConfigurations", - "type" : "object", - "properties" : { - "identityTokenAudience" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - }, - "BackOfficeConfigurationsResource" : { - "title" : "BackOfficeConfigurationsResource", - "required" : [ "identityTokenAudience", "url" ], - "type" : "object", - "properties" : { - "identityTokenAudience" : { - "type" : "string", - "description" : "Product's identity token audience" - }, - "url" : { - "type" : "string", - "description" : "URL that redirects to the back-office section, where is possible to manage the product" - } - } - }, - "ContractOperations" : { - "title" : "ContractOperations", - "type" : "object", - "properties" : { - "contractTemplatePath" : { - "type" : "string" - }, - "contractTemplateUpdatedAt" : { - "type" : "string", - "format" : "date-time" - }, - "contractTemplateVersion" : { - "type" : "string" - } - } - }, - "ContractResource" : { - "title" : "ContractResource", - "type" : "object", - "properties" : { - "contractTemplatePath" : { - "type" : "string", - "description" : "The path of contract" - }, - "contractTemplateUpdatedAt" : { - "type" : "string", - "description" : "Date the contract was postponed", - "format" : "date-time" - }, - "contractTemplateVersion" : { - "type" : "string", - "description" : "Version of the contract" - } - } - }, - "CreateProductDto" : { - "title" : "CreateProductDto", - "required" : [ "contractTemplatePath", "contractTemplateVersion", "description", "id", "identityTokenAudience", "roleMappings", "title", "urlBO", "urlPublic" ], - "type" : "object", - "properties" : { - "backOfficeEnvironmentConfigurations" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/BackOfficeConfigurationsResource" - }, - "description" : "Environment-specific configurations for back-office redirection with Token Exchange" - }, - "contractTemplatePath" : { - "type" : "string", - "description" : "The path of contract" - }, - "contractTemplateVersion" : { - "type" : "string", - "description" : "Version of the contract" - }, - "description" : { - "type" : "string", - "description" : "Product's description" - }, - "id" : { - "type" : "string", - "description" : "Product's unique identifier" - }, - "identityTokenAudience" : { - "type" : "string", - "description" : "Product's identity token audience" - }, - "institutionContractMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ContractResource" - }, - "description" : "Product contract based on institutionType" - }, - "logoBgColor" : { - "pattern" : "^#[0-9A-F]{6}$", - "type" : "string", - "description" : "Product logo's background color", - "example" : "#000000" - }, - "roleMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ProductRoleInfoReq" - }, - "description" : "Mappings between Party's and Product's role" - }, - "title" : { - "type" : "string", - "description" : "Product's title" - }, - "urlBO" : { - "type" : "string", - "description" : "URL that redirects to the back-office section, where is possible to manage the product" - }, - "urlPublic" : { - "type" : "string", - "description" : "URL that redirects to the public information webpage of the product" - } - } - }, - "CreateSubProductDto" : { - "title" : "CreateSubProductDto", - "required" : [ "contractTemplatePath", "contractTemplateVersion", "id", "title" ], - "type" : "object", - "properties" : { - "contractTemplatePath" : { - "type" : "string", - "description" : "The path of contract" - }, - "contractTemplateVersion" : { - "type" : "string", - "description" : "Version of the contract" - }, - "id" : { - "type" : "string", - "description" : "Product's unique identifier" - }, - "institutionContractMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ContractResource" - }, - "description" : "Product contract based on institutionType" - }, - "title" : { - "type" : "string", - "description" : "Product's title" - } - } - }, - "InvalidParam" : { - "title" : "InvalidParam", - "required" : [ "name", "reason" ], - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "description" : "Invalid parameter name." - }, - "reason" : { - "type" : "string", - "description" : "Invalid parameter reason." - } - } - }, - "Problem" : { - "title" : "Problem", - "required" : [ "status", "title" ], - "type" : "object", - "properties" : { - "detail" : { - "type" : "string", - "description" : "Human-readable description of this specific problem." - }, - "instance" : { - "type" : "string", - "description" : "A URI that describes where the problem occurred." - }, - "invalidParams" : { - "type" : "array", - "description" : "A list of invalid parameters details.", - "items" : { - "$ref" : "#/components/schemas/InvalidParam" - } - }, - "status" : { - "type" : "integer", - "description" : "The HTTP status code.", - "format" : "int32", - "example" : 500 - }, - "title" : { - "type" : "string", - "description" : "Short human-readable summary of the problem." - }, - "type" : { - "type" : "string", - "description" : "A URL to a page with more details regarding the problem." - } - }, - "description" : "A \"problem detail\" as a way to carry machine-readable details of errors (https://datatracker.ietf.org/doc/html/rfc7807)" - }, - "ProductOperations" : { - "title" : "ProductOperations", - "type" : "object", - "properties" : { - "backOfficeEnvironmentConfigurations" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/BackOfficeConfigurations" - } - }, - "contractTemplatePath" : { - "type" : "string" - }, - "contractTemplateUpdatedAt" : { - "type" : "string", - "format" : "date-time" - }, - "contractTemplateVersion" : { - "type" : "string" - }, - "createdAt" : { - "type" : "string", - "format" : "date-time" - }, - "createdBy" : { - "type" : "string" - }, - "delegable" : { - "type" : "boolean" - }, - "depictImageUrl" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "enabled" : { - "type" : "boolean" - }, - "id" : { - "type" : "string" - }, - "identityTokenAudience" : { - "type" : "string" - }, - "institutionContractMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ContractOperations" - } - }, - "logo" : { - "type" : "string" - }, - "logoBgColor" : { - "type" : "string" - }, - "modifiedAt" : { - "type" : "string", - "format" : "date-time" - }, - "modifiedBy" : { - "type" : "string" - }, - "parentId" : { - "type" : "string" - }, - "productOperations" : { - "$ref" : "#/components/schemas/ProductOperations" - }, - "roleManagementURL" : { - "type" : "string" - }, - "roleMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ProductRoleInfoOperations" - } - }, - "status" : { - "type" : "string", - "enum" : [ "ACTIVE", "INACTIVE", "PHASE_OUT", "TESTING" ] - }, - "title" : { - "type" : "string" - }, - "urlBO" : { - "type" : "string" - }, - "urlPublic" : { - "type" : "string" - } - } - }, - "ProductResource" : { - "title" : "ProductResource", - "type" : "object", - "properties" : { - "backOfficeEnvironmentConfigurations" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/BackOfficeConfigurationsResource" - }, - "description" : "Environment-specific configurations for back-office redirection with Token Exchange" - }, - "contractTemplatePath" : { - "type" : "string", - "description" : "The path of contract" - }, - "contractTemplateUpdatedAt" : { - "type" : "string", - "description" : "Date the contract was postponed", - "format" : "date-time" - }, - "contractTemplateVersion" : { - "type" : "string", - "description" : "Version of the contract" - }, - "createdAt" : { - "type" : "string", - "description" : "Creation/activation date and time", - "format" : "date-time" - }, - "createdBy" : { - "type" : "string", - "description" : "User who created/activated the resource", - "format" : "uuid" - }, - "delegable" : { - "type" : "boolean", - "description" : "If a product is delegable to a technical partner ", - "example" : false - }, - "depictImageUrl" : { - "type" : "string", - "description" : "Product's depiction image url" - }, - "description" : { - "type" : "string", - "description" : "Product's description" - }, - "id" : { - "type" : "string", - "description" : "Product's unique identifier" - }, - "identityTokenAudience" : { - "type" : "string", - "description" : "Product's identity token audience" - }, - "logo" : { - "type" : "string", - "description" : "Product's logo url" - }, - "logoBgColor" : { - "type" : "string", - "description" : "Product logo's background color", - "example" : "#000000" - }, - "modifiedAt" : { - "type" : "string", - "description" : "Last modified date and time", - "format" : "date-time" - }, - "modifiedBy" : { - "type" : "string", - "description" : "User who modified the resource", - "format" : "uuid" - }, - "parentId" : { - "type" : "string", - "description" : "Root parent of the sub product" - }, - "productOperations" : { - "$ref" : "#/components/schemas/ProductOperations" - }, - "roleManagementURL" : { - "type" : "string", - "description" : "Url of the utilities management" - }, - "roleMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ProductRoleInfoRes" - }, - "description" : "Mappings between Party's and Product's role" - }, - "status" : { - "type" : "string", - "description" : "Product's status", - "enum" : [ "ACTIVE", "INACTIVE", "PHASE_OUT", "TESTING" ] - }, - "title" : { - "type" : "string", - "description" : "Product's title" - }, - "urlBO" : { - "type" : "string", - "description" : "URL that redirects to the back-office section, where is possible to manage the product" - }, - "urlPublic" : { - "type" : "string", - "description" : "URL that redirects to the public information webpage of the product" - } - } - }, - "ProductRole" : { - "title" : "ProductRole", - "required" : [ "code", "description", "label" ], - "type" : "object", - "properties" : { - "code" : { - "type" : "string", - "description" : "Product role internal code" - }, - "description" : { - "type" : "string", - "description" : "Product role description" - }, - "label" : { - "type" : "string", - "description" : "Product role label" - } - } - }, - "ProductRoleInfoOperations" : { - "title" : "ProductRoleInfoOperations", - "type" : "object", - "properties" : { - "multiroleAllowed" : { - "type" : "boolean" - }, - "roles" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ProductRoleOperations" - } - } - } - }, - "ProductRoleInfoReq" : { - "title" : "ProductRoleInfoReq", - "required" : [ "multiroleAllowed", "roles" ], - "type" : "object", - "properties" : { - "multiroleAllowed" : { - "type" : "boolean", - "description" : "Flag indicating if a User can have more than one product role", - "example" : false - }, - "roles" : { - "type" : "array", - "description" : "Available product roles", - "items" : { - "$ref" : "#/components/schemas/ProductRoleOperations" - } - } - } - }, - "ProductRoleInfoRes" : { - "title" : "ProductRoleInfoRes", - "required" : [ "multiroleAllowed", "roles" ], - "type" : "object", - "properties" : { - "multiroleAllowed" : { - "type" : "boolean", - "description" : "Flag indicating if a User can have more than one product role", - "example" : false - }, - "roles" : { - "type" : "array", - "description" : "Available product roles", - "items" : { - "$ref" : "#/components/schemas/ProductRole" - } - } - } - }, - "ProductRoleOperations" : { - "title" : "ProductRoleOperations", - "type" : "object", - "properties" : { - "code" : { - "type" : "string" - }, - "description" : { - "type" : "string" - }, - "label" : { - "type" : "string" - } - } - }, - "ProductTreeResource" : { - "title" : "ProductTreeResource", - "type" : "object", - "properties" : { - "children" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ProductResource" - } - }, - "node" : { - "$ref" : "#/components/schemas/ProductResource" - } - } - }, - "UpdateProductDto" : { - "title" : "UpdateProductDto", - "required" : [ "contractTemplatePath", "contractTemplateVersion", "description", "identityTokenAudience", "roleMappings", "title", "urlBO", "urlPublic" ], - "type" : "object", - "properties" : { - "backOfficeEnvironmentConfigurations" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/BackOfficeConfigurationsResource" - }, - "description" : "Environment-specific configurations for back-office redirection with Token Exchange" - }, - "contractTemplatePath" : { - "type" : "string", - "description" : "The path of contract" - }, - "contractTemplateVersion" : { - "type" : "string", - "description" : "Version of the contract" - }, - "description" : { - "type" : "string", - "description" : "Product's description" - }, - "identityTokenAudience" : { - "type" : "string", - "description" : "Product's identity token audience" - }, - "institutionContractMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ContractResource" - }, - "description" : "Product contract based on institutionType" - }, - "logoBgColor" : { - "pattern" : "^#[0-9A-F]{6}$", - "type" : "string", - "description" : "Product logo's background color", - "example" : "#000000" - }, - "roleMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ProductRoleInfoReq" - }, - "description" : "Mappings between Party's and Product's role" - }, - "title" : { - "type" : "string", - "description" : "Product's title" - }, - "urlBO" : { - "type" : "string", - "description" : "URL that redirects to the back-office section, where is possible to manage the product" - }, - "urlPublic" : { - "type" : "string", - "description" : "URL that redirects to the public information webpage of the product" - } - } - }, - "UpdateSubProductDto" : { - "title" : "UpdateSubProductDto", - "required" : [ "contractTemplatePath", "contractTemplateVersion", "title" ], - "type" : "object", - "properties" : { - "contractTemplatePath" : { - "type" : "string", - "description" : "The path of contract" - }, - "contractTemplateVersion" : { - "type" : "string", - "description" : "Version of the contract" - }, - "institutionContractMappings" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/ContractResource" - }, - "description" : "Product contract based on institutionType" - }, - "title" : { - "type" : "string", - "description" : "Product's title" - } - } - } - }, - "securitySchemes" : { - "bearerAuth" : { - "type" : "http", - "description" : "A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725)", - "scheme" : "bearer", - "bearerFormat" : "JWT" - } - } - } -} \ No newline at end of file diff --git a/onboarding-ms/src/main/resources/application.properties b/onboarding-ms/src/main/resources/application.properties index 7cccccbe7..5bc321a54 100644 --- a/onboarding-ms/src/main/resources/application.properties +++ b/onboarding-ms/src/main/resources/application.properties @@ -43,13 +43,11 @@ quarkus.openapi-generator.codegen.spec.core_json.enable-security-generation=fals quarkus.openapi-generator.codegen.spec.core_json.additional-api-type-annotations=@org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders(it.pagopa.selfcare.onboarding.client.auth.AuthenticationPropagationHeadersFactory.class) quarkus.rest-client."org.openapi.quarkus.core_json.api.OnboardingApi".url=${MS_CORE_URL:http://localhost:8080} -quarkus.openapi-generator.codegen.spec.product_json.mutiny=true -quarkus.openapi-generator.codegen.spec.product_json.additional-model-type-annotations=@lombok.Builder; @lombok.NoArgsConstructor; @lombok.AllArgsConstructor -quarkus.openapi-generator.codegen.spec.product_json.enable-security-generation=false -quarkus.openapi-generator.codegen.spec.product_json.additional-api-type-annotations=@org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders(it.pagopa.selfcare.onboarding.client.auth.AuthenticationPropagationHeadersFactory.class) -quarkus.rest-client."org.openapi.quarkus.product_json.api.ProductApi".url=${MS_PRODUCT_URL:http://localhost:8080} - +## AZURE STORAGE ## +onboarding-ms.blob-storage.container-product=${STORAGE_CONTAINER_PRODUCT:selc-d-product} +onboarding-ms.blob-storage.filepath-product = products.json +onboarding-ms.blob-storage.connection-string-product = ${BLOB_STORAGE_CONN_STRING_PRODUCT:UseDevelopmentStorage=true;} ## Jacoco quarkus.jacoco.includes=it/pagopa/selfcare/controller/*,it/pagopa/selfcare/service/**,it/pagopa/selfcare/repository/** \ No newline at end of file diff --git a/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java b/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java index 9a87c767a..3b464b288 100644 --- a/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java +++ b/onboarding-ms/src/test/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefaultTest.java @@ -15,7 +15,10 @@ import it.pagopa.selfcare.onboarding.entity.Onboarding; import it.pagopa.selfcare.onboarding.exception.InvalidRequestException; import it.pagopa.selfcare.onboarding.exception.OnboardingNotAllowedException; -import it.pagopa.selfcare.onboarding.service.OnboardingServiceDefault; +import it.pagopa.selfcare.product.entity.Product; +import it.pagopa.selfcare.product.entity.ProductRole; +import it.pagopa.selfcare.product.entity.ProductRoleInfo; +import it.pagopa.selfcare.product.service.ProductService; import jakarta.inject.Inject; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response; @@ -24,12 +27,9 @@ import org.jboss.resteasy.reactive.ClientWebApplicationException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.openapi.quarkus.core_json.api.OnboardingApi; import org.openapi.quarkus.onboarding_functions_json.api.OrchestrationApi; import org.openapi.quarkus.onboarding_functions_json.model.OrchestrationResponse; -import org.openapi.quarkus.product_json.api.ProductApi; -import org.openapi.quarkus.product_json.model.*; import org.openapi.quarkus.user_registry_json.api.UserApi; import org.openapi.quarkus.user_registry_json.model.CertifiableFieldResourceOfstring; import org.openapi.quarkus.user_registry_json.model.UserId; @@ -56,8 +56,7 @@ public class OnboardingServiceDefaultTest { UserApi userRegistryApi; @InjectMock - @RestClient - ProductApi productApi; + ProductService productService; @InjectMock @RestClient @@ -111,8 +110,8 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductIsNotValid() { when(userRegistryApi.searchUsingPOST(any(),any())) .thenReturn(Uni.createFrom().item(managerResource)); - when(productApi.getProductIsValidUsingGET(onboardingRequest.getProductId())) - .thenReturn(Uni.createFrom().nullItem()); + when(productService.getProductIsValid(onboardingRequest.getProductId())) + .thenReturn(null); onboardingService.onboardingPa(onboardingRequest) .subscribe().withSubscriber(UniAssertSubscriber.create()) @@ -120,8 +119,8 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductIsNotValid() { verify(userRegistryApi, times(1)) .searchUsingPOST(any(),any()); - verify(productApi, times(1)) - .getProductIsValidUsingGET(onboardingRequest.getProductId()); + verify(productService, times(1)) + .getProductIsValid(onboardingRequest.getProductId()); verifyNoMoreInteractions(userRegistryApi); } @@ -137,10 +136,10 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductIsNotDelegable() { when(userRegistryApi.searchUsingPOST(any(),any())) .thenReturn(Uni.createFrom().item(managerResource)); - ProductResource productResource = new ProductResource(); + Product productResource = new Product(); productResource.setDelegable(Boolean.FALSE); - when(productApi.getProductIsValidUsingGET(onboardingRequest.getProductId())) - .thenReturn(Uni.createFrom().item(productResource)); + when(productService.getProductIsValid(onboardingRequest.getProductId())) + .thenReturn(productResource); onboardingService.onboardingPa(onboardingRequest) .subscribe().withSubscriber(UniAssertSubscriber.create()) @@ -148,8 +147,8 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductIsNotDelegable() { verify(userRegistryApi, times(1)) .searchUsingPOST(any(),any()); - verify(productApi, times(1)) - .getProductIsValidUsingGET(onboardingRequest.getProductId()); + verify(productService, times(1)) + .getProductIsValid(onboardingRequest.getProductId()); verifyNoMoreInteractions(userRegistryApi); } @@ -163,10 +162,10 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductRoleIsNotValid() { when(userRegistryApi.searchUsingPOST(any(),any())) .thenReturn(Uni.createFrom().item(managerResource)); - ProductResource productResource = new ProductResource(); + Product productResource = new Product(); productResource.setRoleMappings(new HashMap<>()); - when(productApi.getProductIsValidUsingGET(onboardingRequest.getProductId())) - .thenReturn(Uni.createFrom().item(productResource)); + when(productService.getProductIsValid(onboardingRequest.getProductId())) + .thenReturn(productResource); onboardingService.onboardingPa(onboardingRequest) .subscribe().withSubscriber(UniAssertSubscriber.create()) @@ -174,8 +173,8 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductRoleIsNotValid() { verify(userRegistryApi, times(1)) .searchUsingPOST(any(),any()); - verify(productApi, times(1)) - .getProductIsValidUsingGET(onboardingRequest.getProductId()); + verify(productService, times(1)) + .getProductIsValid(onboardingRequest.getProductId()); verifyNoMoreInteractions(userRegistryApi); } @@ -189,12 +188,12 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductParentRoleIsNotValid() { when(userRegistryApi.searchUsingPOST(any(),any())) .thenReturn(Uni.createFrom().item(managerResource)); - ProductResource productResource = new ProductResource(); - ProductOperations productParent = new ProductOperations(); + Product productResource = new Product(); + Product productParent = new Product(); productParent.setRoleMappings(new HashMap<>()); - productResource.setProductOperations(productParent); - when(productApi.getProductIsValidUsingGET(onboardingRequest.getProductId())) - .thenReturn(Uni.createFrom().item(productResource)); + productResource.setParent(productParent); + when(productService.getProductIsValid(onboardingRequest.getProductId())) + .thenReturn(productResource); onboardingService.onboardingPa(onboardingRequest) .subscribe().withSubscriber(UniAssertSubscriber.create()) @@ -202,8 +201,8 @@ void onboardingPa_throwExceptionIfUserFoundedAndProductParentRoleIsNotValid() { verify(userRegistryApi, times(1)) .searchUsingPOST(any(),any()); - verify(productApi, times(1)) - .getProductIsValidUsingGET(onboardingRequest.getProductId()); + verify(productService, times(1)) + .getProductIsValid(onboardingRequest.getProductId()); verifyNoMoreInteractions(userRegistryApi); } @@ -274,39 +273,39 @@ void onboardingSa_whenUserFoundedAndWillNotUpdate(UniAsserter asserter) { } void mockSimpleProductValid(String productId) { - ProductResource productResource = createDummyProduct(productId,false); + Product productResource = createDummyProduct(productId,false); - when(productApi.getProductIsValidUsingGET(productId)) - .thenReturn(Uni.createFrom().item(productResource)); + when(productService.getProductIsValid(productId)) + .thenReturn(productResource); } void mockSimpleProductValidAssert(String productId, boolean hasParent, UniAsserter asserter) { - ProductResource productResource = createDummyProduct(productId,hasParent); + Product productResource = createDummyProduct(productId,hasParent); - asserter.execute(() -> when(productApi.getProductIsValidUsingGET(productId)) - .thenReturn(Uni.createFrom().item(productResource))); + asserter.execute(() -> when(productService.getProductIsValid(productId)) + .thenReturn(productResource)); } - ProductResource createDummyProduct(String productId, boolean hasParent) { - ProductResource productResource = new ProductResource(); + Product createDummyProduct(String productId, boolean hasParent) { + Product productResource = new Product(); productResource.setId(productId); - Map roleMapping = new HashMap<>(); - roleMapping.put(manager.getRole().name(), ProductRoleInfoRes.builder() - .roles(List.of(ProductRole.builder().code("admin").build())) - .build()); + Map roleMapping = new HashMap<>(); + ProductRole productRole = new ProductRole(); + productRole.setCode("admin"); + ProductRoleInfo productRoleInfo = new ProductRoleInfo(); + productRoleInfo.setRoles(List.of(productRole)); + roleMapping.put(manager.getRole(), productRoleInfo); productResource.setRoleMappings(roleMapping); if(hasParent) { - ProductOperations parent = new ProductOperations(); + Product parent = new Product(); parent.setId("productParentId"); - Map roleParentMapping = new HashMap<>(); - roleParentMapping.put(manager.getRole().name(), ProductRoleInfoOperations.builder() - .roles(List.of(ProductRoleOperations.builder().code("admin").build())) - .build()); + Map roleParentMapping = new HashMap<>(); + roleParentMapping.put(manager.getRole(), productRoleInfo); parent.setRoleMappings(roleParentMapping); - productResource.setProductOperations(parent); + productResource.setParent(parent); } return productResource; From 1df14816f8c3882f776a7627294c0efffb6aa8dc Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 12:28:26 +0100 Subject: [PATCH 02/20] introduce ONBOARDING_ORCHESTRATION_ENABLED --- onboarding-ms/src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/onboarding-ms/src/main/resources/application.properties b/onboarding-ms/src/main/resources/application.properties index 5bc321a54..9d560e219 100644 --- a/onboarding-ms/src/main/resources/application.properties +++ b/onboarding-ms/src/main/resources/application.properties @@ -18,6 +18,7 @@ quarkus.mongodb.database = selcOnboarding onboarding.institutions-allowed-list=${ONBOARDING_ALLOWED_INSTITUTIONS_PRODUCTS} onboarding.expiring-date = ${ONBOARDING_EXPIRING_DATE:60} +onboarding.orchestration.enabled = ${ONBOARDING_ORCHESTRATION_ENABLED:true} #quarkus.native.resources.includes=publicKey.pem From a240fa6c83f85473b18d70fef684c810b9633b01 Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 12:53:03 +0100 Subject: [PATCH 03/20] rename env variable for secret convention --- onboarding-ms/README.md | 32 ++++++++++++++----- .../src/main/resources/application.properties | 8 ++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/onboarding-ms/README.md b/onboarding-ms/README.md index 991e88abd..a134372f5 100644 --- a/onboarding-ms/README.md +++ b/onboarding-ms/README.md @@ -4,11 +4,24 @@ Repository that contains backend services synch for selfcare onboarding. It implements CRUD operations for the 'onboarding' object and the business logic for the onboarding phase. During the onboarding process, the following activities are executed: -- Check for the presence of users associated with the onboarding and potentially add them to the point of sale (pdv). -- Validate the requested product's suitability and verify eligible roles. -- Verify if there is an existing onboarding record for that institution and product. +1. Check for the presence of users associated with the onboarding and potentially add them to the point of sale (pdv). +2. Validate the requested product's suitability and verify eligible roles. +3. Verify if there is an existing onboarding record for that institution and product. -After the data is saved, it invokes the function implemented by onboarding-functions to trigger asynchronous onboarding activities." +After the data is saved, it invokes the function implemented by onboarding-functions to trigger asynchronous onboarding activities. + +### Disable starting async onboarding workflow + +````properties +env ONBOARDING_ORCHESTRATION_ENABLED=false. +```` +### Allowed onboarding product with status TESTING + +ONBOARDING_ALLOWED_INSTITUTIONS_PRODUCTS property permits onboarding for product with status TESTING. It can contain a map of entry with product as key and a list of taxcode as value. + +````properties +ONBOARDING_ALLOWED_INSTITUTIONS_PRODUCTS={'prod-interop': ['0123456789']}. +```` ## Configuration Properties @@ -17,15 +30,18 @@ Before running you must set these properties as environment variables. | **Property** | **Environment Variable** | **Default** | **Required** | |--------------------------------------------------------|------------------------------------------|-------------|:------------:| -| quarkus.mongodb.connection-string
| MONGODB_CONNECTION_URI | | yes | -| mp.jwt.verify.publickey
| JWT_TOKEN_PUBLIC_KEY | | yes | -| quarkus.rest-client."**.UserApi".api-key
| USER_REGISTRY_API_KEY | | yes | +| quarkus.mongodb.connection-string
| MONGODB-CONNECTION-STRING | | yes | +| mp.jwt.verify.publickey
| JWT-PUBLIC-KEY | | yes | +| quarkus.rest-client."**.UserApi".api-key
| USER-REGISTRY-API-KEY | | yes | | quarkus.rest-client."**.UserApi".url
| USER_REGISTRY_URL | | yes | | quarkus.rest-client."**.ProductApi".url
| MS_PRODUCT_URL | | yes | | quarkus.rest-client."**.OrchestrationApi".url
| ONBOARDING_FUNCTIONS_URL | | yes | -| quarkus.rest-client."**.OrchestrationApi".api-key
| ONBOARDING_FUNCTIONS_API_KEY | | yes | +| quarkus.rest-client."**.OrchestrationApi".api-key
| ONBOARDING-FUNCTIONS-API-KEY | | yes | | onboarding.institutions-allowed-list
| ONBOARDING_ALLOWED_INSTITUTIONS_PRODUCTS | | no | +> **_NOTE:_** properties that contains secret must have the same name of its secret as uppercase. + + ## Running the application in dev mode You can run your application in dev mode that enables live coding using: diff --git a/onboarding-ms/src/main/resources/application.properties b/onboarding-ms/src/main/resources/application.properties index 9d560e219..db9abaa7a 100644 --- a/onboarding-ms/src/main/resources/application.properties +++ b/onboarding-ms/src/main/resources/application.properties @@ -4,7 +4,7 @@ quarkus.http.port=8080 quarkus.smallrye-jwt.blocking-authentication=true quarkus.http.auth.proactive=false -mp.jwt.verify.publickey=${JWT_TOKEN_PUBLIC_KEY} +mp.jwt.verify.publickey=${JWT-PUBLIC-KEY} mp.jwt.verify.issuer=SPID #smallrye.jwt.verify.key-format=JWK_BASE64URL @@ -13,7 +13,7 @@ smallrye.jwt.path.sub=name quarkus.log.level=INFO -quarkus.mongodb.connection-string = ${MONGODB_CONNECTION_URI} +quarkus.mongodb.connection-string = ${MONGODB-CONNECTION-STRING} quarkus.mongodb.database = selcOnboarding onboarding.institutions-allowed-list=${ONBOARDING_ALLOWED_INSTITUTIONS_PRODUCTS} @@ -30,12 +30,12 @@ quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG quarkus.openapi-generator.codegen.spec.onboarding_functions_json.mutiny=true quarkus.openapi-generator.codegen.spec.onboarding_functions_json.additional-model-type-annotations=@lombok.Builder; @lombok.NoArgsConstructor; @lombok.AllArgsConstructor -quarkus.openapi-generator.onboarding_functions_json.auth.api_key.api-key = ${ONBOARDING_FUNCTIONS_API_KEY:example-api-key} +quarkus.openapi-generator.onboarding_functions_json.auth.api_key.api-key = ${ONBOARDING-FUNCTIONS-API-KEY:example-api-key} quarkus.rest-client."org.openapi.quarkus.onboarding_functions_json.api.OrchestrationApi".url=${ONBOARDING_FUNCTIONS_URL:http://localhost:8080} quarkus.openapi-generator.codegen.spec.user_registry_json.mutiny=true quarkus.openapi-generator.codegen.spec.user_registry_json.additional-model-type-annotations=@lombok.Builder; @lombok.NoArgsConstructor; @lombok.AllArgsConstructor -quarkus.openapi-generator.user_registry_json.auth.api_key.api-key = ${USER_REGISTRY_API_KEY:example-api-key} +quarkus.openapi-generator.user_registry_json.auth.api_key.api-key = ${USER-REGISTRY-API-KEY:example-api-key} quarkus.rest-client."org.openapi.quarkus.user_registry_json.api.UserApi".url=${USER_REGISTRY_URL:http://localhost:8080} quarkus.openapi-generator.codegen.spec.core_json.mutiny=true From bcbad9533f899dcdfddc0f76d7354589e3b8f73a Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 12:55:42 +0100 Subject: [PATCH 04/20] fix code review workflow --- .github/workflows/code_review_ms.yml | 51 ++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 903eeb15b..e3876af33 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -13,17 +13,46 @@ on: paths: - 'onboarding-ms/**' -permissions: - id-token: write - contents: read - deployments: write - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: code-review: - name: Code review onboarding-ms - # The type of runner that the job will run on - uses: pagopa/selfcare-onboarding/.github/workflows/code_review.yml@develop - with: - module: onboarding-ms \ No newline at end of file + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: 'temurin' + + - name: Cache Maven packages + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Cache SonarCloud packages + uses: actions/cache@v1 + with: + path: ~/.sonar-project.properties/cache + key: ${{ runner.os }}-sonar-project.properties + restore-keys: ${{ runner.os }}-sonar-project.properties + + - name: Build and analyze on Pull Requests + shell: bash + run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + -Dsonar.organization=pagopa + -Dsonar.projectKey=pagopa_selfcare-onboarding + -Dsonar.coverage.jacoco.xmlReportPaths=./target/jacoco-report/jacoco.xml + -Dsonar.host.url=https://sonarcloud.io + -Dsonar.token=${{ secrets.SONAR_TOKEN }} + -Dsonar.coverage.exclusions='**/exception/**, **/response/**, **/request/**, **/entity/**, **/utils/**, **/*Constant*, **/*Config.java, **/src/test/**' + -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} + -Dsonar.pullrequest.branch=${{ github.head_ref }} + -Dsonar.pullrequest.base=${{ github.base_ref }} + --file onboarding-ms/pom.xml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file From 38d5c0e218e914edfa462963349fa50b8de927bb Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 13:03:07 +0100 Subject: [PATCH 05/20] fix code review functions --- .github/workflows/code_review.yml | 52 -------------------- .github/workflows/code_review_functions.yml | 53 ++++++++++++++++----- .github/workflows/code_review_ms.yml | 2 + 3 files changed, 44 insertions(+), 63 deletions(-) delete mode 100644 .github/workflows/code_review.yml diff --git a/.github/workflows/code_review.yml b/.github/workflows/code_review.yml deleted file mode 100644 index 253730a27..000000000 --- a/.github/workflows/code_review.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Code Review - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - - code-review: - # The type of runner that the job will run on - runs-on: ubuntu-latest - env: - module: ${{ inputs.module || env.MODULE }} - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: 17 - distribution: 'temurin' - - - name: Cache Maven packages - uses: actions/cache@v1 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - - name: Cache SonarCloud packages - uses: actions/cache@v1 - with: - path: ~/.sonar-project.properties/cache - key: ${{ runner.os }}-sonar-project.properties - restore-keys: ${{ runner.os }}-sonar-project.properties - - - name: Build and analyze on Pull Requests - shell: bash - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar - -Dsonar.organization=pagopa - -Dsonar.projectKey=pagopa_selfcare-onboarding - -Dsonar.coverage.jacoco.xmlReportPaths=./target/jacoco-report/jacoco.xml - -Dsonar.host.url=https://sonarcloud.io - -Dsonar.token=${{ secrets.SONAR_TOKEN }} - -Dsonar.coverage.exclusions='**/exception/**, **/response/**, **/request/**, **/entity/**, **/utils/**, **/*Constant*, **/*Config.java, **/src/test/**' - -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} - -Dsonar.pullrequest.branch=${{ github.head_ref }} - -Dsonar.pullrequest.base=${{ github.base_ref }} - --file ${{ inputs.module }}/pom.xml - env: - # Needed to get some information about the pull request, if any - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # SonarCloud access token should be generated from https://sonarcloud.io/account/security/ - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/code_review_functions.yml b/.github/workflows/code_review_functions.yml index f726471f0..2689d0eef 100644 --- a/.github/workflows/code_review_functions.yml +++ b/.github/workflows/code_review_functions.yml @@ -12,18 +12,49 @@ on: - reopened paths: - 'onboarding-functions/**' + + workflow_dispatch: -permissions: - id-token: write - contents: read - deployments: write - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: code-review: - name: Code review onboarding-ms - # The type of runner that the job will run on - uses: pagopa/selfcare-onboarding/.github/workflows/code_review.yml@develop - with: - module: onboarding-functions \ No newline at end of file + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: 'temurin' + + - name: Cache Maven packages + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Cache SonarCloud packages + uses: actions/cache@v1 + with: + path: ~/.sonar-project.properties/cache + key: ${{ runner.os }}-sonar-project.properties + restore-keys: ${{ runner.os }}-sonar-project.properties + + - name: Build and analyze on Pull Requests + shell: bash + run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + -Dsonar.organization=pagopa + -Dsonar.projectKey=pagopa_selfcare-onboarding + -Dsonar.coverage.jacoco.xmlReportPaths=./target/jacoco-report/jacoco.xml + -Dsonar.host.url=https://sonarcloud.io + -Dsonar.token=${{ secrets.SONAR_TOKEN }} + -Dsonar.coverage.exclusions='**/exception/**, **/response/**, **/request/**, **/entity/**, **/utils/**, **/*Constant*, **/*Config.java, **/src/test/**' + -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} + -Dsonar.pullrequest.branch=${{ github.head_ref }} + -Dsonar.pullrequest.base=${{ github.base_ref }} + --file onboarding-functions/pom.xml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index e3876af33..b63e41b2a 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -12,6 +12,8 @@ on: - reopened paths: - 'onboarding-ms/**' + + workflow_dispatch: jobs: From 39e67f9a1f2441b8e9811c6bb99eceb6d1de0e25 Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 13:41:31 +0100 Subject: [PATCH 06/20] add permissions packages read --- .github/workflows/code_review_functions.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/code_review_functions.yml b/.github/workflows/code_review_functions.yml index 2689d0eef..f6bdfeb5a 100644 --- a/.github/workflows/code_review_functions.yml +++ b/.github/workflows/code_review_functions.yml @@ -19,6 +19,8 @@ jobs: code-review: runs-on: ubuntu-latest + permissions: + packages: read steps: - uses: actions/checkout@v4 From a3a7538828bc9ab1893c29b4f43b068e15f1060d Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 14:12:06 +0100 Subject: [PATCH 07/20] permissions packages read --- .github/workflows/code_review_ms.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index b63e41b2a..0f4c94058 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -19,6 +19,8 @@ jobs: code-review: runs-on: ubuntu-latest + permissions: + packages: read steps: - uses: actions/checkout@v4 From 08f97182d8b95f27ee71ce67a7302e8363d4e559 Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 14:20:18 +0100 Subject: [PATCH 08/20] add id-token write --- .github/workflows/code_review_ms.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 0f4c94058..893ac0e55 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -21,6 +21,7 @@ jobs: runs-on: ubuntu-latest permissions: packages: read + id-token: write steps: - uses: actions/checkout@v4 @@ -46,6 +47,8 @@ jobs: - name: Build and analyze on Pull Requests shell: bash + secrets: | + GH_TOKEN=${{ secrets.READ_PACKAGES_TOKEN }} run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.organization=pagopa -Dsonar.projectKey=pagopa_selfcare-onboarding From 595216087a5fbd946783c75f38010fe1094da3ec Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 14:20:51 +0100 Subject: [PATCH 09/20] fix secrets --- .github/workflows/code_review_ms.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 893ac0e55..dc12cacb2 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -47,8 +47,8 @@ jobs: - name: Build and analyze on Pull Requests shell: bash - secrets: | - GH_TOKEN=${{ secrets.READ_PACKAGES_TOKEN }} + secrets: | + GH_TOKEN=${{ secrets.READ_PACKAGES_TOKEN }} run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.organization=pagopa -Dsonar.projectKey=pagopa_selfcare-onboarding From 553a3e5930f6b276eaf71d14875a885f3ec1c328 Mon Sep 17 00:00:00 2001 From: manuraf Date: Fri, 3 Nov 2023 14:25:32 +0100 Subject: [PATCH 10/20] remove secrets --- .github/workflows/code_review_ms.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index dc12cacb2..9231ea3bc 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -47,8 +47,6 @@ jobs: - name: Build and analyze on Pull Requests shell: bash - secrets: | - GH_TOKEN=${{ secrets.READ_PACKAGES_TOKEN }} run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.organization=pagopa -Dsonar.projectKey=pagopa_selfcare-onboarding @@ -62,4 +60,5 @@ jobs: --file onboarding-ms/pom.xml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.READ_PACKAGES_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file From 5886c7920e868b07299c0d286a5e4497ed0b60db Mon Sep 17 00:00:00 2001 From: manuraf Date: Sat, 4 Nov 2023 18:40:18 +0100 Subject: [PATCH 11/20] fix unit test --- .github/workflows/code_review_ms.yml | 2 +- .../selfcare/onboarding/service/OnboardingServiceDefault.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 9231ea3bc..4ab8fde73 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -22,6 +22,7 @@ jobs: permissions: packages: read id-token: write + deployments: write steps: - uses: actions/checkout@v4 @@ -60,5 +61,4 @@ jobs: --file onboarding-ms/pom.xml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_TOKEN: ${{ secrets.READ_PACKAGES_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java b/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java index 24ef53dc2..061e771d7 100644 --- a/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java +++ b/onboarding-ms/src/main/java/it/pagopa/selfcare/onboarding/service/OnboardingServiceDefault.java @@ -121,7 +121,7 @@ public Uni checkProductAndReturnOnboarding(Onboarding onboarding) { final Product product; try { - product = Optional.of(productService.getProductIsValid(onboarding.getProductId())) + product = Optional.ofNullable(productService.getProductIsValid(onboarding.getProductId())) .orElseThrow(() -> new OnboardingNotAllowedException(String.format(UNABLE_TO_COMPLETE_THE_ONBOARDING_FOR_INSTITUTION_FOR_PRODUCT_DISMISSED, onboarding.getInstitution().getTaxCode(), onboarding.getProductId()), DEFAULT_ERROR.getCode())); From 4b4834a3ee55428dadb177c07813d4e5732fa9be Mon Sep 17 00:00:00 2001 From: manuraf Date: Sat, 4 Nov 2023 18:45:39 +0100 Subject: [PATCH 12/20] remove maven cache --- .github/workflows/code_review_ms.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 4ab8fde73..5bcd0760e 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -22,7 +22,6 @@ jobs: permissions: packages: read id-token: write - deployments: write steps: - uses: actions/checkout@v4 @@ -32,20 +31,6 @@ jobs: java-version: 17 distribution: 'temurin' - - name: Cache Maven packages - uses: actions/cache@v1 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - - name: Cache SonarCloud packages - uses: actions/cache@v1 - with: - path: ~/.sonar-project.properties/cache - key: ${{ runner.os }}-sonar-project.properties - restore-keys: ${{ runner.os }}-sonar-project.properties - - name: Build and analyze on Pull Requests shell: bash run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar From 11371b8373891723715988e55a597ddb23275293 Mon Sep 17 00:00:00 2001 From: manuraf Date: Sat, 4 Nov 2023 18:49:49 +0100 Subject: [PATCH 13/20] add maven-settings-action --- .github/workflows/code_review_ms.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 5bcd0760e..01620a1dc 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -30,6 +30,10 @@ jobs: with: java-version: 17 distribution: 'temurin' + - uses: s4u/maven-settings-action@v2.5.0 + with: + servers: '[ + {"id": "github","configuration": {"httpHeaders": {"property": {"name": "Authorization","value": "Bearer ${{ secrets.GITHUB_TOKEN }}"}}}}]' - name: Build and analyze on Pull Requests shell: bash From affe9dd7a7c11d9c685c86e8272ebbbe9dc9d693 Mon Sep 17 00:00:00 2001 From: manuraf Date: Sat, 4 Nov 2023 18:52:12 +0100 Subject: [PATCH 14/20] maven-settings-action v2.8.0 --- .github/workflows/code_review_ms.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 01620a1dc..a083564f8 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -30,11 +30,11 @@ jobs: with: java-version: 17 distribution: 'temurin' - - uses: s4u/maven-settings-action@v2.5.0 - with: - servers: '[ - {"id": "github","configuration": {"httpHeaders": {"property": {"name": "Authorization","value": "Bearer ${{ secrets.GITHUB_TOKEN }}"}}}}]' + - uses: s4u/maven-settings-action@v2.8.0 + with: + servers: '[{"id": "github", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}]' + - name: Build and analyze on Pull Requests shell: bash run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar From 01bb3f48196bdf0201f96857b669c3c4797b8125 Mon Sep 17 00:00:00 2001 From: manuraf Date: Sat, 4 Nov 2023 18:55:23 +0100 Subject: [PATCH 15/20] selfcare-github as id server --- .github/workflows/code_review_ms.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index a083564f8..9f376690d 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -33,8 +33,8 @@ jobs: - uses: s4u/maven-settings-action@v2.8.0 with: - servers: '[{"id": "github", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}]' - + servers: '[{"id": "selfcare-github", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}]' + - name: Build and analyze on Pull Requests shell: bash run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar From 4e8535d8519cc6fb070692f2230bd3355202c218 Mon Sep 17 00:00:00 2001 From: manuraf Date: Tue, 7 Nov 2023 16:12:34 +0100 Subject: [PATCH 16/20] add sparse-checkout for monorepo --- .github/workflows/code_review_ms.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index 9f376690d..eab34f801 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -11,7 +11,7 @@ on: - synchronize - reopened paths: - - 'onboarding-ms/**' + - 'apps/onboarding-ms/**' workflow_dispatch: @@ -24,6 +24,10 @@ jobs: id-token: write steps: - uses: actions/checkout@v4 + with: + sparse-checkout: | + apps/onboarding-ms + libs/ - name: Set up JDK 17 uses: actions/setup-java@v3 @@ -31,10 +35,6 @@ jobs: java-version: 17 distribution: 'temurin' - - uses: s4u/maven-settings-action@v2.8.0 - with: - servers: '[{"id": "selfcare-github", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}]' - - name: Build and analyze on Pull Requests shell: bash run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar From a70b72e7784ba73d73c35007417573896e81f7b7 Mon Sep 17 00:00:00 2001 From: manuraf Date: Tue, 7 Nov 2023 16:12:50 +0100 Subject: [PATCH 17/20] add maven settings for release sdk --- .github/workflows/release_onboarding_sdk.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release_onboarding_sdk.yml b/.github/workflows/release_onboarding_sdk.yml index 021899f56..b41bdb098 100644 --- a/.github/workflows/release_onboarding_sdk.yml +++ b/.github/workflows/release_onboarding_sdk.yml @@ -13,6 +13,8 @@ jobs: - uses: actions/checkout@v3 with: ref: ${{ github.ref_name }} + sparse-checkout: | + libs/onboarding-sdk - name: Set up JDK 17 uses: actions/setup-java@v3 @@ -21,6 +23,10 @@ jobs: java-version: '17' cache: maven + - uses: s4u/maven-settings-action@v2.8.0 + with: + servers: '[{"id": "selfcare-github", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}]' + - name: Build with Maven run: mvn --projects :onboarding-sdk --also-make-dependents clean package -DskipTests shell: bash From 14899a36365b283d846ecc26c70fe15eecc1be86 Mon Sep 17 00:00:00 2001 From: manuraf Date: Tue, 7 Nov 2023 17:29:04 +0100 Subject: [PATCH 18/20] test ls workflow --- .github/workflows/code_review_ms.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index eab34f801..c9a909c9e 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -28,6 +28,11 @@ jobs: sparse-checkout: | apps/onboarding-ms libs/ + - run: | + ls . + ls ./apps + ls ./apps/onboarding-ms + - name: Set up JDK 17 uses: actions/setup-java@v3 From ffdb308d5456fa99aaadbba5983d458cff92a505 Mon Sep 17 00:00:00 2001 From: manuraf Date: Tue, 7 Nov 2023 17:31:55 +0100 Subject: [PATCH 19/20] fix launch verify --- .github/workflows/code_review_ms.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/code_review_ms.yml b/.github/workflows/code_review_ms.yml index c9a909c9e..a541e077d 100644 --- a/.github/workflows/code_review_ms.yml +++ b/.github/workflows/code_review_ms.yml @@ -28,11 +28,6 @@ jobs: sparse-checkout: | apps/onboarding-ms libs/ - - run: | - ls . - ls ./apps - ls ./apps/onboarding-ms - - name: Set up JDK 17 uses: actions/setup-java@v3 @@ -42,7 +37,7 @@ jobs: - name: Build and analyze on Pull Requests shell: bash - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + run: mvn --projects :onboarding-ms --also-make verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.organization=pagopa -Dsonar.projectKey=pagopa_selfcare-onboarding -Dsonar.coverage.jacoco.xmlReportPaths=./target/jacoco-report/jacoco.xml @@ -52,7 +47,6 @@ jobs: -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} -Dsonar.pullrequest.branch=${{ github.head_ref }} -Dsonar.pullrequest.base=${{ github.base_ref }} - --file onboarding-ms/pom.xml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file From 16e53f6dcda43b1da63b47ead0898b4192200f64 Mon Sep 17 00:00:00 2001 From: manuraf Date: Wed, 8 Nov 2023 14:52:04 +0100 Subject: [PATCH 20/20] add secret connection string --- .container_apps/onboarding-ms/env/dev/terraform.tfvars | 7 ++++++- .../src/main/resources/application.properties | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.container_apps/onboarding-ms/env/dev/terraform.tfvars b/.container_apps/onboarding-ms/env/dev/terraform.tfvars index 1c0624e84..a027f4eca 100644 --- a/.container_apps/onboarding-ms/env/dev/terraform.tfvars +++ b/.container_apps/onboarding-ms/env/dev/terraform.tfvars @@ -29,6 +29,10 @@ app_settings = [ { name = "ONBOARDING_ALLOWED_INSTITUTIONS_PRODUCTS" value = "{'prod-interop': ['*'], 'prod-pn': ['*'], 'prod-io': ['*'], 'prod-io-premium': ['*'], 'prod-pagopa': ['*'], 'prod-fd': ['*'], 'prod-fd-garantito': ['*']}" + }, + { + name = "STORAGE_CONTAINER_PRODUCT" + value = "product" } ] @@ -39,6 +43,7 @@ key_vault = { "jwt-public-key", "mongodb-connection-string", "user-registry-api-key", - "onboarding-functions-api-key" + "onboarding-functions-api-key", + "blob-storage-product-connection-string" ] } diff --git a/apps/onboarding-ms/src/main/resources/application.properties b/apps/onboarding-ms/src/main/resources/application.properties index db9abaa7a..5f4d957e7 100644 --- a/apps/onboarding-ms/src/main/resources/application.properties +++ b/apps/onboarding-ms/src/main/resources/application.properties @@ -48,7 +48,7 @@ quarkus.rest-client."org.openapi.quarkus.core_json.api.OnboardingApi".url=${MS_C onboarding-ms.blob-storage.container-product=${STORAGE_CONTAINER_PRODUCT:selc-d-product} onboarding-ms.blob-storage.filepath-product = products.json -onboarding-ms.blob-storage.connection-string-product = ${BLOB_STORAGE_CONN_STRING_PRODUCT:UseDevelopmentStorage=true;} +onboarding-ms.blob-storage.connection-string-product = ${BLOB-STORAGE-PRODUCT-CONNECTION-STRING:UseDevelopmentStorage=true;} ## Jacoco quarkus.jacoco.includes=it/pagopa/selfcare/controller/*,it/pagopa/selfcare/service/**,it/pagopa/selfcare/repository/** \ No newline at end of file