From 6fba44d67c4a44894d41c3c9672d322226cd6fe6 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Mon, 5 Feb 2024 14:27:25 +0100 Subject: [PATCH 1/5] Added user openAPI, userConnector and User rest Client --- app/src/main/resources/config/application.yml | 7 +- .../connector/api/UserApiConnector.java | 15 + .../rest/docs/openapi/api-user-docs.json | 1094 +++++++++++++++++ connector/rest/pom.xml | 38 + .../connector/rest/UserConnectorImpl.java | 57 + .../rest/client/UserApiRestClient.java | 8 + .../rest/config/UserApiRestClientConfig.java | 15 + .../model/mapper/InstitutionV2Mapper.java | 30 + .../rest/model/mapper/UserMapper.java | 46 + .../config/user-rest-client.properties | 2 + .../connector/rest/UserConnectorImplTest.java | 97 ++ 11 files changed, 1408 insertions(+), 1 deletion(-) create mode 100644 connector-api/src/main/java/it/pagopa/selfcare/dashboard/connector/api/UserApiConnector.java create mode 100644 connector/rest/docs/openapi/api-user-docs.json create mode 100644 connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java create mode 100644 connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java create mode 100644 connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/config/UserApiRestClientConfig.java create mode 100644 connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java create mode 100644 connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/UserMapper.java create mode 100644 connector/rest/src/main/resources/config/user-rest-client.properties create mode 100644 connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index 9eb31384c..123975bb9 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -29,4 +29,9 @@ logging: level: it.pagopa.selfcare: ${B4F_DASHBOARD_LOG_LEVEL:DEBUG} pattern: - additional-info: ",%X{X-Client-Ip:-}]" \ No newline at end of file + additional-info: ",%X{X-Client-Ip:-}]" + +dashboard: + user: + client: + api-version: ${B4F_DASHBOARD_USER_CLIENT_API_VERSION:v1} \ No newline at end of file diff --git a/connector-api/src/main/java/it/pagopa/selfcare/dashboard/connector/api/UserApiConnector.java b/connector-api/src/main/java/it/pagopa/selfcare/dashboard/connector/api/UserApiConnector.java new file mode 100644 index 000000000..d18a0700d --- /dev/null +++ b/connector-api/src/main/java/it/pagopa/selfcare/dashboard/connector/api/UserApiConnector.java @@ -0,0 +1,15 @@ +package it.pagopa.selfcare.dashboard.connector.api; + +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; + +import java.util.List; + + +public interface UserApiConnector { + + void updateUser(String userId, String institutionId, MutableUserFieldsDto userDto); + + List getUserProducts(String userId); + +} diff --git a/connector/rest/docs/openapi/api-user-docs.json b/connector/rest/docs/openapi/api-user-docs.json new file mode 100644 index 000000000..054a77d7d --- /dev/null +++ b/connector/rest/docs/openapi/api-user-docs.json @@ -0,0 +1,1094 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "User API (development)", + "version": "1.0.0" + }, + "paths": { + "/institutions/{institutionId}/products/{productId}/createdAt": { + "put": { + "tags": [ + "Institution Controller" + ], + "summary": "The API updates user's onboarded product with createdAt passed in input", + "parameters": [ + { + "name": "institutionId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "productId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "createdAt", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/LocalDateTime" + } + }, + { + "name": "userIds", + "in": "query", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": {} + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/institutions/{institutionId}/user-institutions": { + "get": { + "tags": [ + "Institution Controller" + ], + "summary": "The API retrieves users with optional filters in input as query params", + "parameters": [ + { + "name": "institutionId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "productRoles", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "products", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "roles", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "states", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "userId", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserInstitutionResponse" + } + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/institutions/{institutionId}/users": { + "get": { + "tags": [ + "Institution Controller" + ], + "summary": "The API retrieves user's info including details of roles on products", + "parameters": [ + { + "name": "institutionId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserProductResponse" + } + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users": { + "get": { + "tags": [ + "User Controller" + ], + "summary": "The API retrieves paged users with optional filters in input as query params", + "parameters": [ + { + "name": "institutionId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "schema": { + "format": "int32", + "default": "0", + "type": "integer" + } + }, + { + "name": "productRoles", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "products", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "roles", + "in": "query", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PartyRole" + } + } + }, + { + "name": "size", + "in": "query", + "schema": { + "format": "int32", + "default": "100", + "type": "integer" + } + }, + { + "name": "states", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "userId", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserInstitutionResponse" + } + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/emails": { + "get": { + "tags": [ + "User Controller" + ], + "summary": "The API retrieves Users' emails using institution id and product id", + "parameters": [ + { + "name": "institutionId", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "productId", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/ids": { + "get": { + "tags": [ + "User Controller" + ], + "summary": "Retrieve all users given their userIds", + "parameters": [ + { + "name": "userIds", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserInstitutionResponse" + } + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/notification": { + "get": { + "tags": [ + "User Controller" + ], + "summary": "Retrieve all SC-User for DataLake filtered by optional productId", + "parameters": [ + { + "name": "page", + "in": "query", + "schema": { + "format": "int32", + "default": "0", + "type": "integer" + } + }, + { + "name": "productId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "size", + "in": "query", + "schema": { + "format": "int32", + "default": "100", + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UsersNotificationResponse" + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/{id}": { + "get": { + "tags": [ + "User Controller" + ], + "summary": "Retrieves user given userId and optional ProductId", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "institutionId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "productId", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserResponse" + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/{id}/status": { + "put": { + "tags": [ + "User Controller" + ], + "summary": "Update user status with optional filter for institution, product, role and productRole", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "institutionId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "productId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "productRole", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "role", + "in": "query", + "schema": { + "$ref": "#/components/schemas/PartyRole" + } + }, + { + "name": "status", + "in": "query", + "schema": { + "$ref": "#/components/schemas/OnboardedProductState" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": {} + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/{id}/user-registry": { + "put": { + "tags": [ + "User Controller" + ], + "summary": "Service to update user in user-registry and send notification when user data gets updated", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "institutionId", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRegistryFieldsDto" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": {} + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/{userId}/institutions/{institutionId}/products/{productId}": { + "delete": { + "tags": [ + "User Controller" + ], + "summary": "Delete logically the association institution and product", + "parameters": [ + { + "name": "institutionId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "productId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "userId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + }, + "/users/{userId}/products": { + "get": { + "tags": [ + "User Controller" + ], + "summary": "Retrieves products info and role which the user is enabled", + "parameters": [ + { + "name": "userId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "institutionId", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "states", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserProductsResponse" + } + } + } + }, + "401": { + "description": "Not Authorized" + }, + "403": { + "description": "Not Allowed" + } + }, + "security": [ + { + "SecurityScheme": [] + } + ] + } + } + }, + "components": { + "schemas": { + "CertifiableFieldResourceOfLocalDate": { + "type": "object", + "properties": { + "certification": { + "$ref": "#/components/schemas/CertificationEnum1" + }, + "value": { + "$ref": "#/components/schemas/LocalDate" + } + } + }, + "CertifiableFieldResourceOfstring": { + "type": "object", + "properties": { + "certification": { + "$ref": "#/components/schemas/CertificationEnum" + }, + "value": { + "type": "string" + } + } + }, + "CertificationEnum": { + "enum": [ + "NONE", + "SPID" + ], + "type": "string" + }, + "CertificationEnum1": { + "enum": [ + "NONE", + "SPID" + ], + "type": "string" + }, + "Env": { + "enum": [ + "ROOT", + "DEV", + "COLL", + "PROD" + ], + "type": "string" + }, + "InstitutionProducts": { + "type": "object", + "properties": { + "institutionId": { + "type": "string" + }, + "institutionName": { + "type": "string" + }, + "institutionRootName": { + "type": "string" + }, + "products": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OnboardedProductResponse" + } + } + } + }, + "LocalDate": { + "format": "date", + "type": "string", + "example": "2022-03-10T00:00:00.000Z" + }, + "LocalDateTime": { + "format": "date-time", + "type": "string", + "example": "2022-03-10T12:15:50.000Z" + }, + "UserRegistryFieldsDto": { + "type": "object", + "properties": { + "birthDate": { + "$ref": "#/components/schemas/CertifiableFieldResourceOfLocalDate" + }, + "email": { + "$ref": "#/components/schemas/CertifiableFieldResourceOfstring" + }, + "familyName": { + "$ref": "#/components/schemas/CertifiableFieldResourceOfstring" + }, + "name": { + "$ref": "#/components/schemas/CertifiableFieldResourceOfstring" + }, + "workContacts": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/WorkContactResource" + } + } + } + }, + "OnboardedProductResponse": { + "type": "object", + "properties": { + "productId": { + "type": "string" + }, + "relationshipId": { + "type": "string" + }, + "tokenId": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/OnboardedProductState" + }, + "productRole": { + "type": "string" + }, + "role": { + "$ref": "#/components/schemas/PartyRole" + }, + "env": { + "$ref": "#/components/schemas/Env" + }, + "createdAt": { + "$ref": "#/components/schemas/LocalDateTime" + }, + "updatedAt": { + "$ref": "#/components/schemas/LocalDateTime" + } + } + }, + "OnboardedProductState": { + "enum": [ + "ACTIVE", + "PENDING", + "TOBEVALIDATED", + "SUSPENDED", + "DELETED", + "REJECTED" + ], + "type": "string" + }, + "PartyRole": { + "enum": [ + "MANAGER", + "DELEGATE", + "SUB_DELEGATE", + "OPERATOR" + ], + "type": "string" + }, + "QueueEvent": { + "enum": [ + "ADD", + "UPDATE" + ], + "type": "string" + }, + "UserInstitutionResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "institutionId": { + "type": "string" + }, + "institutionDescription": { + "type": "string" + }, + "products": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OnboardedProductResponse" + } + } + } + }, + "UserNotificationResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "institutionId": { + "type": "string" + }, + "productId": { + "type": "string" + }, + "onboardingTokenId": { + "type": "string" + }, + "createdAt": { + "$ref": "#/components/schemas/LocalDateTime" + }, + "updatedAt": { + "$ref": "#/components/schemas/LocalDateTime" + }, + "eventType": { + "$ref": "#/components/schemas/QueueEvent" + }, + "user": { + "$ref": "#/components/schemas/UserToNotify" + } + } + }, + "UserProductResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "taxCode": { + "type": "string" + }, + "name": { + "type": "string" + }, + "surname": { + "type": "string" + }, + "email": { + "type": "string" + }, + "products": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OnboardedProductResponse" + } + } + } + }, + "UserProductsResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "bindings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InstitutionProducts" + } + } + } + }, + "UserResponse": { + "required": [ + "id", + "name", + "surname" + ], + "type": "object", + "properties": { + "id": { + "minLength": 1, + "type": "string" + }, + "taxCode": { + "type": "string" + }, + "name": { + "pattern": "\\S", + "type": "string" + }, + "surname": { + "pattern": "\\S", + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserToNotify": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "familyName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "$ref": "#/components/schemas/PartyRole" + }, + "productRole": { + "type": "string" + }, + "relationshipStatus": { + "$ref": "#/components/schemas/OnboardedProductState" + } + } + }, + "UsersNotificationResponse": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserNotificationResponse" + } + } + } + }, + "WorkContactResource": { + "type": "object", + "properties": { + "email": { + "$ref": "#/components/schemas/CertifiableFieldResourceOfstring" + } + } + } + }, + "securitySchemes": { + "SecurityScheme": { + "type": "http", + "description": "Authentication", + "scheme": "bearer", + "bearerFormat": "JWT" + } + } + } +} \ No newline at end of file diff --git a/connector/rest/pom.xml b/connector/rest/pom.xml index 10b0b17df..10a358b9f 100644 --- a/connector/rest/pom.xml +++ b/connector/rest/pom.xml @@ -112,6 +112,44 @@ + + org.openapitools + openapi-generator-maven-plugin + 6.3.0 + + + user-ms + + generate + + process-resources + + ${project.basedir}/docs/openapi/api-user-docs.json + spring + spring-cloud + + false + false + + true + ${project.groupId}.user.generated.openapi.v1 + ${project.groupId}.user.generated.openapi.v1.dto + ${project.groupId}.user.generated.openapi.v1.api + ${project.groupId}.user.generated.openapi.v1.config + @lombok.Builder; @lombok.NoArgsConstructor; @lombok.AllArgsConstructor + java8 + true + true + none + source + false + false + true + + + + + diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java new file mode 100644 index 000000000..ca2c05f5e --- /dev/null +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java @@ -0,0 +1,57 @@ +package it.pagopa.selfcare.dashboard.connector.rest; + +import it.pagopa.selfcare.dashboard.connector.api.UserApiConnector; +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; +import it.pagopa.selfcare.dashboard.connector.rest.client.UserApiRestClient; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.InstitutionV2Mapper; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.UserMapper; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Objects; + +import static it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState.*; + +@Slf4j +@Service +@ConditionalOnProperty(value = "dashboard.user.client.api-version", havingValue = "v2") +@RequiredArgsConstructor +public class UserConnectorImpl implements UserApiConnector { + + + private final UserApiRestClient userApiRestClient; + private final InstitutionV2Mapper institutionMapper; + private final UserMapper userMapper; + + + @Override + public void updateUser(String userId, String institutionId, MutableUserFieldsDto userDto) { + log.trace("updateUser start"); + log.debug("updateUser userId = {}, institutionId = {}", userId, institutionId); + userApiRestClient._usersIdUserRegistryPut(userId, institutionId, userMapper.toMutableUserFieldsDto(userDto)); + log.trace("updateUser end"); + } + + @Override + @ConditionalOnProperty(value = "dashboard.user.client.api-version", havingValue = "v2") + public List getUserProducts(String userId) { + log.trace("getUserProducts start"); + UserProductsResponse productsInfoUsingGET = userApiRestClient._usersUserIdProductsGet(userId, null, + List.of(ACTIVE.name(), PENDING.name(), TOBEVALIDATED.name())).getBody(); + + if(Objects.isNull(productsInfoUsingGET) || + Objects.isNull(productsInfoUsingGET.getBindings())) return List.of(); + + List result = productsInfoUsingGET.getBindings().stream() + .map(institutionMapper::toInstitutionInfo) + .toList(); + log.debug("getUserProducts result = {}", result); + log.trace("getUserProducts end"); + return result; + } +} diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java new file mode 100644 index 000000000..eeb4e8f63 --- /dev/null +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java @@ -0,0 +1,8 @@ +package it.pagopa.selfcare.dashboard.connector.rest.client; + +import it.pagopa.selfcare.user.generated.openapi.v1.api.UserControllerApi; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "${rest-client.user-api.serviceCode}", url = "${rest-client.user-api.base-url}") +public interface UserApiRestClient extends UserControllerApi { +} diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/config/UserApiRestClientConfig.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/config/UserApiRestClientConfig.java new file mode 100644 index 000000000..5c4a97e16 --- /dev/null +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/config/UserApiRestClientConfig.java @@ -0,0 +1,15 @@ +package it.pagopa.selfcare.dashboard.connector.rest.config; + +import it.pagopa.selfcare.commons.connector.rest.config.RestClientBaseConfig; +import it.pagopa.selfcare.dashboard.connector.rest.client.UserApiRestClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@Import(RestClientBaseConfig.class) +@EnableFeignClients(clients = UserApiRestClient.class) +@PropertySource("classpath:config/user-rest-client.properties") +public class UserApiRestClientConfig { +} diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java new file mode 100644 index 000000000..b4f2e49d9 --- /dev/null +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java @@ -0,0 +1,30 @@ +package it.pagopa.selfcare.dashboard.connector.rest.model.mapper; + +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.InstitutionProducts; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.OnboardedProductResponse; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +@Mapper(componentModel = "spring") +public interface InstitutionV2Mapper { + + @Mapping(target = "id", source = "institutionId") + @Mapping(target = "description", source = "institutionName") + @Mapping(target = "parentDescription", source = "institutionRootName") + @Mapping(target = "status", source = ".", qualifiedByName = "toStatus") + InstitutionInfo toInstitutionInfo(InstitutionProducts institutionProducts); + + @Named("toStatus") + default RelationshipState toStatus(InstitutionProducts institutionProducts) { + return institutionProducts.getProducts().stream() + .map(OnboardedProductResponse::getStatus) + .sorted() + .findFirst() + .map(statusEnum -> RelationshipState.valueOf(statusEnum.name())) + .orElse(null); + } +} diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/UserMapper.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/UserMapper.java new file mode 100644 index 000000000..1c7c7ecd0 --- /dev/null +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/UserMapper.java @@ -0,0 +1,46 @@ +package it.pagopa.selfcare.dashboard.connector.rest.model.mapper; + +import it.pagopa.selfcare.dashboard.connector.model.user.CertifiedField; +import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; +import it.pagopa.selfcare.dashboard.connector.model.user.WorkContact; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.CertifiableFieldResourceOfstring; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.CertificationEnum; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.UserRegistryFieldsDto; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.WorkContactResource; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +import java.util.HashMap; +import java.util.Map; + +@Mapper(componentModel = "spring") +public interface UserMapper { + + @Mapping(target = "email", expression = "java(toCertifiableFieldResourceOfString(userDto.getEmail()))") + @Mapping(target = "name", expression = "java(toCertifiableFieldResourceOfString(userDto.getName()))") + @Mapping(target = "familyName", expression = "java(toCertifiableFieldResourceOfString(userDto.getFamilyName()))") + @Mapping(target = "workContacts", expression = "java(toWorkContacts(userDto.getWorkContacts()))") + UserRegistryFieldsDto toMutableUserFieldsDto(MutableUserFieldsDto userDto); + + @Named("toCertifiableFieldResourceOfString") + default CertifiableFieldResourceOfstring toCertifiableFieldResourceOfString(CertifiedField field){ + if(field != null && field.getCertification() != null) { + return CertifiableFieldResourceOfstring.builder() + .certification(CertificationEnum.valueOf(field.getCertification().name())) + .value(field.getValue()) + .build(); + } + return null; + } + + @Named("toWorkContacts") + default Map toWorkContacts(Map workContactMap){ + Map resourceMap = new HashMap<>(); + if(workContactMap != null && !workContactMap.isEmpty()) { + workContactMap.forEach((s, workContact) -> resourceMap.put(s, WorkContactResource.builder().email(toCertifiableFieldResourceOfString(workContact.getEmail())).build())); + } + return resourceMap; + } + +} diff --git a/connector/rest/src/main/resources/config/user-rest-client.properties b/connector/rest/src/main/resources/config/user-rest-client.properties new file mode 100644 index 000000000..4e408d98c --- /dev/null +++ b/connector/rest/src/main/resources/config/user-rest-client.properties @@ -0,0 +1,2 @@ +rest-client.user-api.base-url=${SELFCARE_USER_URL:http://localhost:8080} +rest-client.user-api.serviceCode=user-domain \ No newline at end of file diff --git a/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java b/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java new file mode 100644 index 000000000..6736c64be --- /dev/null +++ b/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java @@ -0,0 +1,97 @@ +package it.pagopa.selfcare.dashboard.connector.rest; + +import it.pagopa.selfcare.dashboard.connector.exception.ResourceNotFoundException; +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; +import it.pagopa.selfcare.dashboard.connector.rest.client.UserApiRestClient; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.InstitutionV2MapperImpl; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.UserMapper; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.UserMapperImpl; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +import java.util.List; + +import static it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +@ContextConfiguration(classes = {UserConnectorImpl.class, InstitutionV2MapperImpl.class, UserMapper.class}) +class UserConnectorImplTest { + + @Mock + UserApiRestClient userApiRestClient; + + + UserConnectorImpl userConnector; + + @Test + void updateUserOK() { + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + when(userApiRestClient._usersIdUserRegistryPut(eq("userID"),eq("InstitutionId"), any(UserRegistryFieldsDto.class))) + .thenReturn(ResponseEntity.ok().build()); + Assertions.assertDoesNotThrow(() -> userConnector.updateUser("userID", "InstitutionId", new MutableUserFieldsDto())); + } + + @Test + void updateUserKO() { + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + when(userApiRestClient._usersIdUserRegistryPut(eq("userID"),eq("InstitutionId"), any(UserRegistryFieldsDto.class))) + .thenThrow(ResourceNotFoundException.class); + Assertions.assertThrows(ResourceNotFoundException.class, () -> userConnector.updateUser("userID", "InstitutionId", new MutableUserFieldsDto())); + } + + @Test + void getUserProductsNotFound() { + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + when(userApiRestClient._usersUserIdProductsGet("userID", null, + List.of(ACTIVE.name(), PENDING.name(), TOBEVALIDATED.name()))).thenThrow(ResourceNotFoundException.class); + Assertions.assertThrows(ResourceNotFoundException.class, () -> userConnector.getUserProducts("userID")); + } + + @Test + void getUserProductsFound() { + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + UserProductsResponse userProductsResponse = getUserProductsResponse(); + when(userApiRestClient._usersUserIdProductsGet("userID", null, + List.of(ACTIVE.name(), PENDING.name(), TOBEVALIDATED.name()))).thenReturn(ResponseEntity.ok(userProductsResponse)); + List result = userConnector.getUserProducts("userID"); + Assertions.assertEquals(1, result.size()); + Assertions.assertEquals(ACTIVE, result.get(0).getStatus()); + Assertions.assertEquals("institutionId", result.get(0).getId()); + Assertions.assertEquals("institutionName", result.get(0).getDescription()); + } + + private static UserProductsResponse getUserProductsResponse() { + UserProductsResponse userProductsResponse = new UserProductsResponse(); + userProductsResponse.setId("userID"); + InstitutionProducts institutionProducts = new InstitutionProducts(); + institutionProducts.setInstitutionId("institutionId"); + institutionProducts.setInstitutionName("institutionName"); + institutionProducts.setProducts(getOnboardedProduct()); + userProductsResponse.setBindings(List.of(institutionProducts)); + return userProductsResponse; + } + + private static List getOnboardedProduct() { + OnboardedProductResponse onboardedProductResponse = new OnboardedProductResponse(); + onboardedProductResponse.setProductId("prod-pagopa"); + onboardedProductResponse.setRole(PartyRole.MANAGER); + onboardedProductResponse.setStatus(OnboardedProductState.ACTIVE); + OnboardedProductResponse onboardedProductResponse2 = new OnboardedProductResponse(); + onboardedProductResponse2.setProductId("prod-pagopa"); + onboardedProductResponse2.setRole(PartyRole.MANAGER); + onboardedProductResponse2.setStatus(OnboardedProductState.PENDING); + return List.of(onboardedProductResponse, onboardedProductResponse2); + } +} From 9489312a0b3ad6f36f58017f9321f6c033631042 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Tue, 6 Feb 2024 09:27:04 +0100 Subject: [PATCH 2/5] change requests and remove unused properties for Api version --- app/src/main/resources/config/application.yml | 7 +---- .../connector/rest/UserConnectorImpl.java | 4 +-- .../rest/model/mapper/InstitutionMapper.java | 18 ++++++++++- .../model/mapper/InstitutionV2Mapper.java | 30 ------------------- .../config/user-rest-client.properties | 7 +++-- .../connector/rest/UserConnectorImplTest.java | 14 ++++----- 6 files changed, 31 insertions(+), 49 deletions(-) delete mode 100644 connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index 123975bb9..9eb31384c 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -29,9 +29,4 @@ logging: level: it.pagopa.selfcare: ${B4F_DASHBOARD_LOG_LEVEL:DEBUG} pattern: - additional-info: ",%X{X-Client-Ip:-}]" - -dashboard: - user: - client: - api-version: ${B4F_DASHBOARD_USER_CLIENT_API_VERSION:v1} \ No newline at end of file + additional-info: ",%X{X-Client-Ip:-}]" \ No newline at end of file diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java index ca2c05f5e..a2645959f 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java @@ -4,7 +4,7 @@ import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; import it.pagopa.selfcare.dashboard.connector.rest.client.UserApiRestClient; -import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.InstitutionV2Mapper; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.InstitutionMapper; import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.UserMapper; import it.pagopa.selfcare.user.generated.openapi.v1.dto.*; import lombok.RequiredArgsConstructor; @@ -25,7 +25,7 @@ public class UserConnectorImpl implements UserApiConnector { private final UserApiRestClient userApiRestClient; - private final InstitutionV2Mapper institutionMapper; + private final InstitutionMapper institutionMapper; private final UserMapper userMapper; diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionMapper.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionMapper.java index 2479cefe0..02d5d0021 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionMapper.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionMapper.java @@ -2,9 +2,9 @@ import it.pagopa.selfcare.core.generated.openapi.v1.dto.InstitutionProducts; import it.pagopa.selfcare.core.generated.openapi.v1.dto.Product; -import it.pagopa.selfcare.core.generated.openapi.v1.dto.UserProductsResponse; import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; import it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState; +import it.pagopa.selfcare.user.generated.openapi.v1.dto.OnboardedProductResponse; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; @@ -27,4 +27,20 @@ default RelationshipState toStatus(InstitutionProducts institutionProducts) { .map(statusEnum -> RelationshipState.valueOf(statusEnum.name())) .orElse(null); } + + @Mapping(target = "id", source = "institutionId") + @Mapping(target = "description", source = "institutionName") + @Mapping(target = "parentDescription", source = "institutionRootName") + @Mapping(target = "status", source = ".", qualifiedByName = "toStatus") + InstitutionInfo toInstitutionInfo(it.pagopa.selfcare.user.generated.openapi.v1.dto.InstitutionProducts institutionProducts); + + @Named("toStatus") + default RelationshipState toStatus(it.pagopa.selfcare.user.generated.openapi.v1.dto.InstitutionProducts institutionProducts) { + return institutionProducts.getProducts().stream() + .map(OnboardedProductResponse::getStatus) + .sorted() + .findFirst() + .map(statusEnum -> RelationshipState.valueOf(statusEnum.name())) + .orElse(null); + } } diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java deleted file mode 100644 index b4f2e49d9..000000000 --- a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/model/mapper/InstitutionV2Mapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package it.pagopa.selfcare.dashboard.connector.rest.model.mapper; - -import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; -import it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState; -import it.pagopa.selfcare.user.generated.openapi.v1.dto.InstitutionProducts; -import it.pagopa.selfcare.user.generated.openapi.v1.dto.OnboardedProductResponse; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Named; - -@Mapper(componentModel = "spring") -public interface InstitutionV2Mapper { - - @Mapping(target = "id", source = "institutionId") - @Mapping(target = "description", source = "institutionName") - @Mapping(target = "parentDescription", source = "institutionRootName") - @Mapping(target = "status", source = ".", qualifiedByName = "toStatus") - InstitutionInfo toInstitutionInfo(InstitutionProducts institutionProducts); - - @Named("toStatus") - default RelationshipState toStatus(InstitutionProducts institutionProducts) { - return institutionProducts.getProducts().stream() - .map(OnboardedProductResponse::getStatus) - .sorted() - .findFirst() - .map(statusEnum -> RelationshipState.valueOf(statusEnum.name())) - .orElse(null); - } -} diff --git a/connector/rest/src/main/resources/config/user-rest-client.properties b/connector/rest/src/main/resources/config/user-rest-client.properties index 4e408d98c..6b55d7af4 100644 --- a/connector/rest/src/main/resources/config/user-rest-client.properties +++ b/connector/rest/src/main/resources/config/user-rest-client.properties @@ -1,2 +1,5 @@ -rest-client.user-api.base-url=${SELFCARE_USER_URL:http://localhost:8080} -rest-client.user-api.serviceCode=user-domain \ No newline at end of file +rest-client.user-ms.base-url=${SELFCARE_USER_URL:http://localhost:8080} +rest-client.user-ms.serviceCode=user-ms +feign.client.config.user-ms.connectTimeout=${SELFCARE_USER_REST_CLIENT_CONNECT_TIMEOUT:${REST_CLIENT_CONNECT_TIMEOUT:5000}} +feign.client.config.user-ms.readTimeout=${SELFCARE_USER_REST_CLIENT_READ_TIMEOUT:${REST_CLIENT_READ_TIMEOUT:5000}} +feign.client.config.user-ms.loggerLevel=${SELFCARE_USER_REST_CLIENT_LOGGER_LEVEL:${REST_CLIENT_LOGGER_LEVEL:FULL}} \ No newline at end of file diff --git a/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java b/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java index 6736c64be..5e574bf8d 100644 --- a/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java +++ b/connector/rest/src/test/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImplTest.java @@ -4,7 +4,7 @@ import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; import it.pagopa.selfcare.dashboard.connector.rest.client.UserApiRestClient; -import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.InstitutionV2MapperImpl; +import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.InstitutionMapperImpl; import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.UserMapper; import it.pagopa.selfcare.dashboard.connector.rest.model.mapper.UserMapperImpl; import it.pagopa.selfcare.user.generated.openapi.v1.dto.*; @@ -13,7 +13,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; @@ -22,11 +21,10 @@ import static it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) -@ContextConfiguration(classes = {UserConnectorImpl.class, InstitutionV2MapperImpl.class, UserMapper.class}) +@ContextConfiguration(classes = {UserConnectorImpl.class, InstitutionMapperImpl.class, UserMapper.class}) class UserConnectorImplTest { @Mock @@ -37,7 +35,7 @@ class UserConnectorImplTest { @Test void updateUserOK() { - userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionMapperImpl(), new UserMapperImpl()); when(userApiRestClient._usersIdUserRegistryPut(eq("userID"),eq("InstitutionId"), any(UserRegistryFieldsDto.class))) .thenReturn(ResponseEntity.ok().build()); Assertions.assertDoesNotThrow(() -> userConnector.updateUser("userID", "InstitutionId", new MutableUserFieldsDto())); @@ -45,7 +43,7 @@ void updateUserOK() { @Test void updateUserKO() { - userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionMapperImpl(), new UserMapperImpl()); when(userApiRestClient._usersIdUserRegistryPut(eq("userID"),eq("InstitutionId"), any(UserRegistryFieldsDto.class))) .thenThrow(ResourceNotFoundException.class); Assertions.assertThrows(ResourceNotFoundException.class, () -> userConnector.updateUser("userID", "InstitutionId", new MutableUserFieldsDto())); @@ -53,7 +51,7 @@ void updateUserKO() { @Test void getUserProductsNotFound() { - userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionMapperImpl(), new UserMapperImpl()); when(userApiRestClient._usersUserIdProductsGet("userID", null, List.of(ACTIVE.name(), PENDING.name(), TOBEVALIDATED.name()))).thenThrow(ResourceNotFoundException.class); Assertions.assertThrows(ResourceNotFoundException.class, () -> userConnector.getUserProducts("userID")); @@ -61,7 +59,7 @@ void getUserProductsNotFound() { @Test void getUserProductsFound() { - userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionV2MapperImpl(), new UserMapperImpl()); + userConnector = new UserConnectorImpl(userApiRestClient, new InstitutionMapperImpl(), new UserMapperImpl()); UserProductsResponse userProductsResponse = getUserProductsResponse(); when(userApiRestClient._usersUserIdProductsGet("userID", null, List.of(ACTIVE.name(), PENDING.name(), TOBEVALIDATED.name()))).thenReturn(ResponseEntity.ok(userProductsResponse)); From 894a3efbae7ff43e7d97621c26631286c3af89a6 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Tue, 6 Feb 2024 10:59:55 +0100 Subject: [PATCH 3/5] Add UserV2Controller and Service for new API of BE-User --- .../connector/rest/UserConnectorImpl.java | 1 - .../dashboard/core/UserV2Service.java | 16 ++ .../dashboard/core/UserV2ServiceImpl.java | 56 +++++++ .../dashboard/core/UserV2ServiceImplTest.java | 138 ++++++++++++++++++ .../web/controller/UserV2Controller.java | 71 +++++++++ .../web/controller/UserV2ControllerTest.java | 133 +++++++++++++++++ 6 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2Service.java create mode 100644 core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImpl.java create mode 100644 core/src/test/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImplTest.java create mode 100644 web/src/main/java/it/pagopa/selfcare/dashboard/web/controller/UserV2Controller.java create mode 100644 web/src/test/java/it/pagopa/selfcare/dashboard/web/controller/UserV2ControllerTest.java diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java index a2645959f..9120d1c7d 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/UserConnectorImpl.java @@ -19,7 +19,6 @@ @Slf4j @Service -@ConditionalOnProperty(value = "dashboard.user.client.api-version", havingValue = "v2") @RequiredArgsConstructor public class UserConnectorImpl implements UserApiConnector { diff --git a/core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2Service.java b/core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2Service.java new file mode 100644 index 000000000..27d1ac880 --- /dev/null +++ b/core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2Service.java @@ -0,0 +1,16 @@ +package it.pagopa.selfcare.dashboard.core; + +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.*; + +import java.util.Collection; +import java.util.UUID; + +public interface UserV2Service { + + void updateUser(UUID id, String institutionId, MutableUserFieldsDto userDto); + + Collection getInstitutions(String userId); + + +} diff --git a/core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImpl.java b/core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImpl.java new file mode 100644 index 000000000..4519a83de --- /dev/null +++ b/core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImpl.java @@ -0,0 +1,56 @@ +package it.pagopa.selfcare.dashboard.core; + +import it.pagopa.selfcare.commons.base.logging.LogUtils; +import it.pagopa.selfcare.dashboard.connector.api.MsCoreConnector; +import it.pagopa.selfcare.dashboard.connector.api.UserApiConnector; +import it.pagopa.selfcare.dashboard.connector.api.UserRegistryConnector; +import it.pagopa.selfcare.dashboard.connector.exception.ResourceNotFoundException; +import it.pagopa.selfcare.dashboard.connector.model.institution.Institution; +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +import java.util.Collection; +import java.util.EnumSet; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +import static it.pagopa.selfcare.dashboard.connector.model.user.User.Fields.*; + +@Slf4j +@Service +@RequiredArgsConstructor +public class UserV2ServiceImpl implements UserV2Service { + + private final MsCoreConnector msCoreConnector; + private final UserApiConnector userApiConnector; + + @Override + public void updateUser(UUID id, String institutionId, MutableUserFieldsDto userDto) { + log.trace("updateUser start"); + log.debug(LogUtils.CONFIDENTIAL_MARKER, "updateUser id = {}, institutionId = {}, userDto = {}", id, institutionId, userDto); + Assert.notNull(id, "UUID is required"); + Assert.hasText(institutionId, "An institutionId is required"); + Assert.notNull(userDto, "A userDto is required"); + Institution institution = msCoreConnector.getInstitution(institutionId); + if (institution == null) { + throw new ResourceNotFoundException("There are no institution for given institutionId"); + } + userApiConnector.updateUser(id.toString(), institutionId, userDto); + log.trace("updateUser end"); + } + + @Override + public Collection getInstitutions(String userId) { + log.trace("getInstitutions start"); + Collection result = userApiConnector.getUserProducts(userId); + log.debug(LogUtils.CONFIDENTIAL_MARKER, "getInstitutions result = {}", result); + log.trace("getInstitutions end"); + return result; + } + +} diff --git a/core/src/test/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImplTest.java b/core/src/test/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImplTest.java new file mode 100644 index 000000000..8e53a7735 --- /dev/null +++ b/core/src/test/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImplTest.java @@ -0,0 +1,138 @@ +package it.pagopa.selfcare.dashboard.core; + +import it.pagopa.selfcare.dashboard.connector.api.MsCoreConnector; +import it.pagopa.selfcare.dashboard.connector.api.UserApiConnector; +import it.pagopa.selfcare.dashboard.connector.api.UserRegistryConnector; +import it.pagopa.selfcare.dashboard.connector.exception.ResourceNotFoundException; +import it.pagopa.selfcare.dashboard.connector.model.institution.Institution; +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; +import it.pagopa.selfcare.dashboard.connector.model.user.WorkContact; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.function.Executable; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; +import static java.util.UUID.randomUUID; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.verifyNoInteractions; + +@ExtendWith({MockitoExtension.class}) +class UserV2ServiceImplTest { + + @Mock + private UserRegistryConnector userConnectorMock; + + @InjectMocks + private UserV2ServiceImpl userService; + + @Mock + private MsCoreConnector msCoreConnectorMock; + + @Mock + private UserApiConnector userApiConnector; + + + @Test + void updateUser() { + //given + String institutionId = "institutionId"; + UUID id = randomUUID(); + MutableUserFieldsDto user = mockInstance(new MutableUserFieldsDto(), "setWorkContacts"); + WorkContact workContact = mockInstance(new WorkContact()); + user.setWorkContacts(Map.of(institutionId, workContact)); + Institution institutionMock = mockInstance(new Institution()); + when(msCoreConnectorMock.getInstitution(Mockito.anyString())) + .thenReturn(institutionMock); + doNothing().when(userApiConnector).updateUser(id.toString(), institutionId, user); + //when + Executable executable = () -> userService.updateUser(id, institutionId, user); + //then + assertDoesNotThrow(executable); + verify(msCoreConnectorMock, times(1)) + .getInstitution(institutionId); + verifyNoMoreInteractions(userConnectorMock, msCoreConnectorMock); + } + + @Test + void updateUser_nullInstitution() { + //given + String institutionId = "institutionId"; + UUID id = randomUUID(); + MutableUserFieldsDto user = mockInstance(new MutableUserFieldsDto(), "setWorkContacts"); + //when + Executable executable = () -> userService.updateUser(id, institutionId, user); + //then + ResourceNotFoundException e = assertThrows(ResourceNotFoundException.class, executable); + assertEquals("There are no institution for given institutionId", e.getMessage()); + verifyNoInteractions(userConnectorMock); + } + + @Test + void updateUser_nullInstitutionId() { + //given + String institutionId = null; + UUID id = randomUUID(); + MutableUserFieldsDto user = mockInstance(new MutableUserFieldsDto(), "setWorkContacts"); + //when + Executable executable = () -> userService.updateUser(id, institutionId, user); + //then + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable); + assertEquals("An institutionId is required", e.getMessage()); + verifyNoInteractions(userConnectorMock, msCoreConnectorMock); + } + + @Test + void updateUser_nullUUID() { + //given + String institutionId = "institutionId"; + UUID id = null; + MutableUserFieldsDto user = mockInstance(new MutableUserFieldsDto(), "setWorkContacts"); + //when + Executable executable = () -> userService.updateUser(id, institutionId, user); + //then + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable); + assertEquals("UUID is required", e.getMessage()); + verifyNoInteractions(userConnectorMock, msCoreConnectorMock); + } + + @Test + void updateUser_nullDto() { + //given + String institutionId = "institutionId"; + UUID id = randomUUID(); + //when + Executable executable = () -> userService.updateUser(id, institutionId, null); + //then + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable); + assertEquals("A userDto is required", e.getMessage()); + verifyNoInteractions(userConnectorMock, msCoreConnectorMock); + } + + @Test + void getInstitutions() { + // given + String userId = "userId"; + InstitutionInfo expectedInstitutionInfo = new InstitutionInfo(); + + when(userApiConnector.getUserProducts(userId)).thenReturn(List.of(expectedInstitutionInfo)); + // when + Collection institutions = userService.getInstitutions(userId); + + assertNotNull(institutions); + assertEquals(1, institutions.size()); + assertSame(expectedInstitutionInfo, institutions.iterator().next()); + verifyNoMoreInteractions(msCoreConnectorMock); + } + +} diff --git a/web/src/main/java/it/pagopa/selfcare/dashboard/web/controller/UserV2Controller.java b/web/src/main/java/it/pagopa/selfcare/dashboard/web/controller/UserV2Controller.java new file mode 100644 index 000000000..72a51856d --- /dev/null +++ b/web/src/main/java/it/pagopa/selfcare/dashboard/web/controller/UserV2Controller.java @@ -0,0 +1,71 @@ +package it.pagopa.selfcare.dashboard.web.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import it.pagopa.selfcare.commons.base.logging.LogUtils; +import it.pagopa.selfcare.commons.base.security.SelfCareUser; +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.core.UserV2Service; +import it.pagopa.selfcare.dashboard.web.InstitutionBaseResource; +import it.pagopa.selfcare.dashboard.web.model.UpdateUserDto; +import it.pagopa.selfcare.dashboard.web.model.mapper.InstitutionResourceMapper; +import it.pagopa.selfcare.dashboard.web.model.mapper.UserMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +@Slf4j +@RestController +@Api(tags = "user") +@RequestMapping(value = "/v2", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class UserV2Controller { + + private final UserV2Service userService; + private final InstitutionResourceMapper institutionResourceMapper; + + @PutMapping(value = "/users/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.dashboard.user.api.updateUserById}") + public void updateUser(@ApiParam("${swagger.dashboard.user.model.id}") + @PathVariable("id") + UUID id, + @ApiParam("${swagger.dashboard.institutions.model.id}") + @RequestParam(value = "institutionId") + String institutionId, + @RequestBody + @Valid + UpdateUserDto updateUserDto) { + log.trace("updateUser start"); + log.debug(LogUtils.CONFIDENTIAL_MARKER, "id = {}, institutionId = {}, userDto = {}", id, institutionId, updateUserDto); + userService.updateUser(id, institutionId, UserMapper.fromUpdateUser(updateUserDto, institutionId)); + log.trace("updateUser end"); + } + + @GetMapping("/institutions") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(value = "", notes = "${swagger.dashboard.institutions.api.getInstitutions}") + public List getInstitutions(Authentication authentication) { + + log.trace("getInstitutions start"); + String userId = ((SelfCareUser) authentication.getPrincipal()).getId(); + Collection institutions = userService.getInstitutions(userId); + + List result = institutions.stream() + .map(institutionResourceMapper::toResource) + .toList(); + log.debug(LogUtils.CONFIDENTIAL_MARKER, "getInstitutions result = {}", result); + log.trace("getInstitutions end"); + + return result; + } +} diff --git a/web/src/test/java/it/pagopa/selfcare/dashboard/web/controller/UserV2ControllerTest.java b/web/src/test/java/it/pagopa/selfcare/dashboard/web/controller/UserV2ControllerTest.java new file mode 100644 index 000000000..886eec1f5 --- /dev/null +++ b/web/src/test/java/it/pagopa/selfcare/dashboard/web/controller/UserV2ControllerTest.java @@ -0,0 +1,133 @@ +package it.pagopa.selfcare.dashboard.web.controller; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import it.pagopa.selfcare.commons.base.security.SelfCareUser; +import it.pagopa.selfcare.commons.utils.TestUtils; +import it.pagopa.selfcare.dashboard.connector.model.institution.GeographicTaxonomy; +import it.pagopa.selfcare.dashboard.connector.model.institution.InstitutionInfo; +import it.pagopa.selfcare.dashboard.connector.model.user.Certification; +import it.pagopa.selfcare.dashboard.connector.model.user.MutableUserFieldsDto; +import it.pagopa.selfcare.dashboard.connector.model.user.User; +import it.pagopa.selfcare.dashboard.connector.model.user.WorkContact; +import it.pagopa.selfcare.dashboard.core.UserService; +import it.pagopa.selfcare.dashboard.core.UserV2Service; +import it.pagopa.selfcare.dashboard.web.InstitutionBaseResource; +import it.pagopa.selfcare.dashboard.web.config.WebTestConfig; +import it.pagopa.selfcare.dashboard.web.model.GET_INSTITUTION_MODE; +import it.pagopa.selfcare.dashboard.web.model.InstitutionResource; +import it.pagopa.selfcare.dashboard.web.model.mapper.InstitutionResourceMapper; +import it.pagopa.selfcare.dashboard.web.model.mapper.InstitutionResourceMapperImpl; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.core.io.Resource; +import org.springframework.http.MediaType; +import org.springframework.security.core.Authentication; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.util.*; + +import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; +import static org.hamcrest.Matchers.emptyString; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(value = {UserV2Controller.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class) +@ContextConfiguration(classes = {UserV2Controller.class, InstitutionResourceMapperImpl.class, WebTestConfig.class}) +class UserV2ControllerTest { + + @Autowired + protected MockMvc mvc; + + @MockBean + private UserV2Service userServiceMock; + + + @Autowired + protected ObjectMapper objectMapper; + + private static final String BASE_URL = "/v2"; + + private static final User USER_RESOURCE; + + static { + USER_RESOURCE = TestUtils.mockInstance(new User()); + USER_RESOURCE.setId(UUID.randomUUID().toString()); + Map workContacts = new HashMap<>(); + WorkContact workContact = TestUtils.mockInstance(new WorkContact()); + workContact.getEmail().setCertification(Certification.SPID); + workContacts.put("institutionId", workContact); + USER_RESOURCE.setWorkContacts(workContacts); + } + + + @Test + void updateUser(@Value("classpath:stubs/updateUserDto.json") Resource updateUserDto) throws Exception { + //given + UUID id = UUID.randomUUID(); + String institutionId = "institutionId"; + //when + mvc.perform(MockMvcRequestBuilders + .put(BASE_URL + "/users/{id}", id) + .queryParam("institutionId", institutionId) + .content(updateUserDto.getInputStream().readAllBytes()) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isNoContent()) + .andExpect(content().string(emptyString())); + //then + verify(userServiceMock, times(1)) + .updateUser(eq(id), eq(institutionId), any(MutableUserFieldsDto.class)); + Mockito.verifyNoMoreInteractions(userServiceMock); + } + + @Test + void getInstitutions_institutionInfoNotNull() throws Exception { + // given + String userId = "userId"; + Authentication authentication = mock(Authentication.class); + when(authentication.getPrincipal()).thenReturn(SelfCareUser.builder(userId).build()); + + InstitutionInfo expectedInstitution = mockInstance(new InstitutionInfo()); + expectedInstitution.setGeographicTaxonomies(List.of(mockInstance(new GeographicTaxonomy()))); + List expectedInstitutionInfos = new ArrayList<>(); + expectedInstitutionInfos.add(expectedInstitution); + when(userServiceMock.getInstitutions(userId)).thenReturn(expectedInstitutionInfos); + // when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .get(BASE_URL + "/institutions") + .principal(authentication) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().is2xxSuccessful()) + .andReturn(); + // then + List resources = objectMapper.readValue(result.getResponse().getContentAsString(), + new TypeReference<>() { + }); + + assertNotNull(resources); + assertFalse(resources.isEmpty()); + assertEquals(resources.get(0).getStatus(), expectedInstitution.getStatus().name()); + assertNotNull(resources.get(0).getUserRole()); + verify(userServiceMock, times(1)) + .getInstitutions(userId); + verifyNoMoreInteractions(userServiceMock); + } + + +} From b67a5ab86201c583aa09f72178499ae05d29d8be Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Tue, 6 Feb 2024 12:45:25 +0100 Subject: [PATCH 4/5] fix swagger config test --- app/src/main/resources/swagger/api-docs.json | 182 ++++++++++++++++++ .../web/config/SwaggerConfigTest.java | 3 + 2 files changed, 185 insertions(+) diff --git a/app/src/main/resources/swagger/api-docs.json b/app/src/main/resources/swagger/api-docs.json index 06698a474..76bca98cc 100644 --- a/app/src/main/resources/swagger/api-docs.json +++ b/app/src/main/resources/swagger/api-docs.json @@ -3323,6 +3323,188 @@ "bearerAuth" : [ "global" ] } ] } + }, + "/v2/institutions" : { + "get" : { + "tags" : [ "user" ], + "summary" : "getInstitutions", + "description" : "Service to get all the institutions related to logged user", + "operationId" : "getInstitutionsUsingGET_1", + "parameters" : [ { + "name" : "authenticated", + "in" : "query", + "required" : false, + "style" : "form", + "schema" : { + "type" : "boolean" + } + }, { + "name" : "authorities[0].authority", + "in" : "query", + "required" : false, + "style" : "form", + "schema" : { + "type" : "string" + } + }, { + "name" : "credentials", + "in" : "query", + "required" : false, + "style" : "form", + "schema" : { + "type" : "object" + } + }, { + "name" : "details", + "in" : "query", + "required" : false, + "style" : "form", + "schema" : { + "type" : "object" + } + }, { + "name" : "principal", + "in" : "query", + "required" : false, + "style" : "form", + "schema" : { + "type" : "object" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/InstitutionBaseResource" + } + } + } + } + }, + "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" ] + } ] + } + }, + "/v2/users/{id}" : { + "put" : { + "tags" : [ "user" ], + "summary" : "updateUser", + "description" : "Update previously added user", + "operationId" : "updateUserUsingPUT_1", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "User's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string", + "format" : "uuid" + } + }, { + "name" : "institutionId", + "in" : "query", + "description" : "Institution's unique internal identifier", + "required" : true, + "style" : "form", + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UpdateUserDto" + } + } + } + }, + "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" ] + } ] + } } }, "components" : { diff --git a/app/src/test/java/it/pagopa/selfcare/dashboard/web/config/SwaggerConfigTest.java b/app/src/test/java/it/pagopa/selfcare/dashboard/web/config/SwaggerConfigTest.java index a067ecac9..c086979d5 100644 --- a/app/src/test/java/it/pagopa/selfcare/dashboard/web/config/SwaggerConfigTest.java +++ b/app/src/test/java/it/pagopa/selfcare/dashboard/web/config/SwaggerConfigTest.java @@ -60,6 +60,9 @@ class SwaggerConfigTest { @MockBean private UserService userServiceMock; + @MockBean + private UserV2Service userV2ServiceMock; + @MockBean private BrokerService brokerService; From 1aeca63ce104cc3748efacde2ccda651456abb07 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Wed, 7 Feb 2024 13:15:31 +0100 Subject: [PATCH 5/5] fix properties in feign client --- .../dashboard/connector/rest/client/UserApiRestClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java index eeb4e8f63..b4a2c078d 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/dashboard/connector/rest/client/UserApiRestClient.java @@ -3,6 +3,6 @@ import it.pagopa.selfcare.user.generated.openapi.v1.api.UserControllerApi; import org.springframework.cloud.openfeign.FeignClient; -@FeignClient(name = "${rest-client.user-api.serviceCode}", url = "${rest-client.user-api.base-url}") +@FeignClient(name = "${rest-client.user-ms.serviceCode}", url = "${rest-client.user-ms.base-url}") public interface UserApiRestClient extends UserControllerApi { }