From b56201c1112f1c7ef5df1aa7e3d71726226103fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Cal=C3=B2?= Date: Wed, 4 Dec 2024 17:20:32 +0100 Subject: [PATCH 1/7] feat: P4ADEV-1428 logging traceId (#9) --- build.gradle.kts | 2 ++ gradle.lockfile | 15 +++++++++++++++ src/main/resources/logback-spring.xml | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5560314..f799688 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,6 +37,7 @@ val nimbusJoseJwtVersion = "9.47" val jjwtVersion = "0.12.6" val wiremockVersion = "3.9.2" val wiremockSpringBootVersion = "2.1.3" +val micrometerVersion = "1.4.0" dependencies { implementation("org.springframework.boot:spring-boot-starter") @@ -47,6 +48,7 @@ dependencies { implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") implementation("org.openapitools:jackson-databind-nullable:$openApiToolsVersion") implementation("com.google.code.findbugs:jsr305:$findbugsVersion") + implementation("io.micrometer:micrometer-tracing-bridge-otel:$micrometerVersion") compileOnly("org.projectlombok:lombok") annotationProcessor("org.projectlombok:lombok") diff --git a/gradle.lockfile b/gradle.lockfile index 8088d6b..9c7b60d 100644 --- a/gradle.lockfile +++ b/gradle.lockfile @@ -1,6 +1,7 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +aopalliance:aopalliance:1.0=compileClasspath ch.qos.logback:logback-classic:1.5.11=compileClasspath ch.qos.logback:logback-core:1.5.11=compileClasspath com.auth0:java-jwt:4.4.0=compileClasspath @@ -16,10 +17,24 @@ com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath com.google.code.findbugs:jsr305:3.0.2=compileClasspath com.nimbusds:nimbus-jose-jwt:9.47=compileClasspath io.jsonwebtoken:jjwt-api:0.12.6=compileClasspath +io.micrometer:context-propagation:1.1.2=compileClasspath io.micrometer:micrometer-commons:1.13.6=compileClasspath io.micrometer:micrometer-core:1.13.6=compileClasspath io.micrometer:micrometer-jakarta9:1.13.6=compileClasspath io.micrometer:micrometer-observation:1.13.6=compileClasspath +io.micrometer:micrometer-tracing-bridge-otel:1.4.0=compileClasspath +io.micrometer:micrometer-tracing:1.3.5=compileClasspath +io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator:2.9.0-alpha=compileClasspath +io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:2.9.0=compileClasspath +io.opentelemetry.semconv:opentelemetry-semconv:1.25.0-alpha=compileClasspath +io.opentelemetry:opentelemetry-api:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-context:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-extension-trace-propagators:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-sdk-common:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-sdk-logs:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-sdk-metrics:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-sdk-trace:1.37.0=compileClasspath +io.opentelemetry:opentelemetry-sdk:1.37.0=compileClasspath io.swagger.core.v3:swagger-annotations-jakarta:2.2.22=compileClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index c46c6d4..6b101ed 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -6,7 +6,7 @@ source="spring.application.name"/> + value="%d{yyyy-MM-dd HH:mm:ss.SSS} [${appName:-}] [%X{externalUserId:-}] [%X{traceId:-}] %-5level [%15.15t] [%-40.40logger{39}] - %msg%n"/> From 434c77d1bb86fe3f4d02f6dbb8173b175edc4fb7 Mon Sep 17 00:00:00 2001 From: RiccardoGiuliani <144138935+RiccardoGiuliani@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:26:50 +0100 Subject: [PATCH 2/7] feat: P4ADEV-1426 invoke service mock C030 (#10) --- build.gradle.kts | 50 ++- helm/values-dev.yaml | 2 + helm/values-prod.yaml | 2 + helm/values-uat.yaml | 2 + openapi/anprApiC003.openapi.yaml | 352 ++++++++++++++++++ openapi/anprApiC030.openapi.yaml | 322 ++++++++++++++++ openapi/p4pa-pdnd.openapi.yaml | 78 +++- .../c003/service}/AnprC003ServiceConfig.java | 2 +- .../pdnd/anpr/c030/client/AnprC030Client.java | 8 + .../anpr/c030/client/AnprC030ClientImpl.java | 45 +++ .../anpr/c030/service/AnprC030Service.java | 47 +++ .../c030/service}/AnprC030ServiceConfig.java | 2 +- .../pdnd/PdndServiceIntegratedConfig.java | 1 + src/main/resources/application.yml | 7 +- .../c030/client/AnprC030ClientImplTest.java | 74 ++++ .../c030/service/AnprC030ServiceTest.java | 52 +++ 16 files changed, 1020 insertions(+), 26 deletions(-) create mode 100644 openapi/anprApiC003.openapi.yaml create mode 100644 openapi/anprApiC030.openapi.yaml rename src/main/java/it/gov/pagopa/payhub/pdnd/{config/pdnd/anpr => anpr/c003/service}/AnprC003ServiceConfig.java (87%) create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030Client.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030Service.java rename src/main/java/it/gov/pagopa/payhub/pdnd/{config/pdnd/anpr => anpr/c030/service}/AnprC030ServiceConfig.java (87%) create mode 100644 src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java create mode 100644 src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java diff --git a/build.gradle.kts b/build.gradle.kts index f799688..475cce0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -50,15 +50,15 @@ dependencies { implementation("com.google.code.findbugs:jsr305:$findbugsVersion") implementation("io.micrometer:micrometer-tracing-bridge-otel:$micrometerVersion") - compileOnly("org.projectlombok:lombok") - annotationProcessor("org.projectlombok:lombok") - // validation token jwt implementation("com.auth0:java-jwt:$javaJwtVersion") implementation("com.auth0:jwks-rsa:$jwksRsaVersion") implementation("com.nimbusds:nimbus-jose-jwt:$nimbusJoseJwtVersion") implementation("io.jsonwebtoken:jjwt-api:$jjwtVersion") + compileOnly("org.projectlombok:lombok") + annotationProcessor("org.projectlombok:lombok") + // Testing testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.security:spring-security-test") @@ -100,7 +100,7 @@ configurations { } tasks.compileJava { - dependsOn("openApiGeneratePayhub","openApiGeneratePdndClient") + dependsOn("openApiGeneratePayhub","openApiGeneratePdndClient","openApiGenerateAnprApiC030", "openApiGenerateAnprApiC003") } configure { @@ -156,4 +156,46 @@ tasks.register("ope "generateSupportingFiles" to "true" )) library.set("resttemplate") +} + +tasks.register("openApiGenerateAnprApiC030") { + group = "openapi" + description = "description" + + generatorName.set("spring") + inputSpec.set("$rootDir/openapi/anprApiC030.openapi.yaml") + outputDir.set("$projectDir/build/generated") + apiPackage.set("it.gov.pagopa.payhub.anpr.C030.controller.generated") + modelPackage.set("it.gov.pagopa.payhub.anpr.C030.model.generated") + configOptions.set(mapOf( + "dateLibrary" to "java8", + "requestMappingMode" to "api_interface", + "useSpringBoot3" to "true", + "interfaceOnly" to "true", + "useTags" to "true", + "generateConstructorWithAllArgs" to "false", + "generatedConstructorWithRequiredArgs" to "false", + "additionalModelTypeAnnotations" to "@lombok.Data;@lombok.Builder;@lombok.NoArgsConstructor;@lombok.AllArgsConstructor" + )) +} + +tasks.register("openApiGenerateAnprApiC003") { + group = "openapi" + description = "description" + + generatorName.set("spring") + inputSpec.set("$rootDir/openapi/anprApiC003.openapi.yaml") + outputDir.set("$projectDir/build/generated") + apiPackage.set("it.gov.pagopa.payhub.anpr.C003.controller.generated") + modelPackage.set("it.gov.pagopa.payhub.anpr.C003.model.generated") + configOptions.set(mapOf( + "dateLibrary" to "java8", + "requestMappingMode" to "api_interface", + "useSpringBoot3" to "true", + "interfaceOnly" to "true", + "useTags" to "true", + "generateConstructorWithAllArgs" to "false", + "generatedConstructorWithRequiredArgs" to "false", + "additionalModelTypeAnnotations" to "@lombok.Data;@lombok.Builder;@lombok.NoArgsConstructor;@lombok.AllArgsConstructor" + )) } \ No newline at end of file diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 30de24f..16afb34 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -38,6 +38,8 @@ microservice-chart: PDND_SERVICE_ANPR_C003_PURPOSE_ID: 5ba1f38f-6a91-4da4-8a42-4da1aa55bfee PDND_SERVICE_ANPR_C030_PURPOSE_ID: 87520bd5-207a-4616-85d9-10d7bb3e88b8 + ANPR_BASE_URL: http://p4pa-mocks-microservice-chart:8080 + keyvault: name: "p4pa-d-payhub-kv" tenantId: "7788edaf-0346-4068-9d79-c868aed15b3d" \ No newline at end of file diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 957a939..69a4c06 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -39,6 +39,8 @@ microservice-chart: PDND_SERVICE_ANPR_C003_PURPOSE_ID: 5ba1f38f-6a91-4da4-8a42-4da1aa55bfee PDND_SERVICE_ANPR_C030_PURPOSE_ID: 87520bd5-207a-4616-85d9-10d7bb3e88b8 + ANPR_BASE_URL: https://p4pa-mocks-microservice-chart:8080 + keyvault: name: "p4pa-p-payhub-kv" tenantId: "7788edaf-0346-4068-9d79-c868aed15b3d" diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index a111d12..4adce36 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -38,6 +38,8 @@ microservice-chart: PDND_SERVICE_ANPR_C003_PURPOSE_ID: 5ba1f38f-6a91-4da4-8a42-4da1aa55bfee PDND_SERVICE_ANPR_C030_PURPOSE_ID: 87520bd5-207a-4616-85d9-10d7bb3e88b8 + ANPR_BASE_URL: http://p4pa-mocks-microservice-chart:8080 + keyvault: name: "p4pa-u-payhub-kv" tenantId: "7788edaf-0346-4068-9d79-c868aed15b3d" diff --git a/openapi/anprApiC003.openapi.yaml b/openapi/anprApiC003.openapi.yaml new file mode 100644 index 0000000..2335479 --- /dev/null +++ b/openapi/anprApiC003.openapi.yaml @@ -0,0 +1,352 @@ +openapi: 3.0.3 +info: + title: Consultazione ANPR API C003 + description: |- + Servizio di verifica dei dati di una dichiarazione di generalità di un cittadino + Pattern Model applicati: + - [AUDIT_REST_02 ] Inoltro dati tracciati nel dominio del Fruitore REST con correlazione + - [BLOCK_REST] Blocking REST + - [INTEGRITY_REST_02] Integrità del payload messaggio REST in PDND + version: '1.0.0' + contact: + name: API Support + email: Assistenza.anpr@pec.sogei.it + termsOfService: 'http://swagger.io/terms/' + x-api-id: C003 + x-summary: Servizio di verifica dichiarazione generalità +servers: + - url: 'https://modipa-val.anpr.interno.it/govway/rest/in/MinInternoPortaANPR-PDND/C003-servizioVerificaDichGeneralita/v1' + description: Url di test per Consultazione Enti C003 + - url: 'https://modipa.anpr.interno.it/govway/rest/in/MinInternoPortaANPR-PDND/C003-servizioVerificaDichGeneralita/v1' + description: Url di esercizio per Consultazione Enti C003 +tags: +- name: E002 service + description: Manage consultazione enti +security: + - bearerAuth: [] + Agid-JWT-Signature: [] +paths: + /status: + get: + summary: Returns the application status + description: | + Returns the application status. For testing purposes, it might randomly reply with an error. + operationId: get_status + tags: + - health + responses: + '200': + description: | + This is the valid status from the server. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' + /anpr-service-e002: + post: + tags: + - E002 service + summary: Trova caso d'uso + description: Consultazione di un caso d'uso + operationId: e002 + security: + - bearerAuth: [] + requestBody: + required: true + description: Richiesta da consultare + content: + application/json: + schema: + $ref: '#/components/schemas/RichiestaE002' + responses: + "200": + description: Caso d'uso trovato + content: + application/json: + schema: + $ref: '#/components/schemas/RispostaE002OK' + "400": + description: Caso d'uso invalido + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' + "404": + description: Caso d'uso non trovato + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' + "500": + description: Internal Server Error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' +components: + schemas: + RichiestaE002: + type: object + required: + - idOperazioneClient + - criteriRicerca + - datiRichiesta + properties: + idOperazioneClient: + type: string + description: Identificativo univoco attribuito all'operazione dall'ente. Deve essere un alfanumerico. Si consiglia di usare il timestamp o un identificativo della postazione piu' il timestamp + criteriRicerca: + $ref: '#/components/schemas/TipoCriteriRicercaE002' + verifica: + $ref: '#/components/schemas/TipoVerificaE002' + datiRichiesta: + $ref: '#/components/schemas/TipoDatiRichiestaE002' + RispostaE002OK: + type: object + properties: + idOperazioneANPR: + type: string + listaSoggetti: + $ref: '#/components/schemas/TipoListaSoggetti' + listaAnomalie: + type: array + items: + $ref: '#/components/schemas/TipoErroriAnomalia' + RispostaKO: + type: object + properties: + idOperazioneANPR: + type: string + listaErrori: + type: array + items: + $ref: '#/components/schemas/TipoErroriAnomalia' + TipoCriteriRicercaE002: + type: object + properties: + codiceFiscale: + type: string + idANPR: + type: string + description: Identificativo Unico Nazionale + cognome: + type: string + senzaCognome: + type: string + nome: + type: string + senzaNome: + type: string + sesso: + type: string + datiNascita: + $ref: '#/components/schemas/TipoDatiNascitaE000' + TipoDatiRichiestaE002: + type: object + required: + - dataRiferimentoRichiesta + - casoUso + - motivoRichiesta + properties: + dataRiferimentoRichiesta: + type: string + description: Data cui deve essere riferita la versione della scheda anagrafica + format: YYYY-MM-DD + example: '2021-11-15' + motivoRichiesta: + type: string + description: campo per l’indicazione obbligatoria del numero di riferimento della pratica per quale è effettuata l’interrogazione (es. numero di protocollo, fascicolo, verbale, etc.) + casoUso: + type: string + description: caso d'uso (es. C001) + TipoErroriAnomalia: + type: object + properties: + codiceErroreAnomalia: + type: string + tipoErroreAnomalia: + type: string + testoErroreAnomalia: + type: string + oggettoErroreAnomalia: + type: string + campoErroreAnomalia: + type: string + valoreErroreAnomalia: + type: string + TipoDatiNascitaE000: + type: object + properties: + dataEvento: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + senzaGiorno: + type: string + senzaGiornoMese: + type: string + luogoNascita: + $ref: '#/components/schemas/TipoLuogoNascita3000' + TipoLuogoNascita3000: + type: object + properties: + luogoEccezionale: + type: string + comune: + $ref: '#/components/schemas/TipoComune' + localita: + $ref: '#/components/schemas/TipoLocalita' + TipoComune: + type: object + properties: + nomeComune: + type: string + codiceIstat: + type: string + siglaProvinciaIstat: + type: string + descrizioneLocalita: + type: string + TipoLocalita: + type: object + properties: + descrizioneLocalita: + type: string + descrizioneStato: + type: string + codiceStato: + type: string + provinciaContea: + type: string + TipoGeneralita: + type: object + properties: + codiceFiscale: + $ref: '#/components/schemas/TipoCodiceFiscale' + cognome: + type: string + senzaCognome: + type: string + nome: + type: string + senzaNome: + type: string + sesso: + type: string + dataNascita: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + senzaGiorno: + type: string + senzaGiornoMese: + type: string + luogoNascita: + $ref: '#/components/schemas/TipoLuogoEvento' + soggettoAIRE: + type: string + annoEspatrio: + type: string + idSchedaSoggettoComune: + $ref: '#/components/schemas/TipoIdSchedaSoggettoComune' + idSchedaSoggettoANPR: + type: string + note: + type: string + TipoCodiceFiscale: + type: object + properties: + codFiscale: + type: string + validitaCF: + type: string + description: 1 validato, 9 non validato + dataAttribuzioneValidita: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + TipoLuogoEvento: + type: object + properties: + luogoEccezionale: + type: string + comune: + $ref: '#/components/schemas/TipoComune' + localita: + $ref: '#/components/schemas/TipoLocalita' + TipoIdSchedaSoggettoComune: + type: object + properties: + idSchedaSoggettoComuneIstat: + type: string + idSchedaSoggetto: + type: string + TipoVerificaE002: + type: object + properties: + generalita: + $ref: '#/components/schemas/TipoGeneralita' + TipoListaSoggetti: + type: object + properties: + datiSoggetto: + type: array + items: + $ref: '#/components/schemas/TipoDatiSoggettiEnte' + TipoDatiSoggettiEnte: + type: object + properties: + infoSoggettoEnte: + type: array + items: + $ref: '#/components/schemas/TipoInfoSoggettoEnte' + TipoInfoSoggettoEnte: + type: object + properties: + id: + type: string + chiave: + type: string + valore: + $ref: '#/components/schemas/TipoInfoValore' + valoreTesto: + type: string + valoreData: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + dettaglio: + type: string + TipoInfoValore: + enum: + - A + - "N" + - S + type: string + 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 + Agid-JWT-Signature: + type: apiKey + in: header + name: Agid-JWT-Signature + description: |- + Header della firma di JWS. + Il valore di questo header è una firma JWS. + Vedere Modi [integrity_rest_02] Integrità del payload del messaggio REST in PDND + Agid-JWT-TrackingEvidence: + type: apiKey + in: header + name: Agid-JWT-TrackingEvidence + description: |- + Header della firma di JWS. + Il valore di questo header è una firma JWS. + Vedere Modi [audit_rest_02] Inoltro dati tracciati nel dominio del Fruitore REST con correlazione + Claim da includere: + userID, un identificativo univoco dell'utente interno al dominio del fruitore che ha determinato l'esigenza della request di accesso all'e-service dell'erogatore; + userLocation, un identificativo univoco della postazione interna al dominio del fruitore da cui è avviata l'esigenza della request di accesso all'e-service dell'erogatore; + LoA, livello di sicurezza o di garanzia adottato nel processo di autenticazione informatica nel dominio del fruitore. + diff --git a/openapi/anprApiC030.openapi.yaml b/openapi/anprApiC030.openapi.yaml new file mode 100644 index 0000000..02179ff --- /dev/null +++ b/openapi/anprApiC030.openapi.yaml @@ -0,0 +1,322 @@ +openapi: 3.0.3 +info: + title: Consultazione ANPR API C030 + description: |- + Servizio per la consultazione dell'id univoco nazionale ai fini di un accertamento + Pattern Model applicati: + - [AUDIT_REST_02 ] Inoltro dati tracciati nel dominio del Fruitore REST con correlazione + - [BLOCK_REST] Blocking REST + - [INTEGRITY_REST_02] Integrità del payload messaggio REST in PDND + version: '1.0.0' + contact: + name: API Support + email: Assistenza.anpr@pec.sogei.it + termsOfService: 'http://swagger.io/terms/' + x-api-id: C030 + x-summary: Accertamento dell'id univoco nazionale +servers: + - url: 'https://modipa-val.anpr.interno.it/govway/rest/in/MinInternoPortaANPR-PDND/C030-servizioAccertamentoIdUnicoNazionale/v1' + description: Url di test per Consultazione Enti C029 + - url: 'https://modipa.anpr.interno.it/govway/rest/in/MinInternoPortaANPR-PDND/C030-servizioAccertamentoIdUnicoNazionale/v1' + description: Url di esercizio per Consultazione Enti C029 +tags: + - name: E002 service + description: Manage consultazione enti +security: + - bearerAuth: [] + Agid-JWT-Signature: [] +paths: + /status: + get: + summary: Returns the application status + description: | + Returns the application status. For testing purposes, it might randomly reply with an error. + operationId: get_status + tags: + - health + responses: + '200': + description: | + This is the valid status from the server. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' + /anpr-service-e002: + post: + tags: + - E002 service + summary: Trova caso d'uso + description: Consultazione di un caso d'uso + operationId: e002 + security: + - bearerAuth: [] + requestBody: + required: true + description: Richiesta da consultare + content: + application/json: + schema: + $ref: '#/components/schemas/RichiestaE002' + responses: + "200": + description: Caso d'uso trovato + content: + application/json: + schema: + $ref: '#/components/schemas/RispostaE002OK' + "400": + description: Caso d'uso invalido + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' + "404": + description: Caso d'uso non trovato + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' + "500": + description: Internal Server Error + content: + application/problem+json: + schema: + $ref: '#/components/schemas/RispostaKO' +components: + schemas: + RichiestaE002: + type: object + required: + - idOperazioneClient + - criteriRicerca + - datiRichiesta + properties: + idOperazioneClient: + type: string + description: Identificativo univoco attribuito all'operazione dall'ente. Deve essere un alfanumerico. Si consiglia di usare il timestamp o un identificativo della postazione piu' il timestamp + criteriRicerca: + $ref: '#/components/schemas/TipoCriteriRicercaE002' + datiRichiesta: + $ref: '#/components/schemas/TipoDatiRichiestaE002' + RispostaE002OK: + type: object + properties: + idOperazioneANPR: + type: string + listaSoggetti: + $ref: '#/components/schemas/TipoListaSoggetti' + listaAnomalie: + type: array + items: + $ref: '#/components/schemas/TipoErroriAnomalia' + RispostaKO: + type: object + properties: + idOperazioneANPR: + type: string + listaErrori: + type: array + items: + $ref: '#/components/schemas/TipoErroriAnomalia' + TipoCriteriRicercaE002: + type: object + properties: + codiceFiscale: + type: string + cognome: + type: string + senzaCognome: + type: string + nome: + type: string + senzaNome: + type: string + sesso: + type: string + datiNascita: + $ref: '#/components/schemas/TipoDatiNascitaE000' + TipoDatiRichiestaE002: + type: object + required: + - dataRiferimentoRichiesta + - casoUso + - motivoRichiesta + properties: + dataRiferimentoRichiesta: + type: string + description: Data cui deve essere riferita la versione della scheda anagrafica + format: YYYY-MM-DD + example: '2021-11-15' + motivoRichiesta: + type: string + description: campo per l’indicazione obbligatoria del numero di riferimento della pratica per quale è effettuata l’interrogazione (es. numero di protocollo, fascicolo, verbale, etc.) + casoUso: + type: string + description: caso d'uso (es. C001) + TipoErroriAnomalia: + type: object + properties: + codiceErroreAnomalia: + type: string + tipoErroreAnomalia: + type: string + testoErroreAnomalia: + type: string + oggettoErroreAnomalia: + type: string + campoErroreAnomalia: + type: string + valoreErroreAnomalia: + type: string + TipoListaSoggetti: + type: object + properties: + datiSoggetto: + type: array + items: + $ref: '#/components/schemas/TipoDatiSoggettiEnte' + TipoDatiSoggettiEnte: + type: object + properties: + identificativi: + $ref: '#/components/schemas/TipoIdentificativi' + TipoIdentificativi: + type: object + properties: + idANPR: + type: string + TipoDatiNascitaE000: + type: object + properties: + dataEvento: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + senzaGiorno: + type: string + senzaGiornoMese: + type: string + luogoNascita: + $ref: '#/components/schemas/TipoLuogoNascita3000' + TipoLuogoNascita3000: + type: object + properties: + luogoEccezionale: + type: string + comune: + $ref: '#/components/schemas/TipoComune' + localita: + $ref: '#/components/schemas/TipoLocalita' + TipoComune: + type: object + properties: + nomeComune: + type: string + codiceIstat: + type: string + siglaProvinciaIstat: + type: string + descrizioneLocalita: + type: string + TipoLocalita: + type: object + properties: + descrizioneLocalita: + type: string + descrizioneStato: + type: string + codiceStato: + type: string + provinciaContea: + type: string + TipoGeneralita: + type: object + properties: + codiceFiscale: + $ref: '#/components/schemas/TipoCodiceFiscale' + cognome: + type: string + senzaCognome: + type: string + nome: + type: string + senzaNome: + type: string + sesso: + type: string + dataNascita: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + senzaGiorno: + type: string + senzaGiornoMese: + type: string + luogoNascita: + $ref: '#/components/schemas/TipoLuogoEvento' + soggettoAIRE: + type: string + annoEspatrio: + type: string + idSchedaSoggettoComune: + $ref: '#/components/schemas/TipoIdSchedaSoggettoComune' + idSchedaSoggettoANPR: + type: string + note: + type: string + TipoCodiceFiscale: + type: object + properties: + codFiscale: + type: string + validitaCF: + type: string + description: 1 validato, 9 non validato + dataAttribuzioneValidita: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + TipoLuogoEvento: + type: object + properties: + luogoEccezionale: + type: string + comune: + $ref: '#/components/schemas/TipoComune' + localita: + $ref: '#/components/schemas/TipoLocalita' + TipoIdSchedaSoggettoComune: + type: object + properties: + idSchedaSoggettoComuneIstat: + type: string + idSchedaSoggetto: + type: string + 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 + Agid-JWT-Signature: + type: apiKey + in: header + name: Agid-JWT-Signature + description: |- + Header della firma di JWS. + Il valore di questo header è una firma JWS. + Vedere Modi [integrity_rest_02] Integrità del payload del messaggio REST in PDND + Agid-JWT-TrackingEvidence: + type: apiKey + in: header + name: Agid-JWT-TrackingEvidence + description: |- + Header della firma di JWS. + Il valore di questo header è una firma JWS. + Vedere Modi [audit_rest_02] Inoltro dati tracciati nel dominio del Fruitore REST con correlazione + Claim da includere: + userID, un identificativo univoco dell'utente interno al dominio del fruitore che ha determinato l'esigenza della request di accesso all'e-service dell'erogatore; + userLocation, un identificativo univoco della postazione interna al dominio del fruitore da cui è avviata l'esigenza della request di accesso all'e-service dell'erogatore; + LoA, livello di sicurezza o di garanzia adottato nel processo di autenticazione informatica nel dominio del fruitore. + diff --git a/openapi/p4pa-pdnd.openapi.yaml b/openapi/p4pa-pdnd.openapi.yaml index 6992bcd..84cfcff 100644 --- a/openapi/p4pa-pdnd.openapi.yaml +++ b/openapi/p4pa-pdnd.openapi.yaml @@ -1,31 +1,71 @@ -openapi: 3.0.1 +openapi: 3.0.3 info: - title: Fake API - description: "Una semplice API di esempio" - version: "1.0.0" + title: P4PA-PDND-Service API + description: API and Models. + version: 0.0.1 +servers: + - url: "http://localhost:8080/p4papdnd" paths: - /api/v1/greet: + /anpr-service-e002/citizen: get: - summary: "Ottieni un saluto" - description: "Endpoint di esempio che restituisce un saluto" + summary: Retrieve citizen data + description: Returns detailed information about a citizen based on their fiscal code. + parameters: + - name: fiscalCode + in: query + description: The fiscal code of the citizen + required: true + schema: + type: string + example: RSSMRA85M01H501Z responses: '200': - description: "Successo" + description: OK content: application/json: schema: type: object properties: - message: + firstName: type: string - example: "Hello, World!" - '500': - description: "Errore interno del server" - content: - application/json: - schema: - type: object - properties: - error: + example: Mario + lastName: type: string - example: "Errore interno del server" \ No newline at end of file + example: Rossi + dateOfBirth: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + address: + $ref: '#/components/schemas/Address' + '400': + description: Invalid request + '403': + description: Forbidden + '404': + description: Citizen not found + '500': + description: Internal server error +security: + - BearerAuth: [] +components: + securitySchemes: + BearerAuth: + type: http + scheme: bearer + schemas: + Address: + type: object + properties: + street: + type: string + example: Via Roma 10 + city: + type: string + example: Roma + postalCode: + type: string + example: 00100 + country: + type: string + example: Italy \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/anpr/AnprC003ServiceConfig.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceConfig.java similarity index 87% rename from src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/anpr/AnprC003ServiceConfig.java rename to src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceConfig.java index 9013207..26c5f40 100644 --- a/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/anpr/AnprC003ServiceConfig.java +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceConfig.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payhub.pdnd.config.pdnd.anpr; +package it.gov.pagopa.payhub.pdnd.anpr.c003.service; import it.gov.pagopa.payhub.pdnd.config.pdnd.PdndServiceIntegratedConfig; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030Client.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030Client.java new file mode 100644 index 0000000..58a0d09 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030Client.java @@ -0,0 +1,8 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c030.client; + +import it.gov.pagopa.payhub.anpr.C030.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; + +public interface AnprC030Client { + RispostaE002OK getIdAnprFromFc(RichiestaE002 request); +} diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java new file mode 100644 index 0000000..55cc1da --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java @@ -0,0 +1,45 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c030.client; + +import it.gov.pagopa.payhub.anpr.C030.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.pdnd.anpr.c030.service.AnprC030ServiceConfig; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class AnprC030ClientImpl implements AnprC030Client { + + @Value("${app.pdnd.anpr.base-url}") + private String anprBasePath; + private final RestTemplate restTemplate; + private final AnprC030ServiceConfig anprC030ServiceConfig; + + public AnprC030ClientImpl(RestTemplateBuilder restTemplateBuilder, AnprC030ServiceConfig anprC030ServiceConfig) { + this.restTemplate = restTemplateBuilder.build(); + this.anprC030ServiceConfig = anprC030ServiceConfig; + } + + public RispostaE002OK getIdAnprFromFc(RichiestaE002 request) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", "application/json"); + headers.set("Accept", "application/json"); + + HttpEntity entity = new HttpEntity<>(request, headers); + + ResponseEntity response = restTemplate.exchange( + anprBasePath + anprC030ServiceConfig.getUrl(), + HttpMethod.POST, + entity, + RispostaE002OK.class + ); + + return response.getBody(); + } +} + diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030Service.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030Service.java new file mode 100644 index 0000000..6059b65 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030Service.java @@ -0,0 +1,47 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c030.service; + +import it.gov.pagopa.payhub.anpr.C030.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.anpr.C030.model.generated.TipoCriteriRicercaE002; +import it.gov.pagopa.payhub.anpr.C030.model.generated.TipoDatiRichiestaE002; +import it.gov.pagopa.payhub.pdnd.anpr.c030.client.AnprC030Client; +import it.gov.pagopa.payhub.pdnd.anpr.c030.client.AnprC030ClientImpl; +import org.springframework.stereotype.Service; + +import java.time.Instant; +import java.util.UUID; + +@Service +public class AnprC030Service { + + private final AnprC030Client anprC030Client; + + public AnprC030Service(AnprC030ClientImpl anprC030Client) { + this.anprC030Client = anprC030Client; + } + + public RispostaE002OK getIdAnprFromFc(String fiscalCode) { + TipoCriteriRicercaE002 searchTypes = TipoCriteriRicercaE002.builder() + .codiceFiscale(fiscalCode) + .build(); + + TipoDatiRichiestaE002 reqDataTypes = TipoDatiRichiestaE002.builder() + .casoUso("C030") + .build(); + + RichiestaE002 request = RichiestaE002.builder() + .idOperazioneClient(generateIdClientOperation(fiscalCode)) + .criteriRicerca(searchTypes) + .datiRichiesta(reqDataTypes) + .build(); + + return anprC030Client.getIdAnprFromFc(request); + } + + private String generateIdClientOperation(String fiscalCode) { + String timestamp = String.valueOf(Instant.now().toEpochMilli()); + String uuid = UUID.nameUUIDFromBytes(fiscalCode.getBytes()).toString(); + return uuid + "-" + timestamp; + } +} + diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/anpr/AnprC030ServiceConfig.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceConfig.java similarity index 87% rename from src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/anpr/AnprC030ServiceConfig.java rename to src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceConfig.java index 962660b..419687e 100644 --- a/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/anpr/AnprC030ServiceConfig.java +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceConfig.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.payhub.pdnd.config.pdnd.anpr; +package it.gov.pagopa.payhub.pdnd.anpr.c030.service; import it.gov.pagopa.payhub.pdnd.config.pdnd.PdndServiceIntegratedConfig; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/PdndServiceIntegratedConfig.java b/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/PdndServiceIntegratedConfig.java index db040ff..765d7ba 100644 --- a/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/PdndServiceIntegratedConfig.java +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/config/pdnd/PdndServiceIntegratedConfig.java @@ -14,4 +14,5 @@ public abstract class PdndServiceIntegratedConfig { private String purposeId; private String privateKey; private String publicKey; + private String url; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 096b5df..830d43a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,6 +21,7 @@ app: config: audience: "\${PDND_ACCESS_TOKEN_AUDIENCE:auth.uat.interop.pagopa.it/client-assertion}" anpr: + base-url: "\${ANPR_BASE_URL:http://localhost:8080}" services: c003: client-id: "\${PDND_SERVICE_ANPR_C003_CLIENTID:\${PDND_SERVICE_ANPR_CLIENTID:\${PDND_SERVICE_CLIENTID:clientid}}}" @@ -28,14 +29,18 @@ app: purpose-id: "\${PDND_SERVICE_ANPR_C003_PURPOSE_ID:c003purposeid}" privateKey: "\${PDND_SERVICE_ANPR_C003_PRIVATEKEY:\${PDND_SERVICE_ANPR_PRIVATEKEY:\${PDND_SERVICE_PRIVATEKEY:}}}" publicKey: "\${PDND_SERVICE_ANPR_C003_PUBLICKEY:\${PDND_SERVICE_ANPR_PUBLICKEY:\${PDND_SERVICE_PUBLICKEY:}}}" + url: "\${PDND_SERVICE_ANPR_C003_URL:/govway/rest/in/MinInternoPortaANPR-PDND/C003-servizioVerificaDichGeneralita/v1/anpr-service-e002}" c030: client-id: "\${PDND_SERVICE_ANPR_C030_CLIENTID:\${PDND_SERVICE_ANPR_CLIENTID:\${PDND_SERVICE_CLIENTID:clientid}}}" kid: "\${PDND_SERVICE_ANPR_C030_KID:\${PDND_SERVICE_ANPR_KID:\${PDND_SERVICE_KID:kid}}}" purpose-id: "\${PDND_SERVICE_ANPR_C030_PURPOSE_ID:c030purposeid}" privateKey: "\${PDND_SERVICE_ANPR_C030_PRIVATEKEY:\${PDND_SERVICE_ANPR_PRIVATEKEY:\${PDND_SERVICE_PRIVATEKEY:}}}" publicKey: "\${PDND_SERVICE_ANPR_C030_PUBLICKEY:\${PDND_SERVICE_ANPR_PUBLICKEY:\${PDND_SERVICE_PUBLICKEY:}}}" + url: "\${PDND_SERVICE_ANPR_C030_URL:/govway/rest/in/MinInternoPortaANPR-PDND/C030-servizioAccertamentoIdUnicoNazionale/v1/anpr-service-e002}" rest-client: connect.timeout.millis: "\${CONNECT_TIMEOUT_MILLIS:120000}" read.timeout.millis: "\${READ_TIMEOUT_MILLIS:120000}" auth: - base-url: "\${AUTH_SERVER_BASE_URL:https://auth-server/api}" \ No newline at end of file + base-url: "\${AUTH_SERVER_BASE_URL:https://auth-server/api}" +server: + port: 8081 \ No newline at end of file diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java new file mode 100644 index 0000000..7d9fad3 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java @@ -0,0 +1,74 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c030.client; + +import it.gov.pagopa.payhub.anpr.C030.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.pdnd.anpr.c030.service.AnprC030ServiceConfig; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.client.RestTemplate; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +class AnprC030ClientImplTest { + + @Mock + private RestTemplate restTemplate; + + @Mock + private RestTemplateBuilder restTemplateBuilder; + + @Mock + private AnprC030ServiceConfig anprC030ServiceConfig; + + private AnprC030ClientImpl anprC030Client; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + when(restTemplateBuilder.build()).thenReturn(restTemplate); + + anprC030Client = new AnprC030ClientImpl(restTemplateBuilder, anprC030ServiceConfig); + ReflectionTestUtils.setField(anprC030Client, "anprBasePath", "http://localhost:8080"); + } + + @Test + void testGetIdAnprFromFc() { + RichiestaE002 request = RichiestaE002.builder() + .idOperazioneClient("ID-ENTE-myHost-1701102800550") + .build(); + + RispostaE002OK mockResponse = RispostaE002OK.builder() + .idOperazioneANPR("ANPR-12345") + .build(); + + ResponseEntity responseEntity = ResponseEntity.ok(mockResponse); + + when(anprC030ServiceConfig.getUrl()).thenReturn("/test"); + when(restTemplate.exchange( + eq("http://localhost:8080/test"), + eq(HttpMethod.POST), + any(), + eq(RispostaE002OK.class) + )).thenReturn(responseEntity); + + RispostaE002OK result = anprC030Client.getIdAnprFromFc(request); + + assertEquals("ANPR-12345", result.getIdOperazioneANPR()); + verify(restTemplate, times(1)).exchange( + eq("http://localhost:8080/test"), + eq(HttpMethod.POST), + any(), + eq(RispostaE002OK.class) + ); + } +} diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java new file mode 100644 index 0000000..2781f16 --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java @@ -0,0 +1,52 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c030.service; + +import it.gov.pagopa.payhub.anpr.C030.model.generated.*; +import it.gov.pagopa.payhub.pdnd.anpr.c030.client.AnprC030ClientImpl; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class AnprC030ServiceTest { + + @Mock + private AnprC030ClientImpl anprC030ClientImpl; + + @InjectMocks + private AnprC030Service anprC030Service; + + @Test + void testGetIdAnprFromFc() { + String fiscalCode = "DNTCRL65S67M126K"; + + TipoIdentificativi idTypes = TipoIdentificativi.builder() + .idANPR("d20fcd8e-f228-323c-8924-6405b44879bf").build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .identificativi(idTypes).build(); + + TipoListaSoggetti subListTypes = TipoListaSoggetti.builder() + .datiSoggetto(List.of(subDataTypes)).build(); + + RispostaE002OK mockResponse = RispostaE002OK.builder() + .idOperazioneANPR("12345") + .listaSoggetti(subListTypes) + .listaAnomalie(null) + .build(); + + when(anprC030ClientImpl.getIdAnprFromFc(Mockito.any(RichiestaE002.class))).thenReturn(mockResponse); + + RispostaE002OK response = anprC030Service.getIdAnprFromFc(fiscalCode); + + assertNotNull(response); + assertEquals("d20fcd8e-f228-323c-8924-6405b44879bf", response.getListaSoggetti().getDatiSoggetto().getFirst().getIdentificativi().getIdANPR()); + } +} \ No newline at end of file From c6126b2757171fe27f02eb909c7a7120edabe523 Mon Sep 17 00:00:00 2001 From: RiccardoGiuliani <144138935+RiccardoGiuliani@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:34:11 +0100 Subject: [PATCH 3/7] feat: P4ADEV-1429 invoke service mock C003 (#11) --- .../pdnd/anpr/c003/client/AnprC003Client.java | 8 ++ .../anpr/c003/client/AnprC003ClientImpl.java | 29 ++++++ .../anpr/c003/service/AnprC003Service.java | 47 ++++++++++ .../anpr/c030/client/AnprC030ClientImpl.java | 36 ++----- .../pdnd/anpr/client/AbstractAnprClient.java | 41 ++++++++ .../c003/client/AnprC003ClientImplTest.java | 94 +++++++++++++++++++ .../c003/service/AnprC003ServiceTest.java | 61 ++++++++++++ .../c030/client/AnprC030ClientImplTest.java | 2 +- 8 files changed, 291 insertions(+), 27 deletions(-) create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003Client.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImpl.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003Service.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/client/AbstractAnprClient.java create mode 100644 src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java create mode 100644 src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003Client.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003Client.java new file mode 100644 index 0000000..24995b9 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003Client.java @@ -0,0 +1,8 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c003.client; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK; + +public interface AnprC003Client { + RispostaE002OK getUserData(RichiestaE002 request); +} diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImpl.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImpl.java new file mode 100644 index 0000000..f9c6968 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImpl.java @@ -0,0 +1,29 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c003.client; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.pdnd.anpr.c003.service.AnprC003ServiceConfig; +import it.gov.pagopa.payhub.pdnd.anpr.client.AbstractAnprClient; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.stereotype.Component; + +@Component +public class AnprC003ClientImpl extends AbstractAnprClient implements AnprC003Client { + + private final AnprC003ServiceConfig anprC003ServiceConfig; + + public AnprC003ClientImpl(RestTemplateBuilder restTemplateBuilder, AnprC003ServiceConfig anprC003ServiceConfig) { + super(restTemplateBuilder); + this.anprC003ServiceConfig = anprC003ServiceConfig; + } + + @Override + protected String getEndpointPath() { + return anprC003ServiceConfig.getUrl(); + } + + @Override + public RispostaE002OK getUserData(RichiestaE002 request) { + return sendRequest(request, RispostaE002OK.class); + } +} diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003Service.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003Service.java new file mode 100644 index 0000000..717547a --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003Service.java @@ -0,0 +1,47 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c003.service; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.RichiestaE002; +import it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.anpr.C003.model.generated.TipoCriteriRicercaE002; +import it.gov.pagopa.payhub.anpr.C003.model.generated.TipoDatiRichiestaE002; +import it.gov.pagopa.payhub.pdnd.anpr.c003.client.AnprC003Client; +import it.gov.pagopa.payhub.pdnd.anpr.c003.client.AnprC003ClientImpl; +import org.springframework.stereotype.Service; + +import java.time.Instant; +import java.util.UUID; + +@Service +public class AnprC003Service { + + private final AnprC003Client anprC003Client; + + public AnprC003Service(AnprC003ClientImpl anprC003Client) { + this.anprC003Client = anprC003Client; + } + + public RispostaE002OK getUserData(String idAnpr, String fiscalCode) { + TipoCriteriRicercaE002 searchTypes = TipoCriteriRicercaE002.builder() + .idANPR(idAnpr) + .build(); + + TipoDatiRichiestaE002 reqDataTypes = TipoDatiRichiestaE002.builder() + .casoUso("C003") + .build(); + + RichiestaE002 request = RichiestaE002.builder() + .idOperazioneClient(generateIdClientOperation(fiscalCode)) + .criteriRicerca(searchTypes) + .datiRichiesta(reqDataTypes) + .build(); + + return anprC003Client.getUserData(request); + } + + private String generateIdClientOperation(String fiscalCode) { + String timestamp = String.valueOf(Instant.now().toEpochMilli()); + String uuid = UUID.nameUUIDFromBytes(fiscalCode.getBytes()).toString(); + return uuid + "-" + timestamp; + } +} + diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java index 55cc1da..c5eab6d 100644 --- a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java @@ -3,43 +3,27 @@ import it.gov.pagopa.payhub.anpr.C030.model.generated.RichiestaE002; import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; import it.gov.pagopa.payhub.pdnd.anpr.c030.service.AnprC030ServiceConfig; -import org.springframework.beans.factory.annotation.Value; +import it.gov.pagopa.payhub.pdnd.anpr.client.AbstractAnprClient; import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; @Component -public class AnprC030ClientImpl implements AnprC030Client { +public class AnprC030ClientImpl extends AbstractAnprClient implements AnprC030Client { - @Value("${app.pdnd.anpr.base-url}") - private String anprBasePath; - private final RestTemplate restTemplate; private final AnprC030ServiceConfig anprC030ServiceConfig; public AnprC030ClientImpl(RestTemplateBuilder restTemplateBuilder, AnprC030ServiceConfig anprC030ServiceConfig) { - this.restTemplate = restTemplateBuilder.build(); + super(restTemplateBuilder); this.anprC030ServiceConfig = anprC030ServiceConfig; } - public RispostaE002OK getIdAnprFromFc(RichiestaE002 request) { - HttpHeaders headers = new HttpHeaders(); - headers.set("Content-Type", "application/json"); - headers.set("Accept", "application/json"); - - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange( - anprBasePath + anprC030ServiceConfig.getUrl(), - HttpMethod.POST, - entity, - RispostaE002OK.class - ); + @Override + protected String getEndpointPath() { + return anprC030ServiceConfig.getUrl(); + } - return response.getBody(); + @Override + public RispostaE002OK getIdAnprFromFc(RichiestaE002 request) { + return sendRequest(request, RispostaE002OK.class); } } - diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/client/AbstractAnprClient.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/client/AbstractAnprClient.java new file mode 100644 index 0000000..ef6fd65 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/client/AbstractAnprClient.java @@ -0,0 +1,41 @@ +package it.gov.pagopa.payhub.pdnd.anpr.client; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +public abstract class AbstractAnprClient { + + @Value("${app.pdnd.anpr.base-url}") + private String anprBasePath; + + private final RestTemplate restTemplate; + + protected AbstractAnprClient(RestTemplateBuilder restTemplateBuilder) { + this.restTemplate = restTemplateBuilder.build(); + } + + protected abstract String getEndpointPath(); + + public S sendRequest(R request, Class responseType) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", "application/json"); + headers.set("Accept", "application/json"); + + HttpEntity entity = new HttpEntity<>(request, headers); + + ResponseEntity response = restTemplate.exchange( + anprBasePath + getEndpointPath(), + HttpMethod.POST, + entity, + responseType + ); + + return response.getBody(); + } +} + diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java new file mode 100644 index 0000000..77b8a4b --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java @@ -0,0 +1,94 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c003.client; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.*; +import it.gov.pagopa.payhub.pdnd.anpr.c003.service.AnprC003ServiceConfig; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.client.RestTemplate; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +class AnprC003ClientImplTest { + + @Mock + private RestTemplate restTemplate; + + @Mock + private RestTemplateBuilder restTemplateBuilder; + + @Mock + private AnprC003ServiceConfig anprC003ServiceConfig; + + private AnprC003ClientImpl anprC003Client; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + when(restTemplateBuilder.build()).thenReturn(restTemplate); + + anprC003Client = new AnprC003ClientImpl(restTemplateBuilder, anprC003ServiceConfig); + ReflectionTestUtils.setField(anprC003Client, "anprBasePath", "http://localhost:8080"); + } + + @Test + void getUserData() { + RichiestaE002 request = RichiestaE002.builder() + .idOperazioneClient("13f32508-7bcb-38d0-8510-d68bf240aa59-1733496758205") + .build(); + + TipoInfoSoggettoEnte subTypeInfo = TipoInfoSoggettoEnte.builder() + .id("nome") + .chiave("Jed") + .valore(TipoInfoValore.S) + .valoreTesto("Nome del soggetto") + .valoreData("2024-11-02") + .dettaglio("") + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .infoSoggettoEnte(List.of(subTypeInfo)) + .build(); + + TipoListaSoggetti subTypeList = TipoListaSoggetti.builder() + .datiSoggetto(List.of(subDataTypes)) + .build(); + + RispostaE002OK mockResponse = RispostaE002OK.builder() + .idOperazioneANPR("ANPR-12345") + .listaSoggetti(subTypeList) + .build(); + + ResponseEntity responseEntity = ResponseEntity.ok(mockResponse); + + when(anprC003ServiceConfig.getUrl()).thenReturn("/test"); + when(restTemplate.exchange( + eq("http://localhost:8080/test"), + eq(HttpMethod.POST), + any(), + eq(RispostaE002OK.class) + )).thenReturn(responseEntity); + + RispostaE002OK result = anprC003Client.getUserData(request); + + assertEquals("ANPR-12345", result.getIdOperazioneANPR()); + assertEquals(1, result.getListaSoggetti().getDatiSoggetto().size()); + verify(restTemplate, times(1)).exchange( + eq("http://localhost:8080/test"), + eq(HttpMethod.POST), + any(), + eq(RispostaE002OK.class) + ); + } +} \ No newline at end of file diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java new file mode 100644 index 0000000..005c5de --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java @@ -0,0 +1,61 @@ +package it.gov.pagopa.payhub.pdnd.anpr.c003.service; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.*; +import it.gov.pagopa.payhub.pdnd.anpr.c003.client.AnprC003ClientImpl; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class AnprC003ServiceTest { + + @Mock + private AnprC003ClientImpl anprC003ClientImpl; + + @InjectMocks + private AnprC003Service anprC003Service; + + @Test + void getUserData() { + String fiscalCode = "DNTCRL65S67M126K"; + String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; + + TipoInfoSoggettoEnte subTypeInfo = TipoInfoSoggettoEnte.builder() + .id("nome") + .chiave("Jed") + .valore(TipoInfoValore.S) + .valoreTesto("Nome del soggetto") + .valoreData("2024-11-02") + .dettaglio("") + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .infoSoggettoEnte(List.of(subTypeInfo)) + .build(); + + TipoListaSoggetti subTypeList = TipoListaSoggetti.builder() + .datiSoggetto(List.of(subDataTypes)) + .build(); + + RispostaE002OK mockResponse = RispostaE002OK.builder() + .idOperazioneANPR("12345") + .listaSoggetti(subTypeList) + .listaAnomalie(null) + .build(); + + when(anprC003ClientImpl.getUserData(Mockito.any(RichiestaE002.class))).thenReturn(mockResponse); + + RispostaE002OK response = anprC003Service.getUserData(idAnpr, fiscalCode); + + assertNotNull(response); + assertEquals("Jed", response.getListaSoggetti().getDatiSoggetto().getFirst().getInfoSoggettoEnte().getFirst().getChiave()); + } +} \ No newline at end of file diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java index 7d9fad3..7e5a85f 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java @@ -44,7 +44,7 @@ void setUp() { @Test void testGetIdAnprFromFc() { RichiestaE002 request = RichiestaE002.builder() - .idOperazioneClient("ID-ENTE-myHost-1701102800550") + .idOperazioneClient("13f32508-7bcb-38d0-8510-d68bf240aa59-1733496758205") .build(); RispostaE002OK mockResponse = RispostaE002OK.builder() From ad1d364024ccc85e3c209954569651a69d4e0d1b Mon Sep 17 00:00:00 2001 From: RiccardoGiuliani <144138935+RiccardoGiuliani@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:11:22 +0100 Subject: [PATCH 4/7] feat: P4ADEV-1352 api to retrieve citizen data (#12) --- helm/values-prod.yaml | 2 +- openapi/p4pa-pdnd.openapi.yaml | 32 +- .../controller/PdndServiceController.java | 23 ++ .../pdnd/anpr/mapper/AnprResponseMapper.java | 55 +++ .../payhub/pdnd/anpr/service/PdndService.java | 8 + .../pdnd/anpr/service/PdndServiceImpl.java | 34 ++ src/main/resources/application.yml | 2 +- .../controller/PdndServiceControllerTest.java | 54 +++ .../anpr/service/PdndServiceImplTest.java | 182 ++++++++ ...A-PDND-Service API.postman_collection.json | 388 ++++++++++++++++++ 10 files changed, 763 insertions(+), 17 deletions(-) create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/mapper/AnprResponseMapper.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndService.java create mode 100644 src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImpl.java create mode 100644 src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java create mode 100644 src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java create mode 100644 src/test/postman/P4PA-PDND-Service API.postman_collection.json diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 69a4c06..8dd9e6e 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -39,7 +39,7 @@ microservice-chart: PDND_SERVICE_ANPR_C003_PURPOSE_ID: 5ba1f38f-6a91-4da4-8a42-4da1aa55bfee PDND_SERVICE_ANPR_C030_PURPOSE_ID: 87520bd5-207a-4616-85d9-10d7bb3e88b8 - ANPR_BASE_URL: https://p4pa-mocks-microservice-chart:8080 + ANPR_BASE_URL: http://p4pa-mocks-microservice-chart:8080 keyvault: name: "p4pa-p-payhub-kv" diff --git a/openapi/p4pa-pdnd.openapi.yaml b/openapi/p4pa-pdnd.openapi.yaml index 84cfcff..dd5cff0 100644 --- a/openapi/p4pa-pdnd.openapi.yaml +++ b/openapi/p4pa-pdnd.openapi.yaml @@ -24,20 +24,7 @@ paths: content: application/json: schema: - type: object - properties: - firstName: - type: string - example: Mario - lastName: - type: string - example: Rossi - dateOfBirth: - type: string - format: YYYY-MM-DD - example: '2021-11-15' - address: - $ref: '#/components/schemas/Address' + $ref: '#/components/schemas/Citizen' '400': description: Invalid request '403': @@ -68,4 +55,19 @@ components: example: 00100 country: type: string - example: Italy \ No newline at end of file + example: Italy + Citizen: + type: object + properties: + firstName: + type: string + example: Mario + lastName: + type: string + example: Rossi + dateOfBirth: + type: string + format: YYYY-MM-DD + example: '2021-11-15' + address: + $ref: '#/components/schemas/Address' \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java new file mode 100644 index 0000000..7e90f2a --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java @@ -0,0 +1,23 @@ +package it.gov.pagopa.payhub.pdnd.anpr.controller; + +import it.gov.pagopa.payhub.controller.generated.DefaultApi; +import it.gov.pagopa.payhub.model.generated.Citizen; +import it.gov.pagopa.payhub.pdnd.anpr.service.PdndService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PdndServiceController implements DefaultApi { + + private final PdndService pdndService; + + public PdndServiceController(PdndService pdndService) { + this.pdndService = pdndService; + } + + @Override + public ResponseEntity anprServiceE002CitizenGet(String fiscalCode) { + Citizen response = pdndService.getCitizenData(fiscalCode); + return ResponseEntity.ok(response); + } +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/mapper/AnprResponseMapper.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/mapper/AnprResponseMapper.java new file mode 100644 index 0000000..f861414 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/mapper/AnprResponseMapper.java @@ -0,0 +1,55 @@ +package it.gov.pagopa.payhub.pdnd.anpr.mapper; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.anpr.C003.model.generated.TipoDatiSoggettiEnte; +import it.gov.pagopa.payhub.anpr.C003.model.generated.TipoInfoSoggettoEnte; +import it.gov.pagopa.payhub.model.generated.Address; +import it.gov.pagopa.payhub.model.generated.Citizen; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class AnprResponseMapper { + + private AnprResponseMapper() { + } + + public static Citizen mapToAnprResponse(RispostaE002OK responseC003) { + List subTypeInfo = getTipoInfoSoggettoEnteList(responseC003); + + Map valuesMap = subTypeInfo.stream() + .collect(Collectors.toMap( + TipoInfoSoggettoEnte::getId, + TipoInfoSoggettoEnte::getChiave + )); + + Address address = Address.builder() + .street(valuesMap.get("street")) + .city(valuesMap.get("city")) + .postalCode(valuesMap.get("postalCode")) + .country(valuesMap.get("country")) + .build(); + + return Citizen.builder() + .firstName(valuesMap.get("firstName")) + .lastName(valuesMap.get("lastName")) + .dateOfBirth(valuesMap.get("dateOfBirth")) + .address(address) + .build(); + } + + private static List getTipoInfoSoggettoEnteList(RispostaE002OK responseC003) { + if (responseC003 == null || responseC003.getListaSoggetti() == null) { + throw new IllegalArgumentException("No valid data in listaSoggetti found in response"); + } + + List subDataTypes = responseC003.getListaSoggetti().getDatiSoggetto(); + if (subDataTypes == null || subDataTypes.isEmpty()) { + throw new IllegalArgumentException("No subject data in datiSoggetto found in response"); + } + + return subDataTypes.getFirst().getInfoSoggettoEnte(); + } +} + diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndService.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndService.java new file mode 100644 index 0000000..f63c355 --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndService.java @@ -0,0 +1,8 @@ +package it.gov.pagopa.payhub.pdnd.anpr.service; + +import it.gov.pagopa.payhub.model.generated.Citizen; + +public interface PdndService { + + Citizen getCitizenData(String fiscalCode); +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImpl.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImpl.java new file mode 100644 index 0000000..ffd51ee --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImpl.java @@ -0,0 +1,34 @@ +package it.gov.pagopa.payhub.pdnd.anpr.service; + +import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.model.generated.Citizen; +import it.gov.pagopa.payhub.pdnd.anpr.c003.service.AnprC003Service; +import it.gov.pagopa.payhub.pdnd.anpr.c030.service.AnprC030Service; +import it.gov.pagopa.payhub.pdnd.anpr.mapper.AnprResponseMapper; +import org.springframework.stereotype.Service; + +@Service +public class PdndServiceImpl implements PdndService { + + private final AnprC003Service anprC003Service; + private final AnprC030Service anprC030Service; + + public PdndServiceImpl(AnprC003Service anprC003Service, AnprC030Service anprC030Service) { + this.anprC003Service = anprC003Service; + this.anprC030Service = anprC030Service; + } + + @Override + public Citizen getCitizenData(String fiscalCode) { + RispostaE002OK anprC030Response = anprC030Service.getIdAnprFromFc(fiscalCode); + String idAnpr = anprC030Response.getListaSoggetti() + .getDatiSoggetto() + .getFirst() + .getIdentificativi() + .getIdANPR(); + + it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK anprC003Response = anprC003Service.getUserData(idAnpr, fiscalCode); + + return AnprResponseMapper.mapToAnprResponse(anprC003Response); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 830d43a..147a48f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,7 +21,7 @@ app: config: audience: "\${PDND_ACCESS_TOKEN_AUDIENCE:auth.uat.interop.pagopa.it/client-assertion}" anpr: - base-url: "\${ANPR_BASE_URL:http://localhost:8080}" + base-url: "\${ANPR_BASE_URL:http://p4pa-mocks-microservice-chart:8080}" services: c003: client-id: "\${PDND_SERVICE_ANPR_C003_CLIENTID:\${PDND_SERVICE_ANPR_CLIENTID:\${PDND_SERVICE_CLIENTID:clientid}}}" diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java new file mode 100644 index 0000000..0b25f2c --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java @@ -0,0 +1,54 @@ +package it.gov.pagopa.payhub.pdnd.anpr.controller; + +import it.gov.pagopa.payhub.model.generated.Address; +import it.gov.pagopa.payhub.model.generated.Citizen; +import it.gov.pagopa.payhub.pdnd.anpr.service.PdndService; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(value = PdndServiceController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class) +@ContextConfiguration(classes = {PdndServiceController.class}) +class PdndServiceControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private PdndService pdndService; + + @Test + void testAnprServiceE002CitizenGet_Success() throws Exception { + String fiscalCode = "DNTCRL65S67M126K"; + Citizen citizen = Citizen.builder() + .firstName("Julieta") + .lastName("Lindgren") + .dateOfBirth("2024-12-11") + .address(Address.builder() + .street("106 Hansen Mountains") + .city("West Aurelio") + .postalCode("36495-0217") + .country("Heard Island and McDonald Islands") + .build()) + .build(); + + Mockito.when(pdndService.getCitizenData(fiscalCode)).thenReturn(citizen); + + mockMvc.perform(get("/p4papdnd/anpr-service-e002/citizen") + .param("fiscalCode", fiscalCode)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.firstName").value("Julieta")) + .andExpect(jsonPath("$.lastName").value("Lindgren")); + + Mockito.verify(pdndService, Mockito.times(1)).getCitizenData(Mockito.any()); + } +} \ No newline at end of file diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java new file mode 100644 index 0000000..503a81e --- /dev/null +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java @@ -0,0 +1,182 @@ +package it.gov.pagopa.payhub.pdnd.anpr.service; + +import it.gov.pagopa.payhub.anpr.C003.model.generated.TipoInfoSoggettoEnte; +import it.gov.pagopa.payhub.anpr.C003.model.generated.TipoInfoValore; +import it.gov.pagopa.payhub.anpr.C030.model.generated.RispostaE002OK; +import it.gov.pagopa.payhub.anpr.C030.model.generated.TipoDatiSoggettiEnte; +import it.gov.pagopa.payhub.anpr.C030.model.generated.TipoIdentificativi; +import it.gov.pagopa.payhub.anpr.C030.model.generated.TipoListaSoggetti; +import it.gov.pagopa.payhub.model.generated.Citizen; +import it.gov.pagopa.payhub.pdnd.anpr.c003.service.AnprC003Service; +import it.gov.pagopa.payhub.pdnd.anpr.c030.service.AnprC030Service; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(MockitoExtension.class) +class PdndServiceImplTest { + + @Mock + private AnprC003Service anprC003Service; + + @Mock + private AnprC030Service anprC030Service; + + @InjectMocks + private PdndServiceImpl pdndService; + + @Test + void testGetCitizenData_Success() { + String fiscalCode = "DNTCRL65S67M126K"; + String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; + + TipoIdentificativi idTypes = TipoIdentificativi.builder() + .idANPR(idAnpr) + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .identificativi(idTypes) + .build(); + + RispostaE002OK anprC030Response = new RispostaE002OK(); + anprC030Response.setListaSoggetti(new TipoListaSoggetti(List.of(subDataTypes))); + + it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK anprC003Response = new it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK(); + TipoInfoSoggettoEnte subTypeInfo = TipoInfoSoggettoEnte.builder() + .id("firstName") + .chiave("Julieta") + .valore(TipoInfoValore.S) + .valoreTesto("First name of the subject") + .valoreData("2024-11-02") + .dettaglio("") + .build(); + + anprC003Response.setListaSoggetti(new it.gov.pagopa.payhub.anpr.C003.model.generated.TipoListaSoggetti(List.of( + new it.gov.pagopa.payhub.anpr.C003.model.generated.TipoDatiSoggettiEnte(List.of(subTypeInfo)) + ))); + + Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenReturn(anprC030Response); + Mockito.when(anprC003Service.getUserData(idAnpr, fiscalCode)).thenReturn(anprC003Response); + + Citizen result = pdndService.getCitizenData(fiscalCode); + + assertNotNull(result); + assertEquals("Julieta", result.getFirstName()); + } + + @Test + void testGetCitizenData_InvalidListaSoggetti() { + String fiscalCode = "DNTCRL65S67M126K"; + String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; + + TipoIdentificativi idTypes = TipoIdentificativi.builder() + .idANPR(idAnpr) + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .identificativi(idTypes) + .build(); + + RispostaE002OK anprC030Response = new RispostaE002OK(); + anprC030Response.setListaSoggetti(new TipoListaSoggetti(List.of(subDataTypes))); + + it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK anprC003Response = new it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK(); + anprC003Response.setListaSoggetti(null); + + Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenReturn(anprC030Response); + Mockito.when(anprC003Service.getUserData(idAnpr, fiscalCode)).thenReturn(anprC003Response); + + assertThrows(IllegalArgumentException.class, () -> pdndService.getCitizenData(fiscalCode)); + } + + @Test + void testGetCitizenData_InvalidC003Response() { + String fiscalCode = "DNTCRL65S67M126K"; + String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; + + TipoIdentificativi idTypes = TipoIdentificativi.builder() + .idANPR(idAnpr) + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .identificativi(idTypes) + .build(); + + RispostaE002OK anprC030Response = new RispostaE002OK(); + anprC030Response.setListaSoggetti(new TipoListaSoggetti(List.of(subDataTypes))); + + Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenReturn(anprC030Response); + Mockito.when(anprC003Service.getUserData(idAnpr, fiscalCode)).thenReturn(null); + + assertThrows(IllegalArgumentException.class, () -> pdndService.getCitizenData(fiscalCode)); + } + + @Test + void testGetCitizenData_InvalidSubDataType() { + String fiscalCode = "DNTCRL65S67M126K"; + String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; + + TipoIdentificativi idTypes = TipoIdentificativi.builder() + .idANPR(idAnpr) + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .identificativi(idTypes) + .build(); + + RispostaE002OK anprC030Response = new RispostaE002OK(); + anprC030Response.setListaSoggetti(new TipoListaSoggetti(List.of(subDataTypes))); + + it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK anprC003Response = new it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK(); + + anprC003Response.setListaSoggetti(new it.gov.pagopa.payhub.anpr.C003.model.generated.TipoListaSoggetti(null)); + + Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenReturn(anprC030Response); + Mockito.when(anprC003Service.getUserData(idAnpr, fiscalCode)).thenReturn(anprC003Response); + + assertThrows(IllegalArgumentException.class, () -> pdndService.getCitizenData(fiscalCode)); + } + + @Test + void testGetCitizenData_EmptySubDataType() { + String fiscalCode = "DNTCRL65S67M126K"; + String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; + + TipoIdentificativi idTypes = TipoIdentificativi.builder() + .idANPR(idAnpr) + .build(); + + TipoDatiSoggettiEnte subDataTypes = TipoDatiSoggettiEnte.builder() + .identificativi(idTypes) + .build(); + + RispostaE002OK anprC030Response = new RispostaE002OK(); + anprC030Response.setListaSoggetti(new TipoListaSoggetti(List.of(subDataTypes))); + + it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK anprC003Response = new it.gov.pagopa.payhub.anpr.C003.model.generated.RispostaE002OK(); + + anprC003Response.setListaSoggetti(new it.gov.pagopa.payhub.anpr.C003.model.generated.TipoListaSoggetti(new ArrayList<>())); + + Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenReturn(anprC030Response); + Mockito.when(anprC003Service.getUserData(idAnpr, fiscalCode)).thenReturn(anprC003Response); + + assertThrows(IllegalArgumentException.class, () -> pdndService.getCitizenData(fiscalCode)); + } + + @Test + void testGetCitizenData_InvalidResponse_ThrowsException() { + String fiscalCode = "DNTCRL65S67M126K"; + + Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenThrow(new RuntimeException("Service unavailable")); + + assertThrows(RuntimeException.class, () -> pdndService.getCitizenData(fiscalCode)); + } +} diff --git a/src/test/postman/P4PA-PDND-Service API.postman_collection.json b/src/test/postman/P4PA-PDND-Service API.postman_collection.json new file mode 100644 index 0000000..fb2d351 --- /dev/null +++ b/src/test/postman/P4PA-PDND-Service API.postman_collection.json @@ -0,0 +1,388 @@ +{ + "info": { + "_postman_id": "07c1f103-1e5f-44fe-a5e3-00126c6ece77", + "name": "P4PA-PDND-Service API", + "description": "API and Models.", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "29646859", + "_collection_link": "https://crimson-zodiac-456704.postman.co/workspace/Personal-Workspace~7804a326-503c-4623-9152-3f4c38f2d060/collection/29646859-07c1f103-1e5f-44fe-a5e3-00126c6ece77?action=share&source=collection_link&creator=29646859" + }, + "item": [ + { + "name": "01.token", + "item": [ + { + "name": "01_getAuthToken", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();\r", + "pm.collectionVariables.set(\"token\", jsonData.accessToken);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "POST", + "header": [], + "url": { + "raw": "{{baseUrlAuth}}/auth/token?client_id=piattaforma-unitaria&grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=e1d9c534-86a9-4039-80da-8aa7a33ac9e7&subject_issuer=soak-test&subject_token_type=FAKE-AUTH&scope=openid&client_secret", + "host": [ + "{{baseUrlAuth}}" + ], + "path": [ + "auth", + "token" + ], + "query": [ + { + "key": "client_id", + "value": "piattaforma-unitaria" + }, + { + "key": "grant_type", + "value": "urn:ietf:params:oauth:grant-type:token-exchange" + }, + { + "key": "subject_token", + "value": "e1d9c534-86a9-4039-80da-8aa7a33ac9e7" + }, + { + "key": "subject_issuer", + "value": "soak-test" + }, + { + "key": "subject_token_type", + "value": "FAKE-AUTH" + }, + { + "key": "scope", + "value": "openid" + }, + { + "key": "client_secret", + "value": null + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "02.citizen", + "item": [ + { + "name": "02_getCitizenData", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"PDND - 02_getCitizenData - Responses with 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test(\"MyPay - 02_getCitizenData - check response and reading citizen data\", function () {\r", + " let jsonResponse = pm.response.json();\r", + "\r", + " pm.expect(jsonResponse).to.have.property(\"firstName\", \"Julieta\");\r", + " pm.expect(jsonResponse).to.have.property(\"lastName\", \"Lindgren\");\r", + " pm.expect(jsonResponse).to.have.property(\"dateOfBirth\", \"1975-02-09\");\r", + " \r", + " pm.expect(jsonResponse).to.have.property(\"address\");\r", + " pm.expect(jsonResponse.address).to.have.property(\"street\", \"106 Hansen Mountains\");\r", + " pm.expect(jsonResponse.address).to.have.property(\"city\", \"West Aurelio\");\r", + " pm.expect(jsonResponse.address).to.have.property(\"postalCode\", \"36495-0217\");\r", + " pm.expect(jsonResponse.address).to.have.property(\"country\", \"Heard Island and McDonald Islands\");\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrlPdnd}}/anpr-service-e002/citizen?fiscalCode={{fiscalCode}}", + "host": [ + "{{baseUrlPdnd}}" + ], + "path": [ + "anpr-service-e002", + "citizen" + ], + "query": [ + { + "key": "fiscalCode", + "value": "{{fiscalCode}}" + } + ] + }, + "description": "Returns detailed information about a citizen based on their fiscal code." + }, + "response": [ + { + "name": "OK", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + }, + { + "key": "Authorization", + "value": "Bearer ", + "description": "Added as a part of security scheme: bearer" + } + ], + "url": { + "raw": "{{baseUrl}}/anpr-service-e002/citizen?fiscalCode=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "anpr-service-e002", + "citizen" + ], + "query": [ + { + "key": "fiscalCode", + "value": "", + "description": "(Required) The fiscal code of the citizen" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"firstName\": \"\",\n \"lastName\": \"\",\n \"dateOfBirth\": \"\",\n \"address\": {\n \"street\": \"\",\n \"city\": \"\",\n \"postalCode\": \"\",\n \"country\": \"\"\n }\n}" + }, + { + "name": "Invalid request", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer ", + "description": "Added as a part of security scheme: bearer" + } + ], + "url": { + "raw": "{{baseUrl}}/anpr-service-e002/citizen?fiscalCode=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "anpr-service-e002", + "citizen" + ], + "query": [ + { + "key": "fiscalCode", + "value": "", + "description": "(Required) The fiscal code of the citizen" + } + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + }, + { + "name": "Forbidden", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer ", + "description": "Added as a part of security scheme: bearer" + } + ], + "url": { + "raw": "{{baseUrl}}/anpr-service-e002/citizen?fiscalCode=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "anpr-service-e002", + "citizen" + ], + "query": [ + { + "key": "fiscalCode", + "value": "", + "description": "(Required) The fiscal code of the citizen" + } + ] + } + }, + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + }, + { + "name": "Citizen not found", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer ", + "description": "Added as a part of security scheme: bearer" + } + ], + "url": { + "raw": "{{baseUrl}}/anpr-service-e002/citizen?fiscalCode=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "anpr-service-e002", + "citizen" + ], + "query": [ + { + "key": "fiscalCode", + "value": "", + "description": "(Required) The fiscal code of the citizen" + } + ] + } + }, + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + }, + { + "name": "Internal server error", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer ", + "description": "Added as a part of security scheme: bearer" + } + ], + "url": { + "raw": "{{baseUrl}}/anpr-service-e002/citizen?fiscalCode=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "anpr-service-e002", + "citizen" + ], + "query": [ + { + "key": "fiscalCode", + "value": "", + "description": "(Required) The fiscal code of the citizen" + } + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + } + ] + } + ] + } + ], + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "Bearer {{token}}", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "baseUrlPdnd", + "value": "https://hub.internal.dev.p4pa.pagopa.it/p4papdnd" + }, + { + "key": "fiscalCode", + "value": "DNTCRL65S67M126K", + "type": "string" + }, + { + "key": "token", + "value": "", + "type": "string" + }, + { + "key": "baseUrlAuth", + "value": "https://api.dev.p4pa.pagopa.it/payhub-auth", + "type": "string" + } + ] +} \ No newline at end of file From 1d2f902fd760eb023772a463b32a92d73888de8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Cal=C3=B2?= Date: Wed, 11 Dec 2024 15:47:21 +0100 Subject: [PATCH 5/7] fix: remove server port from application.yml (#13) --- src/main/resources/application.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 147a48f..eff2380 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -41,6 +41,4 @@ app: connect.timeout.millis: "\${CONNECT_TIMEOUT_MILLIS:120000}" read.timeout.millis: "\${READ_TIMEOUT_MILLIS:120000}" auth: - base-url: "\${AUTH_SERVER_BASE_URL:https://auth-server/api}" -server: - port: 8081 \ No newline at end of file + base-url: "\${AUTH_SERVER_BASE_URL:https://auth-server/api}" \ No newline at end of file From fae60c0a10b77df5ddd9f1a1d081540f1b653108 Mon Sep 17 00:00:00 2001 From: RiccardoGiuliani <144138935+RiccardoGiuliani@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:17:25 +0100 Subject: [PATCH 6/7] fix: P4ADEV-1756 modified openapi (#15) --- openapi/p4pa-pdnd.openapi.yaml | 1 + .../anpr/controller/PdndServiceController.java | 2 +- .../anpr/c003/client/AnprC003ClientImplTest.java | 2 +- .../anpr/c003/service/AnprC003ServiceTest.java | 2 +- .../anpr/c030/client/AnprC030ClientImplTest.java | 2 +- .../anpr/c030/service/AnprC030ServiceTest.java | 2 +- .../anpr/controller/PdndServiceControllerTest.java | 2 +- .../pdnd/anpr/service/PdndServiceImplTest.java | 14 +++++++------- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/openapi/p4pa-pdnd.openapi.yaml b/openapi/p4pa-pdnd.openapi.yaml index dd5cff0..6820fe3 100644 --- a/openapi/p4pa-pdnd.openapi.yaml +++ b/openapi/p4pa-pdnd.openapi.yaml @@ -10,6 +10,7 @@ paths: get: summary: Retrieve citizen data description: Returns detailed information about a citizen based on their fiscal code. + operationId: getCitizenDataByFiscalCode parameters: - name: fiscalCode in: query diff --git a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java index 7e90f2a..39f6c2e 100644 --- a/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceController.java @@ -16,7 +16,7 @@ public PdndServiceController(PdndService pdndService) { } @Override - public ResponseEntity anprServiceE002CitizenGet(String fiscalCode) { + public ResponseEntity getCitizenDataByFiscalCode(String fiscalCode) { Citizen response = pdndService.getCitizenData(fiscalCode); return ResponseEntity.ok(response); } diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java index 77b8a4b..292ea97 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/client/AnprC003ClientImplTest.java @@ -43,7 +43,7 @@ void setUp() { } @Test - void getUserData() { + void givenValidRequestWhenGetUserDataThenReturnValidResponse() { RichiestaE002 request = RichiestaE002.builder() .idOperazioneClient("13f32508-7bcb-38d0-8510-d68bf240aa59-1733496758205") .build(); diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java index 005c5de..9df1db3 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c003/service/AnprC003ServiceTest.java @@ -24,7 +24,7 @@ class AnprC003ServiceTest { private AnprC003Service anprC003Service; @Test - void getUserData() { + void givenValidIdAnprAndFiscalCodeWhenGetUserDataThenReturnUserDataSuccessfully() { String fiscalCode = "DNTCRL65S67M126K"; String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java index 7e5a85f..d4931e4 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImplTest.java @@ -42,7 +42,7 @@ void setUp() { } @Test - void testGetIdAnprFromFc() { + void givenValidRequestWhenGetIdAnprFromFcThenReturnValidResponse() { RichiestaE002 request = RichiestaE002.builder() .idOperazioneClient("13f32508-7bcb-38d0-8510-d68bf240aa59-1733496758205") .build(); diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java index 2781f16..4a68ccc 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/c030/service/AnprC030ServiceTest.java @@ -24,7 +24,7 @@ class AnprC030ServiceTest { private AnprC030Service anprC030Service; @Test - void testGetIdAnprFromFc() { + void givenValidFiscalCodeWhenGetIdAnprFromFcThenReturnValidResponse() { String fiscalCode = "DNTCRL65S67M126K"; TipoIdentificativi idTypes = TipoIdentificativi.builder() diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java index 0b25f2c..cd08dc5 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java @@ -27,7 +27,7 @@ class PdndServiceControllerTest { private PdndService pdndService; @Test - void testAnprServiceE002CitizenGet_Success() throws Exception { + void givenValidFiscalCodeWhenGetCitizenDataThenReturnCitizenDetails() throws Exception { String fiscalCode = "DNTCRL65S67M126K"; Citizen citizen = Citizen.builder() .firstName("Julieta") diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java index 503a81e..c9864d9 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/service/PdndServiceImplTest.java @@ -34,7 +34,7 @@ class PdndServiceImplTest { private PdndServiceImpl pdndService; @Test - void testGetCitizenData_Success() { + void givenValidFiscalCodeAndIdAnprWhenGetCitizenDataThenReturnCitizenDetails() { String fiscalCode = "DNTCRL65S67M126K"; String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; @@ -73,7 +73,7 @@ void testGetCitizenData_Success() { } @Test - void testGetCitizenData_InvalidListaSoggetti() { + void givenValidFiscalCodeAndInvalidSubjectListWhenGetCitizenDataThenThrowIllegalArgumentException() { String fiscalCode = "DNTCRL65S67M126K"; String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; @@ -98,7 +98,7 @@ void testGetCitizenData_InvalidListaSoggetti() { } @Test - void testGetCitizenData_InvalidC003Response() { + void givenValidFiscalCodeAndInvalidC003ResponseWhenGetCitizenDataThenThrowIllegalArgumentException() { String fiscalCode = "DNTCRL65S67M126K"; String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; @@ -120,7 +120,7 @@ void testGetCitizenData_InvalidC003Response() { } @Test - void testGetCitizenData_InvalidSubDataType() { + void givenValidFiscalCodeAndInvalidSubDataTypeWhenGetCitizenDataThenThrowIllegalArgumentException() { String fiscalCode = "DNTCRL65S67M126K"; String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; @@ -146,7 +146,7 @@ void testGetCitizenData_InvalidSubDataType() { } @Test - void testGetCitizenData_EmptySubDataType() { + void givenValidFiscalCodeAndEmptySubDataTypeWhenGetCitizenDataThenThrowIllegalArgumentException() { String fiscalCode = "DNTCRL65S67M126K"; String idAnpr = "d20fcd8e-f228-323c-8924-6405b44879bf"; @@ -172,11 +172,11 @@ void testGetCitizenData_EmptySubDataType() { } @Test - void testGetCitizenData_InvalidResponse_ThrowsException() { + void givenServiceUnavailableWhenGetCitizenDataThenThrowRuntimeException() { String fiscalCode = "DNTCRL65S67M126K"; Mockito.when(anprC030Service.getIdAnprFromFc(fiscalCode)).thenThrow(new RuntimeException("Service unavailable")); assertThrows(RuntimeException.class, () -> pdndService.getCitizenData(fiscalCode)); } -} +} \ No newline at end of file From 700c5e2f0125e037e7dbb98e64109f8d7c2f13bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Cal=C3=B2?= Date: Thu, 12 Dec 2024 16:43:15 +0100 Subject: [PATCH 7/7] fix: edit dockerfile and baseurl (#14) --- Dockerfile | 4 ++++ openapi/p4pa-pdnd.openapi.yaml | 2 +- .../pdnd/anpr/controller/PdndServiceControllerTest.java | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6822b33..3f2c5f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -106,6 +106,10 @@ RUN gradle openApiGeneratePayhub dependencies --no-daemon RUN gradle openApiGeneratePdndClient dependencies --no-daemon +RUN gradle openApiGenerateAnprApiC030 dependencies --no-daemon + +RUN gradle openApiGenerateAnprApiC003 dependencies --no-daemon + # # 🏗️ Build Stage # diff --git a/openapi/p4pa-pdnd.openapi.yaml b/openapi/p4pa-pdnd.openapi.yaml index 6820fe3..8cb96da 100644 --- a/openapi/p4pa-pdnd.openapi.yaml +++ b/openapi/p4pa-pdnd.openapi.yaml @@ -4,7 +4,7 @@ info: description: API and Models. version: 0.0.1 servers: - - url: "http://localhost:8080/p4papdnd" + - url: "http://localhost:8080" paths: /anpr-service-e002/citizen: get: diff --git a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java index cd08dc5..d7a0c7a 100644 --- a/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java +++ b/src/test/java/it/gov/pagopa/payhub/pdnd/anpr/controller/PdndServiceControllerTest.java @@ -43,7 +43,7 @@ void givenValidFiscalCodeWhenGetCitizenDataThenReturnCitizenDetails() throws Exc Mockito.when(pdndService.getCitizenData(fiscalCode)).thenReturn(citizen); - mockMvc.perform(get("/p4papdnd/anpr-service-e002/citizen") + mockMvc.perform(get("/anpr-service-e002/citizen") .param("fiscalCode", fiscalCode)) .andExpect(status().isOk()) .andExpect(jsonPath("$.firstName").value("Julieta"))