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/build.gradle.kts b/build.gradle.kts index 5560314..475cce0 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,9 +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") - - compileOnly("org.projectlombok:lombok") - annotationProcessor("org.projectlombok:lombok") + implementation("io.micrometer:micrometer-tracing-bridge-otel:$micrometerVersion") // validation token jwt implementation("com.auth0:java-jwt:$javaJwtVersion") @@ -57,6 +56,9 @@ dependencies { 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") @@ -98,7 +100,7 @@ configurations { } tasks.compileJava { - dependsOn("openApiGeneratePayhub","openApiGeneratePdndClient") + dependsOn("openApiGeneratePayhub","openApiGeneratePdndClient","openApiGenerateAnprApiC030", "openApiGenerateAnprApiC003") } configure { @@ -154,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/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/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..8dd9e6e 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: http://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..8cb96da 100644 --- a/openapi/p4pa-pdnd.openapi.yaml +++ b/openapi/p4pa-pdnd.openapi.yaml @@ -1,31 +1,74 @@ -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" 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. + operationId: getCitizenDataByFiscalCode + 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: - type: string - example: "Hello, World!" + $ref: '#/components/schemas/Citizen' + '400': + description: Invalid request + '403': + description: Forbidden + '404': + description: Citizen not found '500': - description: "Errore interno del server" - content: - application/json: - schema: - type: object - properties: - error: - type: string - example: "Errore interno del server" \ No newline at end of file + 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 + 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/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/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..c5eab6d --- /dev/null +++ b/src/main/java/it/gov/pagopa/payhub/pdnd/anpr/c030/client/AnprC030ClientImpl.java @@ -0,0 +1,29 @@ +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 it.gov.pagopa.payhub.pdnd.anpr.client.AbstractAnprClient; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.stereotype.Component; + +@Component +public class AnprC030ClientImpl extends AbstractAnprClient implements AnprC030Client { + + private final AnprC030ServiceConfig anprC030ServiceConfig; + + public AnprC030ClientImpl(RestTemplateBuilder restTemplateBuilder, AnprC030ServiceConfig anprC030ServiceConfig) { + super(restTemplateBuilder); + this.anprC030ServiceConfig = anprC030ServiceConfig; + } + + @Override + protected String getEndpointPath() { + return anprC030ServiceConfig.getUrl(); + } + + @Override + public RispostaE002OK getIdAnprFromFc(RichiestaE002 request) { + return sendRequest(request, RispostaE002OK.class); + } +} 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/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/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..39f6c2e --- /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 getCitizenDataByFiscalCode(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/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..eff2380 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://p4pa-mocks-microservice-chart:8080}" services: c003: client-id: "\${PDND_SERVICE_ANPR_C003_CLIENTID:\${PDND_SERVICE_ANPR_CLIENTID:\${PDND_SERVICE_CLIENTID:clientid}}}" @@ -28,12 +29,14 @@ 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}" 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"/> 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..292ea97 --- /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 givenValidRequestWhenGetUserDataThenReturnValidResponse() { + 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..9df1db3 --- /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 givenValidIdAnprAndFiscalCodeWhenGetUserDataThenReturnUserDataSuccessfully() { + 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 new file mode 100644 index 0000000..d4931e4 --- /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 givenValidRequestWhenGetIdAnprFromFcThenReturnValidResponse() { + RichiestaE002 request = RichiestaE002.builder() + .idOperazioneClient("13f32508-7bcb-38d0-8510-d68bf240aa59-1733496758205") + .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..4a68ccc --- /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 givenValidFiscalCodeWhenGetIdAnprFromFcThenReturnValidResponse() { + 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 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..d7a0c7a --- /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 givenValidFiscalCodeWhenGetCitizenDataThenReturnCitizenDetails() 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("/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..c9864d9 --- /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 givenValidFiscalCodeAndIdAnprWhenGetCitizenDataThenReturnCitizenDetails() { + 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 givenValidFiscalCodeAndInvalidSubjectListWhenGetCitizenDataThenThrowIllegalArgumentException() { + 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 givenValidFiscalCodeAndInvalidC003ResponseWhenGetCitizenDataThenThrowIllegalArgumentException() { + 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 givenValidFiscalCodeAndInvalidSubDataTypeWhenGetCitizenDataThenThrowIllegalArgumentException() { + 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 givenValidFiscalCodeAndEmptySubDataTypeWhenGetCitizenDataThenThrowIllegalArgumentException() { + 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 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 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