From be43cf0baaef6ca6af4a72aca2f22646383a5cd2 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Mon, 16 Sep 2024 15:32:47 +0200 Subject: [PATCH 01/19] wip --- app/build.gradle.kts | 1 + app/src/main/resources/config/application.yml | 6 + gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle.kts | 1 + zgw/openklant/build.gradle.kts | 40 ++ zgw/openklant/gradle.properties | 17 + zgw/openklant/gradle/publishing.gradle.kts | 35 ++ zgw/openklant/licenseHeaderFile.template | 15 + .../OpenKlantAutoConfiguration.kt | 49 ++ .../OpenKlantModuleConfiguration.kt | 37 ++ .../openklant/client/OpenKlant2Client.kt | 105 +++++ .../nl/nlportal/openklant/domain/Actoren.kt | 71 +++ .../nl/nlportal/openklant/domain/Partijen.kt | 118 +++++ .../nlportal/openklant/domain/ResultPage.kt | 35 ++ .../nl/nlportal/openklant/domain/Shared.kt | 430 ++++++++++++++++++ .../nlportal/openklant/graphql/PartijQuery.kt | 30 ++ .../openklant/service/OpenKlant2Service.kt | 32 ++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../nl/nlportal/openklant/TestApplication.kt | 44 ++ .../nl/nlportal/openklant/TestHelper.kt | 29 ++ .../src/test/resources/config/application.yml | 16 + .../org.mockito.plugins.MockMaker | 1 + 22 files changed, 1115 insertions(+), 2 deletions(-) create mode 100644 zgw/openklant/build.gradle.kts create mode 100644 zgw/openklant/gradle.properties create mode 100644 zgw/openklant/gradle/publishing.gradle.kts create mode 100644 zgw/openklant/licenseHeaderFile.template create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt create mode 100644 zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt create mode 100644 zgw/openklant/src/test/resources/config/application.yml create mode 100644 zgw/openklant/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 68dd71c6..d7e72ae2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -25,6 +25,7 @@ dependencies { implementation(project(":product")) implementation(project(":form")) implementation(project(":zgw:taak")) + implementation(project(":zgw:openklant")) implementation(project(":zgw:zaken-api")) implementation(project(":zgw:catalogi-api")) implementation(project(":zgw:documenten-api")) diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index 1feeee9e..f4deb2da 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -72,6 +72,12 @@ logging: org.springframework.amqp: DEBUG nl-portal: + config: + openklant: + enabled: true + properties: + url: http://localhost:8007 + token: ac045222c9e7cde8120b48735560f9b920bb58cd zgw: catalogiapi: url: http://localhost:8001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b415..e4a5f610 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index ebbd247f..d7185bfa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -56,4 +56,5 @@ include( "zgw:taak", "zgw:zaken-api", "zgw:objectenapi", + "zgw:openklant", ) \ No newline at end of file diff --git a/zgw/openklant/build.gradle.kts b/zgw/openklant/build.gradle.kts new file mode 100644 index 00000000..d88732d5 --- /dev/null +++ b/zgw/openklant/build.gradle.kts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + kotlin("jvm") +} + +val isLib = true + +dependencies { + api(project(":graphql")) + api(project(":portal-authentication")) + api(project(":zgw:common-ground-authentication")) + + testImplementation(project(":zgw:common-ground-authentication-test")) + testImplementation("org.springframework.boot", "spring-boot-starter-test") + testImplementation("org.springframework.security", "spring-security-test") + testImplementation(TestDependencies.kotlinCoroutines) + testImplementation(TestDependencies.okHttpMockWebserver) + testImplementation(TestDependencies.okHttp) +} + +val jar: Jar by tasks +val bootJar: org.springframework.boot.gradle.tasks.bundling.BootJar by tasks +bootJar.enabled = false +jar.enabled = true + +apply(from = "gradle/publishing.gradle.kts") \ No newline at end of file diff --git a/zgw/openklant/gradle.properties b/zgw/openklant/gradle.properties new file mode 100644 index 00000000..766b10fc --- /dev/null +++ b/zgw/openklant/gradle.properties @@ -0,0 +1,17 @@ +# +# Copyright (c) 2024 Ritense BV, the Netherlands. +# +# Licensed under EUPL, Version 1.2 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +isLib = true \ No newline at end of file diff --git a/zgw/openklant/gradle/publishing.gradle.kts b/zgw/openklant/gradle/publishing.gradle.kts new file mode 100644 index 00000000..faab44f7 --- /dev/null +++ b/zgw/openklant/gradle/publishing.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +pluginManager.withPlugin("maven-publish") { + configure { + publications { + withType(MavenPublication::class.java) { + pom { + getName().set("OpenKlant module") + getDescription().set("This module enables NL Portal to interact with OpenKlant.") + developers { + developer { + getId().set("team-nl-portal") + getName().set("Team NL Portal") + getEmail().set("team-nl-portal@ritense.com") + } + } + } + } + } + } +} \ No newline at end of file diff --git a/zgw/openklant/licenseHeaderFile.template b/zgw/openklant/licenseHeaderFile.template new file mode 100644 index 00000000..156abaa9 --- /dev/null +++ b/zgw/openklant/licenseHeaderFile.template @@ -0,0 +1,15 @@ +/* + * Copyright $YEAR Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt new file mode 100644 index 00000000..901cb49c --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.autoconfigure + +import mu.KotlinLogging +import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.service.OpenKlant2Service +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +@EnableConfigurationProperties( + OpenKlantModuleConfiguration::class, +) +class OpenKlantAutoConfiguration { + @Bean + fun openKlant2Client(openklantModuleConfiguration: OpenKlantModuleConfiguration): OpenKlant2Client { + if (!openklantModuleConfiguration.enabled) { + logger.debug { "OpenKlant 2 is not configured." } + } + return OpenKlant2Client(openKlantConfigurationProperties = openklantModuleConfiguration.properties) + } + + @Bean + fun openKlant2Service( + openklantModuleConfiguration: OpenKlantModuleConfiguration, + openklant2Client: OpenKlant2Client + ): OpenKlant2Service { + return OpenKlant2Service(openklantModuleConfiguration.enabled, openklant2Client) + } + + companion object { + private val logger = KotlinLogging.logger {} + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt new file mode 100644 index 00000000..f73f1ae5 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.autoconfigure + +import org.springframework.boot.context.properties.ConfigurationProperties +import java.net.URI + +@ConfigurationProperties(prefix = "nl-portal.config.openklant") +data class OpenKlantModuleConfiguration( + var enabled: Boolean = false, + var properties: OpenKlantConfigurationProperties, +) { + init { + if (enabled) { + requireNotNull(properties.url) + requireNotNull(properties.token) + } + } + + data class OpenKlantConfigurationProperties( + var url: URI? = null, + var token: String? = null, + ) +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt new file mode 100644 index 00000000..b31c2878 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client + +import io.netty.handler.logging.LogLevel.TRACE +import nl.nlportal.commonground.authentication.BedrijfAuthentication +import nl.nlportal.commonground.authentication.BurgerAuthentication +import nl.nlportal.commonground.authentication.CommonGroundAuthentication +import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties +import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.domain.ResultPage +import org.springframework.http.MediaType +import org.springframework.http.client.reactive.ReactorClientHttpConnector +import org.springframework.http.codec.json.Jackson2JsonDecoder +import org.springframework.http.codec.json.Jackson2JsonEncoder +import org.springframework.web.reactive.function.client.ExchangeStrategies +import org.springframework.web.reactive.function.client.WebClient +import org.springframework.web.reactive.function.client.awaitBody +import reactor.netty.http.client.HttpClient +import reactor.netty.transport.logging.AdvancedByteBufFormat.TEXTUAL + +class OpenKlant2Client(private val openKlantConfigurationProperties: OpenKlantConfigurationProperties) { + suspend fun getPartij(authentication: CommonGroundAuthentication): Partij? { + val soortPartij = when (authentication) { + is BurgerAuthentication -> "persoon" + is BedrijfAuthentication -> "organisatie" + else -> "contactpersoon" + } + val searchVariables = mapOf( + "soortPartij" to soortPartij, + "partijIdentificator__objectId" to authentication.userId + ) + + val response: ResultPage = webClient() + .get() + .uri { uriBuilder -> + uriBuilder + .path("/partijen") + .build(searchVariables) + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results.singleOrNull() + } + + fun webClient(): WebClient { + return webclientBuilder + .baseUrl(openKlantConfigurationProperties.url.toString()) + .defaultHeader("Accept-Crs", "EPSG:4326") + .defaultHeader("Content-Crs", "EPSG:4326") + .defaultHeader("Authorization", "Token ${openKlantConfigurationProperties.token}") + .build() + } + + fun webClientWithoutBaseUrl(): WebClient { + return webclientBuilder + .defaultHeader("Accept-Crs", "EPSG:4326") + .defaultHeader("Content-Crs", "EPSG:4326") + .defaultHeader("Authorization", "Token ${openKlantConfigurationProperties.token}") + .build() + } + + private val webclientBuilder = + WebClient.builder() + .clientConnector( + ReactorClientHttpConnector( + HttpClient.create().wiretap( + "reactor.netty.http.client.HttpClient", + TRACE, + TEXTUAL, + ), + ), + ) + .exchangeStrategies( + ExchangeStrategies.builder() + .codecs { configurer -> + with(configurer.defaultCodecs()) { + maxInMemorySize(16 * 1024 * 1024) + jackson2JsonEncoder( + Jackson2JsonEncoder(Mapper.get()), + ) + jackson2JsonDecoder( + Jackson2JsonDecoder(Mapper.get()), + ) + } + } + .build(), + ) +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt new file mode 100644 index 00000000..8e5fcf14 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonValue +import java.util.UUID + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class Actor( + val uuid: UUID, + val url: String, + val naam: String, + val soortActor: SoortActor, + val indicatieActief: Boolean? = null, + val actoridentificator: Identificator? = null, +) + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class CreateActor( + val name: String, + val indicatieActief: Boolean, + val soortActor: SoortActor, +) { + init { + require(name.length in 1..200) { "Actor name has to be between 1 and 200 characters long" } + } +} + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class PatchActor( + val uuid: UUID, + val name: String? = null, + val soortActor: SoortActor, + val indicatieActief: Boolean? = null, + val actoridentificator: Identificator? = null, +) { + init { + require(name == null || name.length in 1..200) { "Actor name has to be between 1 and 200 characters long" } + } +} + +enum class SoortActor( + @JsonValue private val value: String, +) { + MEDEWERKER("medewerker"), + GEAUTOMATISEERDE_ACTOR("geautomatiseerdeActor"), + ORGANISATORISCHE_EENHEID("organisatorischeEenheid"), + ; + + override fun toString(): String { + return this.value + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt new file mode 100644 index 00000000..67ad8ee5 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonValue +import java.util.Locale +import java.util.UUID + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class Partij( + val betrokkenen: List = emptyList(), + val bezoekadres: Adres? = null, + val categorieRelaties: List, + val correspondentieadres: Adres? = null, + val digitaleAdressen: List? = null, + val indicatieActief: Boolean, + val indicatieGeheimhouding: Boolean? = null, + val interneNotitie: String? = null, + val nummer: String? = null, + val partijIdentificatoren: List, + val rekeningnummers: List? = null, + val soortPartij: SoortPartij, + val url: String, + val uuid: UUID, + val vertegenwoordigden: List, + val voorkeursDigitaalAdres: ForeignKey? = null, + val voorkeursRekeningnummer: Rekeningnummer? = null, + val voorkeurstaal: String?, +) { + init { + require(voorkeurstaal == null || voorkeurstaal in Locale.getAvailableLocales().map { it.isO3Language }) { + "Voorkeurstaal must be a valid Language in the ISO 639-2/B format" + } + require(interneNotitie == null || interneNotitie.length <= 1000) { + "Interne notitie can't be longer than 1000 characters." + } + require(nummer == null || nummer.length <= 10) { + "Nummer can't be longer than 10 characters." + } + } +} + +data class PartijenFilterOptions( + val page: Int = 1, + val naam: String? = null, + val indicatieActief: Boolean? = null, + val soortPartij: SoortPartij? = null, +) + +data class Adres( + val adresregel1: String? = null, + val adresregel2: String? = null, + val adresregel3: String? = null, + val land: Landcode? = null, + val nummeraanduidingId: String? = null, +) { + init { + require(nummeraanduidingId == null || nummeraanduidingId.length <= 255) { + "Adresregel1 can't be more than 255 characters long." + } + require(adresregel1 == null || adresregel1.length <= 80) { + "Adresregel1 can't be more than 255 characters long." + } + require(adresregel2 == null || adresregel2.length <= 80) { + "Adresregel1 can't be more than 255 characters long." + } + require(adresregel3 == null || adresregel3.length <= 80) { + "Adresregel1 can't be more than 255 characters long." + } + } +} + +data class CategorieRelatieForeignKey( + val beginDatum: String, + val categorieNaam: String, + val eindDatum: String, + val url: String, + val uuid: String, +) + +data class Rekeningnummer(val uuid: String) + +data class CreatePartij( + val name: String, +) { + init { + require(name.length in 1..200) { "Partij name has to be between 1 and 200 characters long" } + } +} + +enum class SoortPartij( + @JsonValue private val value: String, +) { + PERSOON("persoon"), + ORGANISATIE("organisatie"), + CONTACTPERSOON("contactpersoon"), + ; + + override fun toString(): String { + return this.value + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt new file mode 100644 index 00000000..f71efe90 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2015-2023 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import java.net.URI + +data class ResultPage( + val count: Int, + val next: URI? = null, + val previous: URI? = null, + val results: List, +) { + fun getNextPageNumber(): Int? { + return next + ?.query + ?.split("&") + ?.asSequence() + ?.map { Pair(it.substringBefore("="), it.substringAfter("=")) } + ?.firstOrNull { it.first == "page" } + ?.second?.toIntOrNull() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt new file mode 100644 index 00000000..ee2cd5ae --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import com.fasterxml.jackson.annotation.JsonValue + +data class ForeignKey( + val url: String, + val uuid: String, +) + +data class Identificator( + val objectId: String, + val codeObjecttype: String, + val codeRegister: String, + val codeSoortObjectId: String, +) + +enum class Landcode( + @JsonValue val landcode: String, + val landnaam: String, +) { + CANADA("5001", "Canada"), + FRANKRIJK("5002", "Frankrijk"), + ZWITSERLAND("5003", "Zwitserland"), + RHODESIË("5004", "Rhodesië"), + MALAWI("5005", "Malawi"), + CUBA("5006", "Cuba"), + SURINAME("5007", "Suriname"), + TUNESIË("5008", "Tunesië"), + OOSTENRIJK("5009", "Oostenrijk"), + BELGIË("5010", "België"), + BOTSWANA("5011", "Botswana"), + IRAN("5012", "Iran"), + NIEUWZEELAND("5013", "Nieuw-Zeeland"), + ZUIDAFRIKA("5014", "Zuid-Afrika"), + DENEMARKEN("5015", "Denemarken"), + NOORDJEMEN("5016", "Noord-Jemen"), + HONGARIJE("5017", "Hongarije"), + SAOEDIARABIË("5018", "Saoedi-Arabië"), + LIBERIA("5019", "Liberia"), + ETHIOPIË("5020", "Ethiopië"), + CHILI("5021", "Chili"), + MAROKKO("5022", "Marokko"), + TOGO("5023", "Togo"), + GHANA("5024", "Ghana"), + LAOS("5025", "Laos"), + ANGOLA("5026", "Angola"), + FILIPIJNEN("5027", "Filipijnen"), + ZAMBIA("5028", "Zambia"), + MALI("5029", "Mali"), + IVOORKUST("5030", "Ivoorkust"), + BURMA("5031", "Burma"), + MONACO("5032", "Monaco"), + COLOMBIA("5033", "Colombia"), + ALBANIË("5034", "Albanië"), + KAMEROEN("5035", "Kameroen"), + ZUIDVIETNAM("5036", "Zuid-Vietnam"), + SINGAPORE("5037", "Singapore"), + PARAGUAY("5038", "Paraguay"), + ZWEDEN("5039", "Zweden"), + CYPRUS("5040", "Cyprus"), + AUSTRALISCH_NIEUWGUINEA("5041", "Australisch Nieuw-Guinea"), + BRUNEI("5042", "Brunei"), + IRAK("5043", "Irak"), + MAURITIUS("5044", "Mauritius"), + VATICAANSTAD("5045", "Vaticaanstad"), + KASHMIR("5046", "Kashmir"), + MYANMAR("5047", "Myanmar"), + JEMEN("5048", "Jemen"), + SLOVENIË("5049", "Slovenië"), + ZAÏRE("5050", "Zaïre"), + KROATIË("5051", "Kroatië"), + TAIWAN("5052", "Taiwan"), + RUSLAND("5053", "Rusland"), + ARMENIË("5054", "Armenië"), + ASCENSION("5055", "Ascension"), + AZOREN("5056", "Azoren"), + BAHREIN("5057", "Bahrein"), + BHUTAN("5058", "Bhutan"), + BRITSE_ANTILLEN("5059", "Britse Antillen"), + COMOREN("5060", "Comoren"), + FALKLANDEILANDEN("5061", "Falklandeilanden"), + FRANSGUYANA("5062", "Frans-Guyana"), + FRANSSOMALILAND("5063", "Frans-Somaliland"), + GILBERT_EN_ELLICEEILANDEN("5064", "Gilbert- en Ellice-eilanden"), + GROENLAND("5065", "Groenland"), + GUADELOUPE("5066", "Guadeloupe"), + KAAPVERDISCHE_EILANDEN("5067", "Kaapverdische Eilanden"), + MACAU("5068", "Macau"), + MARTINIQUE("5069", "Martinique"), + MOZAMBIQUE("5070", "Mozambique"), + PITCAIRNEILANDEN("5071", "Pitcairneilanden"), + GUINEEBISSAU("5072", "Guinee-Bissau"), + RÉUNION("5073", "Réunion"), + SAINT_PIERRE_EN_MIQUELON("5074", "Saint Pierre en Miquelon"), + SEYCHELLEN_EN_AMIRANTEN("5075", "Seychellen en Amiranten"), + TONGA("5076", "Tonga"), + WALLIS_EN_FUTUNA("5077", "Wallis en Futuna"), + ZUIDWESTAFRIKA("5078", "Zuidwest-Afrika"), + FRANSINDIË("5079", "Frans-Indië"), + JOHNSTON("5080", "Johnston"), + KEDAH("5081", "Kedah"), + KELANTAN("5082", "Kelantan"), + MALAKKA("5083", "Malakka"), + MAYOTTE("5084", "Mayotte"), + NEGRI_SEMBILAN("5085", "Negri Sembilan"), + PAHANG("5086", "Pahang"), + PERAK("5087", "Perak"), + PERLIS("5088", "Perlis"), + PORTUGEESINDIË("5089", "Portugees-Indië"), + SELANGOR("5090", "Selangor"), + SIKKIM("5091", "Sikkim"), + SAINT_VINCENT_EN_DE_GRENADINES("5092", "Saint Vincent en de Grenadines"), + SPITSBERGEN("5093", "Spitsbergen"), + TRENGGANU("5094", "Trengganu"), + ARUBA("5095", "Aruba"), + BURKINA_FASO("5096", "Burkina Faso"), + AZERBEIDZJAN("5097", "Azerbeidzjan"), + BELARUS("5098", "Belarus"), + KAZACHSTAN("5099", "Kazachstan"), + MACEDONIË("5100", "Macedonië"), + TIMOR_LESTE("5101", "Timor Leste"), + SERVIË_EN_MONTENEGRO("5102", "Servië en Montenegro"), + SERVIË("5103", "Servië"), + MONTENEGRO("5104", "Montenegro"), + KOSOVO("5105", "Kosovo"), + BONAIRE("5106", "Bonaire"), + CURAÇAO("5107", "Curaçao"), + SABA("5108", "Saba"), + SINT_EUSTATIUS("5109", "Sint Eustatius"), + SINT_MAARTEN("5110", "Sint Maarten"), + ZUIDSOEDAN("5111", "Zuid-Soedan"), + GAZASTROOK_EN_WESTELIJKE_JORDAANOEVER("5112", "Gazastrook en Westelijke Jordaanoever"), + REPUBLIEK_NOORDMACEDONIË("5113", "Republiek Noord-Macedonië"), + MOLDAVIË("6000", "Moldavië"), + BURUNDI("6001", "Burundi"), + FINLAND("6002", "Finland"), + GRIEKENLAND("6003", "Griekenland"), + GUATEMALA("6004", "Guatemala"), + NIGERIA("6005", "Nigeria"), + LIBIË("6006", "Libië"), + IERLAND("6007", "Ierland"), + BRAZILIË("6008", "Brazilië"), + RWANDA("6009", "Rwanda"), + VENEZUELA("6010", "Venezuela"), + IJSLAND("6011", "IJsland"), + LIECHTENSTEIN("6012", "Liechtenstein"), + SOMALIË("6013", "Somalië"), + VERENIGDE_STATEN_VAN_AMERIKA("6014", "Verenigde Staten van Amerika"), + BOLIVIA("6015", "Bolivia"), + AUSTRALIË("6016", "Australië"), + JAMAICA("6017", "Jamaica"), + LUXEMBURG("6018", "Luxemburg"), + TSJAAD("6019", "Tsjaad"), + MAURITANIË("6020", "Mauritanië"), + KIRGIZIË("6021", "Kirgizië"), + CHINA("6022", "China"), + AFGHANISTAN("6023", "Afghanistan"), + INDONESIË("6024", "Indonesië"), + GUYANA("6025", "Guyana"), + NOORDVIETNAM("6026", "Noord-Vietnam"), + NOORWEGEN("6027", "Noorwegen"), + SAN_MARINO("6028", "San Marino"), + DUITSLAND("6029", "Duitsland"), + NEDERLAND("6030", "Nederland"), + CAMBODJA("6031", "Cambodja"), + FIJI("6032", "Fiji"), + BAHAMAS("6033", "Bahama's"), + ISRAËL("6034", "Israël"), + NEPAL("6035", "Nepal"), + ZUIDKOREA("6036", "Zuid-Korea"), + SPANJE("6037", "Spanje"), + OEKRAÏNE("6038", "Oekraïne"), + VERENIGD_KONINKRIJK("6039", "Verenigd Koninkrijk"), + NIGER("6040", "Niger"), + HAÏTI("6041", "Haïti"), + JORDANIË("6042", "Jordanië"), + TURKIJE("6043", "Turkije"), + TRINIDAD_EN_TOBAGO("6044", "Trinidad en Tobago"), + JOEGOSLAVIË("6045", "Joegoslavië"), + OPPERVOLTA("6046", "Opper-Volta"), + ALGERIJE("6047", "Algerije"), + GABON("6048", "Gabon"), + NOORDKOREA("6049", "Noord-Korea"), + OEZBEKISTAN("6050", "Oezbekistan"), + SIERRA_LEONE("6051", "Sierra Leone"), + BRITSHONDURAS("6052", "Brits-Honduras"), + CANARISCHE_EILANDEN("6053", "Canarische Eilanden"), + FRANSPOLYNESIË("6054", "Frans-Polynesië"), + GIBRALTAR("6055", "Gibraltar"), + PORTUGEESTIMOR("6056", "Portugees-Timor"), + TADZJIKISTAN("6057", "Tadzjikistan"), + BRITSE_SALOMONSEILANDEN("6058", "Britse Salomonseilanden"), + SÃO_TOMÉ_EN_PRINCIPE("6059", "São Tomé en Principe"), + SINTHELENA("6060", "Sint-Helena"), + TRISTAN_DA_CUNHA("6061", "Tristan Da Cunha"), + WESTSAMOA("6062", "West-Samoa"), + TURKMENISTAN("6063", "Turkmenistan"), + GEORGIË("6064", "Georgië"), + BOSNIËHERZEGOVINA("6065", "Bosnië-Herzegovina"), + TSJECHIË("6066", "Tsjechië"), + SLOWAKIJE("6067", "Slowakije"), + FEDERALE_REPUBLIEK_JOEGOSLAVIË("6068", "Federale Republiek Joegoslavië"), + DEMOCRATISCHE_REPUBLIEK_CONGO("6069", "Democratische Republiek Congo"), + UGANDA("7001", "Uganda"), + KENYA("7002", "Kenya"), + MALTA("7003", "Malta"), + BARBADOS("7004", "Barbados"), + ANDORRA("7005", "Andorra"), + MEXICO("7006", "Mexico"), + COSTA_RICA("7007", "Costa Rica"), + GAMBIA("7008", "Gambia"), + SYRIË("7009", "Syrië"), + NEDERLANDSE_ANTILLEN("7011", "Nederlandse Antillen"), + ZUIDJEMEN("7012", "Zuid-Jemen"), + EGYPTE("7014", "Egypte"), + ARGENTINIË("7015", "Argentinië"), + LESOTHO("7016", "Lesotho"), + HONDURAS("7017", "Honduras"), + NICARAGUA("7018", "Nicaragua"), + PAKISTAN("7020", "Pakistan"), + SENEGAL("7021", "Senegal"), + DAHOMEY("7023", "Dahomey"), + BULGARIJE("7024", "Bulgarije"), + MALEISIË("7026", "Maleisië"), + DOMINICAANSE_REPUBLIEK("7027", "Dominicaanse Republiek"), + POLEN("7028", "Polen"), + RUSLAND_OUD("7029", "Rusland (oud)"), + BRITSE_MAAGDENEILANDEN("7030", "Britse Maagdeneilanden"), + TANZANIA("7031", "Tanzania"), + EL_SALVADOR("7032", "El Salvador"), + SRI_LANKA("7033", "Sri Lanka"), + SOEDAN("7034", "Soedan"), + JAPAN("7035", "Japan"), + HONGKONG("7036", "Hongkong"), + PANAMA("7037", "Panama"), + URUGUAY("7038", "Uruguay"), + ECUADOR("7039", "Ecuador"), + GUINEE("7040", "Guinee"), + MALDIVEN("7041", "Maldiven"), + THAILAND("7042", "Thailand"), + LIBANON("7043", "Libanon"), + ITALIË("7044", "Italië"), + KOEWEIT("7045", "Koeweit"), + INDIA("7046", "India"), + ROEMENIË("7047", "Roemenië"), + TSJECHOSLOWAKIJE("7048", "Tsjecho-Slowakije"), + PERU("7049", "Peru"), + PORTUGAL("7050", "Portugal"), + OMAN("7051", "Oman"), + MONGOLIË("7052", "Mongolië"), + SAMOA("7053", "Samoa"), + VERENIGDE_ARABISCHE_EMIRATEN("7054", "Verenigde Arabische Emiraten"), + TIBET("7055", "Tibet"), + NAURU("7057", "Nauru"), + NEDERLANDS_NIEUWGUINEA("7058", "Nederlands Nieuw-Guinea"), + TANGANYIKA("7059", "Tanganyika"), + PALESTINA("7060", "Palestina"), + BRITS_WESTINDIË("7062", "Brits West-Indië"), + PORTUGEESAFRIKA("7063", "Portugees-Afrika"), + LETLAND("7064", "Letland"), + ESTLAND("7065", "Estland"), + LITOUWEN("7066", "Litouwen"), + BRITSAFRIKA("7067", "Brits-Afrika"), + BELGISCHCONGO("7068", "Belgisch-Congo"), + BRITSINDIË("7070", "Brits-Indië"), + NOORDRHODESIË("7071", "Noord-Rhodesië"), + ZUIDRHODESIË("7072", "Zuid-Rhodesië"), + SAARLAND("7073", "Saarland"), + FRANS_INDOCHINA("7074", "Frans Indochina"), + BRITS_WESTBORNEO("7075", "Brits West-Borneo"), + GOUDKUST("7076", "Goudkust"), + RAS_ALKHAIMAH("7077", "Ras al-Khaimah"), + FRANSCONGO("7079", "Frans-Congo"), + SIAM("7080", "Siam"), + BRITS_OOSTAFRIKA("7082", "Brits Oost-Afrika"), + BRITS_NOORDBORNEO("7083", "Brits Noord-Borneo"), + BANGLADESH("7084", "Bangladesh"), + DUITSE_DEMOCRATISCHE_REPUBLIEK("7085", "Duitse Democratische Republiek"), + MADEIRAEILANDEN("7087", "Madeira-eilanden"), + AMERIKAANSE_MAAGDENEILANDEN("7088", "Amerikaanse Maagdeneilanden"), + AUSTRALISCHE_SALOMONSEILANDEN("7089", "Australische Salomonseilanden"), + SPAANSE_SAHARA("7091", "Spaanse Sahara"), + CAYMANEILANDEN("7092", "Caymaneilanden"), + CAICOSEILANDEN("7093", "Caicoseilanden"), + TURKSEILANDEN("7094", "Turkseilanden"), + BRITS_ANTARCTISCH_TERRITORIUM("7095", "Brits Antarctisch Territorium"), + BRITS_INDISCHE_OCEAANTERRITORIUM("7096", "Brits Indische Oceaanterritorium"), + COOKEILANDEN("7097", "Cookeilanden"), + TOKELAU("7098", "Tokelau"), + NIEUWCALEDONIË("7099", "Nieuw-Caledonië"), + HAWAIIEILANDEN("8000", "Hawaii-eilanden"), + GUAM("8001", "Guam"), + AMERIKAANSSAMOA("8002", "Amerikaans-Samoa"), + MIDWAY("8003", "Midway"), + RIUKIUEILANDEN("8004", "Riukiu-eilanden"), + WAKE("8005", "Wake"), + PACIFICEILANDEN("8006", "Pacific-eilanden"), + GRENADA("8008", "Grenada"), + MARIANEN("8009", "Marianen"), + CABINDA("8010", "Cabinda"), + CANTON_EN_ENDERBURY("8011", "Canton en Enderbury"), + CHRISTMASEILAND("8012", "Christmaseiland"), + COCOSEILANDEN("8013", "Cocoseilanden"), + FAERÖER("8014", "Faeröer"), + MONTSERRAT("8015", "Montserrat"), + NORFOLK("8016", "Norfolk"), + BELIZE("8017", "Belize"), + TASMANIË("8018", "Tasmanië"), + TURKS_EN_CAICOSEILANDEN("8019", "Turks- en Caicoseilanden"), + PUERTO_RICO("8020", "Puerto Rico"), + PAPOEANIEUWGUINEA("8021", "Papoea-Nieuw-Guinea"), + SALOMONSEILANDEN("8022", "Salomonseilanden"), + BENIN("8023", "Benin"), + VIETNAM("8024", "Vietnam"), + KAAPVERDIË("8025", "Kaapverdië"), + SEYCHELLEN("8026", "Seychellen"), + KIRIBATI("8027", "Kiribati"), + TUVALU("8028", "Tuvalu"), + SAINT_LUCIA("8029", "Saint Lucia"), + DOMINICA("8030", "Dominica"), + ZIMBABWE("8031", "Zimbabwe"), + DUBAI("8032", "Dubai"), + NIEUWE_HEBRIDEN("8033", "Nieuwe Hebriden"), + KANAALEILANDEN("8034", "Kanaaleilanden"), + MAN("8035", "Man"), + ANGUILLA("8036", "Anguilla"), + SAINT_KITTS_EN_NEVIS("8037", "Saint Kitts en Nevis"), + ANTIGUA("8038", "Antigua"), + SAINT_VINCENT("8039", "Saint Vincent"), + GILBERTEILANDEN("8040", "Gilberteilanden"), + PANAMAKANAALZONE("8041", "Panamakanaalzone"), + SAINT_KITTS_NEVIS_EN_ANGUILLA("8042", "Saint Kitts, Nevis en Anguilla"), + BELAU("8043", "Belau"), + PALAU("8044", "Palau"), + ANTIGUA_EN_BARBUDA("8045", "Antigua en Barbuda"), + NEWFOUNDLAND("9000", "Newfoundland"), + NYASALAND("9001", "Nyasaland"), + ERITREA("9003", "Eritrea"), + IFNI("9005", "Ifni"), + BRITSKAMEROEN("9006", "Brits-Kameroen"), + KEIZER_WILHELMSLAND("9007", "Keizer Wilhelmsland"), + CONGO("9008", "Congo"), + CONGOKINSHASA("9009", "Congo-Kinshasa"), + MADAGASKAR("9010", "Madagaskar"), + CONGOBRAZZAVILLE("9013", "Congo-Brazzaville"), + LEEWARDEILANDEN("9014", "Leewardeilanden"), + WINDWARDEILANDEN("9015", "Windwardeilanden"), + FRANS_TERRITORIUM_VOOR_AFARS_EN_ISSAS("9016", "Frans Territorium voor Afars en Issa's"), + PHOENIXEILANDEN("9017", "Phoenixeilanden"), + PORTUGEESGUINEE("9020", "Portugees-Guinee"), + DUITS_ZUIDWESTAFRIKA("9022", "Duits Zuidwest-Afrika"), + NAMIBIË("9023", "Namibië"), + BRITSSOMALILAND("9027", "Brits-Somaliland"), + ITALIAANSSOMALILAND("9028", "Italiaans-Somaliland"), + NEDERLANDSINDIË("9030", "Nederlands-Indië"), + BRITSGUYANA("9031", "Brits-Guyana"), + SWAZILAND("9036", "Swaziland"), + QATAR("9037", "Qatar"), + ESWATINI("9038", "Eswatini"), + ADEN("9041", "Aden"), + ZUIDARABISCHE_FEDERATIE("9042", "Zuid-Arabische Federatie"), + EQUATORIAALGUINEA("9043", "Equatoriaal-Guinea"), + SPAANSGUINEE("9044", "Spaans-Guinee"), + VERENIGDE_ARABISCHE_REPUBLIEK("9047", "Verenigde Arabische Republiek"), + BERMUDA("9048", "Bermuda"), + SOVJETUNIE("9049", "Sovjet-Unie"), + DUITS_OOSTAFRIKA("9050", "Duits Oost-Afrika"), + ZANZIBAR("9051", "Zanzibar"), + CEYLON("9052", "Ceylon"), + MUSCAT_EN_OMAN("9053", "Muscat en Oman"), + TRUCIAL_OMAN("9054", "Trucial Oman"), + INDOCHINA("9055", "Indochina"), + MARSHALLEILANDEN("9056", "Marshalleilanden"), + SARAWAK("9057", "Sarawak"), + BRITSBORNEO("9058", "Brits-Borneo"), + SABAH("9060", "Sabah"), + ABU_DHABI("9061", "Abu Dhabi"), + AJMAN("9062", "Ajman"), + BASUTOLAND("9063", "Basutoland"), + BECHUANALAND("9064", "Bechuanaland"), + FUJAIRAH("9065", "Fujairah"), + FRANSKAMEROEN("9066", "Frans-Kameroen"), + JOHORE("9067", "Johore"), + KOREA("9068", "Korea"), + LABUAN("9069", "Labuan"), + UMM_ALQAIWAIN("9070", "Umm Al-Qaiwain"), + OOSTENRIJKHONGARIJE("9071", "Oostenrijk-Hongarije"), + PORTUGEES_OOSTAFRIKA("9072", "Portugees Oost-Afrika"), + PORTUGEES_WESTAFRIKA("9073", "Portugees West-Afrika"), + SHARJAH("9074", "Sharjah"), + STRAITS_SETTLEMENTS("9075", "Straits Settlements"), + ABESSINIË("9076", "Abessinië"), + FRANS_WESTAFRIKA("9077", "Frans West-Afrika"), + FRANS_EQUATORIAALAFRIKA("9078", "Frans Equatoriaal-Afrika"), + URUNDI("9081", "Urundi"), + RUANDAURUNDI("9082", "Ruanda-Urundi"), + GOA("9084", "Goa"), + DANTZIG("9085", "Dantzig"), + CENTRAALAFRIKAANSE_REPUBLIEK("9086", "Centraal-Afrikaanse Republiek"), + DJIBOUTI("9087", "Djibouti"), + TRANSJORDANIË("9088", "Transjordanië"), + BONDSREPUBLIEK_DUITSLAND("9089", "Bondsrepubliek Duitsland"), + VANUATU("9090", "Vanuatu"), + NIUE("9091", "Niue"), + SPAANS_NOORDAFRIKA("9092", "Spaans Noord-Afrika"), + WESTELIJKE_SAHARA("9093", "Westelijke Sahara"), + MICRONESIA("9094", "Micronesia"), + SVALBARDEILANDEN("9095", "Svalbardeilanden"), + INTERNATIONAAL_GEBIED("9999", "Internationaal gebied"), + ; + + override fun toString(): String { + return "$landcode: $landnaam" + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt new file mode 100644 index 00000000..dbc21daf --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.server.operations.Query +import graphql.schema.DataFetchingEnvironment +import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY +import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.service.OpenKlant2Service + +class PartijQuery(private val openklant2Service: OpenKlant2Service): Query { + @GraphQLDescription("Get user Partij") + suspend fun getPartij(dfe: DataFetchingEnvironment): Partij? { + return openklant2Service.getPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY)) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt new file mode 100644 index 00000000..479a191f --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.service + +import nl.nlportal.commonground.authentication.CommonGroundAuthentication +import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.domain.Partij + +class OpenKlant2Service( + private val enabled: Boolean = false, + private val openKlant2Client: OpenKlant2Client +) { + + suspend fun getPartij(authentication: CommonGroundAuthentication): Partij? { + if (!enabled) return null + + return openKlant2Client.getPartij(authentication) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..0651fb78 --- /dev/null +++ b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt new file mode 100644 index 00000000..302a3f67 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant + +import nl.nlportal.core.security.OauthSecurityAutoConfiguration +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication +import org.springframework.context.annotation.Bean +import org.springframework.security.config.web.server.ServerHttpSecurity +import org.springframework.security.web.server.SecurityWebFilterChain + +@SpringBootApplication( + exclude = [ + OauthSecurityAutoConfiguration::class, + ], +) +class TestApplication { + fun main(args: Array) { + runApplication(*args) + } + + @Bean + fun springSecurityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { + return http + .csrf { it.disable() } + .authorizeExchange { + it.anyExchange().permitAll() + } + .build() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt new file mode 100644 index 00000000..db3c9f29 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant + +import okhttp3.mockwebserver.MockResponse + +object TestHelper { + fun mockResponseFromFile(fileName: String): MockResponse { + return MockResponse() + .addHeader("Content-Type", "application/json; charset=utf-8") + .setResponseCode(200) + .setBody(readFileAsString(fileName)) + } + + private fun readFileAsString(fileName: String): String = this::class.java.getResource(fileName).readText(Charsets.UTF_8) +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/application.yml b/zgw/openklant/src/test/resources/config/application.yml new file mode 100644 index 00000000..a7c28a99 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/application.yml @@ -0,0 +1,16 @@ +graphql: + packages: + - "nl.nlportal" + +nl-portal: + openklant: + url: #filled in test + clientId: valtimo_client + secret: e09b8bc5-5831-4618-ab28-41411304309d + +spring: + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://localhost:8082/auth/realms/nlportal \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/zgw/openklant/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 00000000..ca6ee9ce --- /dev/null +++ b/zgw/openklant/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file From 9d37d78b481baaa257ce9c03536dd3048b1f2cc1 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Tue, 17 Sep 2024 16:58:38 +0200 Subject: [PATCH 02/19] wip --- .../openklant/client/OpenKlant2Client.kt | 47 ++++++++++++++++++- .../nl/nlportal/openklant/domain/Partijen.kt | 29 ++++++++++++ .../openklant/service/OpenKlant2Service.kt | 2 +- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt index b31c2878..0f404ce5 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt @@ -21,12 +21,14 @@ import nl.nlportal.commonground.authentication.BurgerAuthentication import nl.nlportal.commonground.authentication.CommonGroundAuthentication import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties +import nl.nlportal.openklant.domain.CreatePartij import nl.nlportal.openklant.domain.Partij import nl.nlportal.openklant.domain.ResultPage import org.springframework.http.MediaType import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.http.codec.json.Jackson2JsonDecoder import org.springframework.http.codec.json.Jackson2JsonEncoder +import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.ExchangeStrategies import org.springframework.web.reactive.function.client.WebClient import org.springframework.web.reactive.function.client.awaitBody @@ -34,14 +36,14 @@ import reactor.netty.http.client.HttpClient import reactor.netty.transport.logging.AdvancedByteBufFormat.TEXTUAL class OpenKlant2Client(private val openKlantConfigurationProperties: OpenKlantConfigurationProperties) { - suspend fun getPartij(authentication: CommonGroundAuthentication): Partij? { + suspend fun findPartij(authentication: CommonGroundAuthentication): Partij? { val soortPartij = when (authentication) { is BurgerAuthentication -> "persoon" is BedrijfAuthentication -> "organisatie" else -> "contactpersoon" } val searchVariables = mapOf( - "soortPartij" to soortPartij, + "soortPartij" to authentication.asSoortPartij(), "partijIdentificator__objectId" to authentication.userId ) @@ -59,6 +61,47 @@ class OpenKlant2Client(private val openKlantConfigurationProperties: OpenKlantCo return response.results.singleOrNull() } + suspend fun createPartij(partij: CreatePartij, authentication: CommonGroundAuthentication): Partij? { + val response: ResultPage = webClient() + .post() + .uri { uriBuilder -> + uriBuilder + .path("/partijen") + .build() + } + .body(BodyInserters.fromValue(partij)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results.singleOrNull() + } + + + suspend fun putPartij(partij: Partij, authentication: CommonGroundAuthentication): Partij? { + val response: ResultPage = webClient() + .put() + .uri { uriBuilder -> + uriBuilder + .path("/partijen/${partij.uuid}") + .build() + } + .body(BodyInserters.fromValue(partij)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results.singleOrNull() + } + + private fun CommonGroundAuthentication.asSoortPartij(): String { + return when (this) { + is BurgerAuthentication -> "persoon" + is BedrijfAuthentication -> "organisatie" + else -> "contactpersoon" + } + } + fun webClient(): WebClient { return webclientBuilder .baseUrl(openKlantConfigurationProperties.url.toString()) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt index 67ad8ee5..7419df9a 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt @@ -56,6 +56,35 @@ data class Partij( } } +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class CreatePartij( + val nummer: String? = null, + val interneNotitie: String? = null, + val digitaleAdressen: List, + val voorkeursDigitaalAdres: ForeignKey, + val rekeningnummers: List, + val voorkeursRekeningnummer: Rekeningnummer, + val soortPartij: SoortPartij, + val indicatieGeheimhouding: Boolean, + val voorkeurstaal: String? = null, + val indicatieActief: Boolean, + val bezoekadres: Adres? = null, + val correspondentieadres: Adres? = null, +) { + init { + require(voorkeurstaal == null || voorkeurstaal in Locale.getAvailableLocales().map { it.isO3Language }) { + "Voorkeurstaal must be a valid Language in the ISO 639-2/B format" + } + require(interneNotitie == null || interneNotitie.length <= 1000) { + "Interne notitie can't be longer than 1000 characters." + } + require(nummer == null || nummer.length <= 10) { + "Nummer can't be longer than 10 characters." + } + } +} + data class PartijenFilterOptions( val page: Int = 1, val naam: String? = null, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index 479a191f..b982a6da 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -27,6 +27,6 @@ class OpenKlant2Service( suspend fun getPartij(authentication: CommonGroundAuthentication): Partij? { if (!enabled) return null - return openKlant2Client.getPartij(authentication) + return openKlant2Client.findPartij(authentication) } } \ No newline at end of file From 7044835b80598d9c54ed747578cf9e82d9985ece Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Sat, 28 Sep 2024 15:20:47 +0200 Subject: [PATCH 03/19] wip --- zgw/openklant/build.gradle.kts | 1 + .../OpenKlantAutoConfiguration.kt | 38 ++- .../OpenKlantModuleConfiguration.kt | 8 +- .../openklant/client/OpenKlant2Client.kt | 85 +----- .../client/path/KlantInteractiesPath.kt | 20 ++ .../openklant/client/path/Partijen.kt | 83 ++++++ .../nlportal/openklant/domain/Betrokkenen.kt | 46 ++++ .../openklant/domain/CategorieRelaties.kt | 40 +++ .../openklant/domain/DigitaleAdressen.kt | 53 ++++ .../openklant/domain/KlantContacten.kt | 43 +++ .../nl/nlportal/openklant/domain/Partijen.kt | 157 +++++++---- .../nl/nlportal/openklant/domain/Shared.kt | 138 ++++++---- .../openklant/graphql/PartijMutation.kt | 46 ++++ .../nlportal/openklant/graphql/PartijQuery.kt | 7 +- .../openklant/service/OpenKlant2Service.kt | 51 +++- .../nl/nlportal/openklant/TestApplication.kt | 12 + .../nl/nlportal/openklant/TestHelper.kt | 251 +++++++++++++++++- .../openklant/client/OpenKlantClientTest.kt | 76 ++++++ .../configuration/ModuleConfigurationIT.kt | 81 ++++++ .../openklant/graphql/PartijQueryIT.kt | 213 +++++++++++++++ .../src/test/resources/config/application.yml | 39 ++- .../config/graphql/getPartij.graphql | 89 +++++++ .../graphql/partijTypeIntrospection.graphql | 7 + 23 files changed, 1356 insertions(+), 228 deletions(-) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt create mode 100644 zgw/openklant/src/test/resources/config/graphql/getPartij.graphql create mode 100644 zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql diff --git a/zgw/openklant/build.gradle.kts b/zgw/openklant/build.gradle.kts index d88732d5..ea1d4b4b 100644 --- a/zgw/openklant/build.gradle.kts +++ b/zgw/openklant/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { testImplementation("org.springframework.boot", "spring-boot-starter-test") testImplementation("org.springframework.security", "spring-security-test") testImplementation(TestDependencies.kotlinCoroutines) + testImplementation(TestDependencies.mockitoKotlin) testImplementation(TestDependencies.okHttpMockWebserver) testImplementation(TestDependencies.okHttp) } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index 901cb49c..727cd5e4 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -15,32 +15,50 @@ */ package nl.nlportal.openklant.autoconfigure +import com.expediagroup.graphql.server.operations.Mutation +import com.expediagroup.graphql.server.operations.Query import mu.KotlinLogging import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.graphql.PartijMutation +import nl.nlportal.openklant.graphql.PartijQuery import nl.nlportal.openklant.service.OpenKlant2Service +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -@Configuration @EnableConfigurationProperties( OpenKlantModuleConfiguration::class, ) class OpenKlantAutoConfiguration { @Bean + @ConditionalOnMissingBean(OpenKlant2Client::class) fun openKlant2Client(openklantModuleConfiguration: OpenKlantModuleConfiguration): OpenKlant2Client { - if (!openklantModuleConfiguration.enabled) { - logger.debug { "OpenKlant 2 is not configured." } - } return OpenKlant2Client(openKlantConfigurationProperties = openklantModuleConfiguration.properties) } @Bean - fun openKlant2Service( - openklantModuleConfiguration: OpenKlantModuleConfiguration, - openklant2Client: OpenKlant2Client - ): OpenKlant2Service { - return OpenKlant2Service(openklantModuleConfiguration.enabled, openklant2Client) + @ConditionalOnMissingBean(OpenKlant2Service::class) + fun openKlant2Service(openklant2Client: OpenKlant2Client): OpenKlant2Service { + return OpenKlant2Service(openklant2Client) + } + + @Bean + @ConditionalOnMissingBean(PartijQuery::class) + @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") + fun partijQuery( + openKlant2Service: OpenKlant2Service, + ): Query { + return PartijQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(PartijMutation::class) + @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") + fun partijMutation( + openKlant2Service: OpenKlant2Service, + ): Mutation { + return PartijMutation(openKlant2Service) } companion object { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt index f73f1ae5..b8ff0aba 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt @@ -25,8 +25,12 @@ data class OpenKlantModuleConfiguration( ) { init { if (enabled) { - requireNotNull(properties.url) - requireNotNull(properties.token) + requireNotNull(properties.url) { + "OpenKlant URL not configured" + } + requireNotNull(properties.token) { + "OpenKlant token not configured" + } } } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt index 0f404ce5..d5943e8b 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt @@ -16,90 +16,21 @@ package nl.nlportal.openklant.client import io.netty.handler.logging.LogLevel.TRACE -import nl.nlportal.commonground.authentication.BedrijfAuthentication -import nl.nlportal.commonground.authentication.BurgerAuthentication -import nl.nlportal.commonground.authentication.CommonGroundAuthentication import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties -import nl.nlportal.openklant.domain.CreatePartij -import nl.nlportal.openklant.domain.Partij -import nl.nlportal.openklant.domain.ResultPage -import org.springframework.http.MediaType +import nl.nlportal.openklant.client.path.KlantInteractiesPath import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.http.codec.json.Jackson2JsonDecoder import org.springframework.http.codec.json.Jackson2JsonEncoder -import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.ExchangeStrategies import org.springframework.web.reactive.function.client.WebClient -import org.springframework.web.reactive.function.client.awaitBody import reactor.netty.http.client.HttpClient import reactor.netty.transport.logging.AdvancedByteBufFormat.TEXTUAL +import kotlin.reflect.full.primaryConstructor class OpenKlant2Client(private val openKlantConfigurationProperties: OpenKlantConfigurationProperties) { - suspend fun findPartij(authentication: CommonGroundAuthentication): Partij? { - val soortPartij = when (authentication) { - is BurgerAuthentication -> "persoon" - is BedrijfAuthentication -> "organisatie" - else -> "contactpersoon" - } - val searchVariables = mapOf( - "soortPartij" to authentication.asSoortPartij(), - "partijIdentificator__objectId" to authentication.userId - ) - - val response: ResultPage = webClient() - .get() - .uri { uriBuilder -> - uriBuilder - .path("/partijen") - .build(searchVariables) - } - .accept(MediaType.APPLICATION_JSON) - .retrieve() - .awaitBody() - - return response.results.singleOrNull() - } - - suspend fun createPartij(partij: CreatePartij, authentication: CommonGroundAuthentication): Partij? { - val response: ResultPage = webClient() - .post() - .uri { uriBuilder -> - uriBuilder - .path("/partijen") - .build() - } - .body(BodyInserters.fromValue(partij)) - .accept(MediaType.APPLICATION_JSON) - .retrieve() - .awaitBody() - - return response.results.singleOrNull() - } - - - suspend fun putPartij(partij: Partij, authentication: CommonGroundAuthentication): Partij? { - val response: ResultPage = webClient() - .put() - .uri { uriBuilder -> - uriBuilder - .path("/partijen/${partij.uuid}") - .build() - } - .body(BodyInserters.fromValue(partij)) - .accept(MediaType.APPLICATION_JSON) - .retrieve() - .awaitBody() - - return response.results.singleOrNull() - } - - private fun CommonGroundAuthentication.asSoortPartij(): String { - return when (this) { - is BurgerAuthentication -> "persoon" - is BedrijfAuthentication -> "organisatie" - else -> "contactpersoon" - } + inline fun path(): P { + return P::class.primaryConstructor!!.call(this) } fun webClient(): WebClient { @@ -111,14 +42,6 @@ class OpenKlant2Client(private val openKlantConfigurationProperties: OpenKlantCo .build() } - fun webClientWithoutBaseUrl(): WebClient { - return webclientBuilder - .defaultHeader("Accept-Crs", "EPSG:4326") - .defaultHeader("Content-Crs", "EPSG:4326") - .defaultHeader("Authorization", "Token ${openKlantConfigurationProperties.token}") - .build() - } - private val webclientBuilder = WebClient.builder() .clientConnector( diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt new file mode 100644 index 00000000..adbbfb49 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client.path + +open class KlantInteractiesPath { + open val path: String = "/" +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt new file mode 100644 index 00000000..2e95df9c --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client.path + +import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.domain.CreatePartij +import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.domain.ResultPage +import org.springframework.http.MediaType +import org.springframework.util.MultiValueMap +import org.springframework.web.reactive.function.BodyInserters +import org.springframework.web.reactive.function.client.awaitBody + +class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { + override val path = "/klantinteracties/api/v1/partijen" + + suspend fun find(queryParams: MultiValueMap? = null): Partij? { + val response: ResultPage = + client + .webClient() + .get() + .uri { uriBuilder -> + uriBuilder + .path(path) + queryParams?.let { uriBuilder.queryParams(it) } + uriBuilder.build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results.singleOrNull() + } + + suspend fun create(createPartij: CreatePartij): Partij { + val response: Partij = + client + .webClient() + .post() + .uri { uriBuilder -> + uriBuilder + .path(path) + .build() + } + .body(BodyInserters.fromValue(createPartij)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response + } + + suspend fun put(partij: Partij): Partij? { + val response: ResultPage = + client + .webClient() + .put() + .uri { uriBuilder -> + uriBuilder + .path("$path/${partij.uuid}") + .build() + } + .body(BodyInserters.fromValue(partij)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results.singleOrNull() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt new file mode 100644 index 00000000..e4a38cfe --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import nl.nlportal.openklant.domain.CreatePartij.Contactnaam + +data class Betrokkene( + val bezoekadres: OpenKlant2Adres? = null, + val contactnaam: Contactnaam? = null, + val correspondentieadres: OpenKlant2Adres? = null, + val digitaleAdressen: List, + val hadKlantcontact: OpenKlant2ForeignKey, + val initiator: Boolean, + val organisatienaam: String, + val rol: String, + val url: String, + val uuid: String, + val volledigeNaam: String, + val wasPartij: OpenKlant2ForeignKey? = null, +) + +data class CreateBetrokkene( + val bezoekadres: OpenKlant2Adres? = null, + val contactnaam: Contactnaam? = null, + val correspondentieadres: OpenKlant2Adres? = null, + val digitaleAdressen: List, + val hadKlantcontact: OpenKlant2ForeignKey, + val initiator: Boolean, + val organisatienaam: String, + val rol: String, + val volledigeNaam: String, + val wasPartij: OpenKlant2ForeignKey? = null, +) \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt new file mode 100644 index 00000000..62eeca3b --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import java.time.LocalDate + +data class CategorieRelatie( + val beginDatum: LocalDate? = null, + val categorie: Categorie? = null, + val eindDatum: LocalDate? = null, + val partij: OpenKlant2ForeignKey? = null, + val url: String, + val uuid: String, +) + +data class CreateCategorieRelatie( + val beginDatum: LocalDate? = null, + val categorie: Categorie? = null, + val eindDatum: LocalDate? = null, + val partij: OpenKlant2ForeignKey? = null, +) + +data class Categorie( + val naam: String, + val url: String, + val uuid: String, +) \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt new file mode 100644 index 00000000..8d5301fa --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class DigitaleAdres( + val adres: String, + val omschrijving: String, + val soortDigitaalAdres: String, + val url: String, + val uuid: String, + val verstrektDoorBetrokkene: OpenKlant2ForeignKey? = null, + val verstrektDoorPartij: OpenKlant2ForeignKey? = null, +) + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class CreateDigitaleAdres( + val adres: String, + val omschrijving: String, + val soortDigitaalAdres: String, + val verstrektDoorBetrokkene: OpenKlant2ForeignKey? = null, + val verstrektDoorPartij: OpenKlant2ForeignKey? = null, +) { + init { + require(adres.length <= 80) { + "adres can't be longer than 10 characters." + } + require(omschrijving.length <= 40) { + "omschrijving can't be longer than 10 characters." + } + require(soortDigitaalAdres.length <= 255) { + "soortDigitaalAdres can't be longer than 10 characters." + } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt new file mode 100644 index 00000000..7af40e39 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.domain + +data class HadKlantcontact( + val gingOverOnderwerpobjecten: List, + val hadBetrokkenActoren: List, + val hadBetrokkenen: List, + val indicatieContactGelukt: Boolean, + val inhoud: String, + val kanaal: String, + val leiddeTotInterneTaken: List, + val nummer: String, + val omvatteBijlagen: List, + val onderwerp: String, + val plaatsgevondenOp: String, + val taal: String, + val url: String, + val uuid: String, + val vertrouwelijk: Boolean, +) + +data class HadBetrokkenActoren( + val actoridentificator: OpenKlant2Identificator, + val indicatieActief: Boolean, + val naam: String, + val soortActor: String, + val url: String, + val uuid: String, +) \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt index 7419df9a..c7781cb4 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt @@ -15,33 +15,56 @@ */ package nl.nlportal.openklant.domain +import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonSubTypes +import com.fasterxml.jackson.annotation.JsonSubTypes.Type +import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonValue +import nl.nlportal.commonground.authentication.BedrijfAuthentication +import nl.nlportal.commonground.authentication.BurgerAuthentication +import nl.nlportal.commonground.authentication.CommonGroundAuthentication +import nl.nlportal.openklant.domain.CreatePartij.ContactpersoonIdentificatie +import nl.nlportal.openklant.domain.CreatePartij.OrganisatieIdentificatie +import nl.nlportal.openklant.domain.CreatePartij.PartijIdentificatie +import nl.nlportal.openklant.domain.CreatePartij.PersoonsIdentificatie +import java.time.LocalDate import java.util.Locale import java.util.UUID +@GraphQLDescription(value = "A Type that represents a Klantinteracties API Partij object") @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) data class Partij( - val betrokkenen: List = emptyList(), - val bezoekadres: Adres? = null, + val betrokkenen: List = emptyList(), + val bezoekadres: OpenKlant2Adres? = null, val categorieRelaties: List, - val correspondentieadres: Adres? = null, - val digitaleAdressen: List? = null, + val correspondentieadres: OpenKlant2Adres? = null, + val digitaleAdressen: List? = null, val indicatieActief: Boolean, val indicatieGeheimhouding: Boolean? = null, val interneNotitie: String? = null, val nummer: String? = null, - val partijIdentificatoren: List, - val rekeningnummers: List? = null, + val partijIdentificatoren: List, + val rekeningnummers: List? = null, val soortPartij: SoortPartij, val url: String, val uuid: UUID, - val vertegenwoordigden: List, - val voorkeursDigitaalAdres: ForeignKey? = null, - val voorkeursRekeningnummer: Rekeningnummer? = null, + val vertegenwoordigden: List, + val voorkeursDigitaalAdres: OpenKlant2ForeignKey? = null, + val voorkeursRekeningnummer: OpenKlant2ForeignKey? = null, val voorkeurstaal: String?, + @JsonTypeInfo(include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "soortPartij", use = JsonTypeInfo.Id.NAME) + @JsonSubTypes( + Type(PersoonsIdentificatie::class, name = "persoon"), + Type(OrganisatieIdentificatie::class, name = "organisatie"), + Type(ContactpersoonIdentificatie::class, name = "contactpersoon"), + ) + val partijIdentificatie: PartijIdentificatie, + @JsonProperty("_expand") + val expand: PartijExpand? = null, ) { init { require(voorkeurstaal == null || voorkeurstaal in Locale.getAvailableLocales().map { it.isO3Language }) { @@ -57,20 +80,32 @@ data class Partij( } @JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) data class CreatePartij( + @JsonInclude(JsonInclude.Include.NON_NULL) val nummer: String? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) val interneNotitie: String? = null, - val digitaleAdressen: List, - val voorkeursDigitaalAdres: ForeignKey, - val rekeningnummers: List, - val voorkeursRekeningnummer: Rekeningnummer, + val digitaleAdressen: List? = null, + val voorkeursDigitaalAdres: OpenKlant2ForeignKey? = null, + val rekeningnummers: List? = null, + val voorkeursRekeningnummer: OpenKlant2ForeignKey? = null, val soortPartij: SoortPartij, val indicatieGeheimhouding: Boolean, + @JsonInclude(JsonInclude.Include.NON_NULL) val voorkeurstaal: String? = null, val indicatieActief: Boolean, - val bezoekadres: Adres? = null, - val correspondentieadres: Adres? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val bezoekadres: OpenKlant2Adres? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val correspondentieadres: OpenKlant2Adres? = null, + val partijIdentificatoren: List, + @JsonTypeInfo(include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "soortPartij", use = JsonTypeInfo.Id.NAME) + @JsonSubTypes( + Type(PersoonsIdentificatie::class, name = "persoon"), + Type(OrganisatieIdentificatie::class, name = "organisatie"), + Type(ContactpersoonIdentificatie::class, name = "contactpersoon"), + ) + val partijIdentificatie: PartijIdentificatie, ) { init { require(voorkeurstaal == null || voorkeurstaal in Locale.getAvailableLocales().map { it.isO3Language }) { @@ -83,58 +118,58 @@ data class CreatePartij( "Nummer can't be longer than 10 characters." } } -} -data class PartijenFilterOptions( - val page: Int = 1, - val naam: String? = null, - val indicatieActief: Boolean? = null, - val soortPartij: SoortPartij? = null, -) + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + open class PersoonsIdentificatie( + val contactnaam: Contactnaam? = null, + val volledigeNaam: String? = null, + ) : PartijIdentificatie -data class Adres( - val adresregel1: String? = null, - val adresregel2: String? = null, - val adresregel3: String? = null, - val land: Landcode? = null, - val nummeraanduidingId: String? = null, -) { - init { - require(nummeraanduidingId == null || nummeraanduidingId.length <= 255) { - "Adresregel1 can't be more than 255 characters long." - } - require(adresregel1 == null || adresregel1.length <= 80) { - "Adresregel1 can't be more than 255 characters long." - } - require(adresregel2 == null || adresregel2.length <= 80) { - "Adresregel1 can't be more than 255 characters long." - } - require(adresregel3 == null || adresregel3.length <= 80) { - "Adresregel1 can't be more than 255 characters long." - } - } + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + data class ContactpersoonIdentificatie( + val uuid: UUID? = null, + val werkteVoorPartij: OpenKlant2ForeignKey? = null, + val contactnaam: Contactnaam? = null, + val volledigeNaam: String? = null, + ) : PartijIdentificatie + + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + data class OrganisatieIdentificatie( + val naam: String? = null, + ) : PartijIdentificatie + + interface PartijIdentificatie + + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + data class Contactnaam( + val voorletters: String? = null, + val voornaam: String? = null, + val voorvoegselAchternaam: String? = null, + val achternaam: String? = null, + ) } +class PartijExpand( + val betrokkenen: List? = null, + val hadKlantcontact: List? = null, + val categorieRelaties: List? = null, + val digitaleAdressen: List? = null, +) + data class CategorieRelatieForeignKey( - val beginDatum: String, + val beginDatum: LocalDate? = null, val categorieNaam: String, - val eindDatum: String, + val eindDatum: LocalDate? = null, val url: String, val uuid: String, ) -data class Rekeningnummer(val uuid: String) - -data class CreatePartij( - val name: String, -) { - init { - require(name.length in 1..200) { "Partij name has to be between 1 and 200 characters long" } - } -} - enum class SoortPartij( - @JsonValue private val value: String, + @JsonValue val value: String, ) { PERSOON("persoon"), ORGANISATIE("organisatie"), @@ -144,4 +179,12 @@ enum class SoortPartij( override fun toString(): String { return this.value } +} + +fun CommonGroundAuthentication.asSoortPartij(): String { + return when (this) { + is BurgerAuthentication -> "persoon" + is BedrijfAuthentication -> "organisatie" + else -> "contactpersoon" + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt index ee2cd5ae..e94ee065 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt @@ -17,18 +17,41 @@ package nl.nlportal.openklant.domain import com.fasterxml.jackson.annotation.JsonValue -data class ForeignKey( +data class OpenKlant2ForeignKey( val url: String, val uuid: String, ) -data class Identificator( +data class OpenKlant2Identificator( val objectId: String, val codeObjecttype: String, val codeRegister: String, val codeSoortObjectId: String, ) +data class OpenKlant2Adres( + val adresregel1: String? = null, + val adresregel2: String? = null, + val adresregel3: String? = null, + val land: Landcode? = null, + val nummeraanduidingId: String? = null, +) { + init { + require(nummeraanduidingId == null || nummeraanduidingId.length <= 255) { + "Adresregel1 can't be more than 255 characters long." + } + require(adresregel1 == null || adresregel1.length <= 80) { + "Adresregel1 can't be more than 255 characters long." + } + require(adresregel2 == null || adresregel2.length <= 80) { + "Adresregel1 can't be more than 255 characters long." + } + require(adresregel3 == null || adresregel3.length <= 80) { + "Adresregel1 can't be more than 255 characters long." + } + } +} + enum class Landcode( @JsonValue val landcode: String, val landnaam: String, @@ -36,13 +59,13 @@ enum class Landcode( CANADA("5001", "Canada"), FRANKRIJK("5002", "Frankrijk"), ZWITSERLAND("5003", "Zwitserland"), - RHODESIË("5004", "Rhodesië"), + RHODESIE("5004", "Rhodesië"), MALAWI("5005", "Malawi"), CUBA("5006", "Cuba"), SURINAME("5007", "Suriname"), - TUNESIË("5008", "Tunesië"), + TUNESIE("5008", "Tunesië"), OOSTENRIJK("5009", "Oostenrijk"), - BELGIË("5010", "België"), + BELGIE("5010", "België"), BOTSWANA("5011", "Botswana"), IRAN("5012", "Iran"), NIEUWZEELAND("5013", "Nieuw-Zeeland"), @@ -50,9 +73,9 @@ enum class Landcode( DENEMARKEN("5015", "Denemarken"), NOORDJEMEN("5016", "Noord-Jemen"), HONGARIJE("5017", "Hongarije"), - SAOEDIARABIË("5018", "Saoedi-Arabië"), + SAOEDIARABIE("5018", "Saoedi-Arabië"), LIBERIA("5019", "Liberia"), - ETHIOPIË("5020", "Ethiopië"), + ETHIOPIE("5020", "Ethiopië"), CHILI("5021", "Chili"), MAROKKO("5022", "Marokko"), TOGO("5023", "Togo"), @@ -66,7 +89,7 @@ enum class Landcode( BURMA("5031", "Burma"), MONACO("5032", "Monaco"), COLOMBIA("5033", "Colombia"), - ALBANIË("5034", "Albanië"), + ALBANIE("5034", "Albanië"), KAMEROEN("5035", "Kameroen"), ZUIDVIETNAM("5036", "Zuid-Vietnam"), SINGAPORE("5037", "Singapore"), @@ -81,12 +104,12 @@ enum class Landcode( KASHMIR("5046", "Kashmir"), MYANMAR("5047", "Myanmar"), JEMEN("5048", "Jemen"), - SLOVENIË("5049", "Slovenië"), - ZAÏRE("5050", "Zaïre"), - KROATIË("5051", "Kroatië"), + SLOVENIE("5049", "Slovenië"), + ZAIRE("5050", "Zaïre"), + KROATIE("5051", "Kroatië"), TAIWAN("5052", "Taiwan"), RUSLAND("5053", "Rusland"), - ARMENIË("5054", "Armenië"), + ARMENIE("5054", "Armenië"), ASCENSION("5055", "Ascension"), AZOREN("5056", "Azoren"), BAHREIN("5057", "Bahrein"), @@ -105,13 +128,13 @@ enum class Landcode( MOZAMBIQUE("5070", "Mozambique"), PITCAIRNEILANDEN("5071", "Pitcairneilanden"), GUINEEBISSAU("5072", "Guinee-Bissau"), - RÉUNION("5073", "Réunion"), + REUNION("5073", "Réunion"), SAINT_PIERRE_EN_MIQUELON("5074", "Saint Pierre en Miquelon"), SEYCHELLEN_EN_AMIRANTEN("5075", "Seychellen en Amiranten"), TONGA("5076", "Tonga"), WALLIS_EN_FUTUNA("5077", "Wallis en Futuna"), ZUIDWESTAFRIKA("5078", "Zuidwest-Afrika"), - FRANSINDIË("5079", "Frans-Indië"), + FRANSINDIE("5079", "Frans-Indië"), JOHNSTON("5080", "Johnston"), KEDAH("5081", "Kedah"), KELANTAN("5082", "Kelantan"), @@ -121,7 +144,7 @@ enum class Landcode( PAHANG("5086", "Pahang"), PERAK("5087", "Perak"), PERLIS("5088", "Perlis"), - PORTUGEESINDIË("5089", "Portugees-Indië"), + PORTUGEESINDIE("5089", "Portugees-Indië"), SELANGOR("5090", "Selangor"), SIKKIM("5091", "Sikkim"), SAINT_VINCENT_EN_DE_GRENADINES("5092", "Saint Vincent en de Grenadines"), @@ -132,45 +155,45 @@ enum class Landcode( AZERBEIDZJAN("5097", "Azerbeidzjan"), BELARUS("5098", "Belarus"), KAZACHSTAN("5099", "Kazachstan"), - MACEDONIË("5100", "Macedonië"), + MACEDONIE("5100", "Macedonië"), TIMOR_LESTE("5101", "Timor Leste"), - SERVIË_EN_MONTENEGRO("5102", "Servië en Montenegro"), - SERVIË("5103", "Servië"), + SERVIE_EN_MONTENEGRO("5102", "Servië en Montenegro"), + SERVIE("5103", "Servië"), MONTENEGRO("5104", "Montenegro"), KOSOVO("5105", "Kosovo"), BONAIRE("5106", "Bonaire"), - CURAÇAO("5107", "Curaçao"), + CURACAO("5107", "Curaçao"), SABA("5108", "Saba"), SINT_EUSTATIUS("5109", "Sint Eustatius"), SINT_MAARTEN("5110", "Sint Maarten"), ZUIDSOEDAN("5111", "Zuid-Soedan"), GAZASTROOK_EN_WESTELIJKE_JORDAANOEVER("5112", "Gazastrook en Westelijke Jordaanoever"), - REPUBLIEK_NOORDMACEDONIË("5113", "Republiek Noord-Macedonië"), - MOLDAVIË("6000", "Moldavië"), + REPUBLIEK_NOORDMACEDONIE("5113", "Republiek Noord-Macedonië"), + MOLDAVIE("6000", "Moldavië"), BURUNDI("6001", "Burundi"), FINLAND("6002", "Finland"), GRIEKENLAND("6003", "Griekenland"), GUATEMALA("6004", "Guatemala"), NIGERIA("6005", "Nigeria"), - LIBIË("6006", "Libië"), + LIBIE("6006", "Libië"), IERLAND("6007", "Ierland"), - BRAZILIË("6008", "Brazilië"), + BRAZILIE("6008", "Brazilië"), RWANDA("6009", "Rwanda"), VENEZUELA("6010", "Venezuela"), IJSLAND("6011", "IJsland"), LIECHTENSTEIN("6012", "Liechtenstein"), - SOMALIË("6013", "Somalië"), + SOMALIE("6013", "Somalië"), VERENIGDE_STATEN_VAN_AMERIKA("6014", "Verenigde Staten van Amerika"), BOLIVIA("6015", "Bolivia"), - AUSTRALIË("6016", "Australië"), + AUSTRALIE("6016", "Australië"), JAMAICA("6017", "Jamaica"), LUXEMBURG("6018", "Luxemburg"), TSJAAD("6019", "Tsjaad"), - MAURITANIË("6020", "Mauritanië"), - KIRGIZIË("6021", "Kirgizië"), + MAURITANIE("6020", "Mauritanië"), + KIRGIZIE("6021", "Kirgizië"), CHINA("6022", "China"), AFGHANISTAN("6023", "Afghanistan"), - INDONESIË("6024", "Indonesië"), + INDONESIE("6024", "Indonesië"), GUYANA("6025", "Guyana"), NOORDVIETNAM("6026", "Noord-Vietnam"), NOORWEGEN("6027", "Noorwegen"), @@ -180,18 +203,18 @@ enum class Landcode( CAMBODJA("6031", "Cambodja"), FIJI("6032", "Fiji"), BAHAMAS("6033", "Bahama's"), - ISRAËL("6034", "Israël"), + ISRAEL("6034", "Israël"), NEPAL("6035", "Nepal"), ZUIDKOREA("6036", "Zuid-Korea"), SPANJE("6037", "Spanje"), - OEKRAÏNE("6038", "Oekraïne"), + OEKRAINE("6038", "Oekraïne"), VERENIGD_KONINKRIJK("6039", "Verenigd Koninkrijk"), NIGER("6040", "Niger"), - HAÏTI("6041", "Haïti"), - JORDANIË("6042", "Jordanië"), + HAITI("6041", "Haïti"), + JORDANIE("6042", "Jordanië"), TURKIJE("6043", "Turkije"), TRINIDAD_EN_TOBAGO("6044", "Trinidad en Tobago"), - JOEGOSLAVIË("6045", "Joegoslavië"), + JOEGOSLAVIE("6045", "Joegoslavië"), OPPERVOLTA("6046", "Opper-Volta"), ALGERIJE("6047", "Algerije"), GABON("6048", "Gabon"), @@ -200,21 +223,21 @@ enum class Landcode( SIERRA_LEONE("6051", "Sierra Leone"), BRITSHONDURAS("6052", "Brits-Honduras"), CANARISCHE_EILANDEN("6053", "Canarische Eilanden"), - FRANSPOLYNESIË("6054", "Frans-Polynesië"), + FRANSPOLYNESIE("6054", "Frans-Polynesië"), GIBRALTAR("6055", "Gibraltar"), PORTUGEESTIMOR("6056", "Portugees-Timor"), TADZJIKISTAN("6057", "Tadzjikistan"), BRITSE_SALOMONSEILANDEN("6058", "Britse Salomonseilanden"), - SÃO_TOMÉ_EN_PRINCIPE("6059", "São Tomé en Principe"), + SAO_TOME_EN_PRINCIPE("6059", "São Tomé en Principe"), SINTHELENA("6060", "Sint-Helena"), TRISTAN_DA_CUNHA("6061", "Tristan Da Cunha"), WESTSAMOA("6062", "West-Samoa"), TURKMENISTAN("6063", "Turkmenistan"), - GEORGIË("6064", "Georgië"), - BOSNIËHERZEGOVINA("6065", "Bosnië-Herzegovina"), - TSJECHIË("6066", "Tsjechië"), + GEORGIE("6064", "Georgië"), + BOSNIEHERZEGOVINA("6065", "Bosnië-Herzegovina"), + TSJECHIE("6066", "Tsjechië"), SLOWAKIJE("6067", "Slowakije"), - FEDERALE_REPUBLIEK_JOEGOSLAVIË("6068", "Federale Republiek Joegoslavië"), + FEDERALE_REPUBLIEK_JOEGOSLAVIE("6068", "Federale Republiek Joegoslavië"), DEMOCRATISCHE_REPUBLIEK_CONGO("6069", "Democratische Republiek Congo"), UGANDA("7001", "Uganda"), KENYA("7002", "Kenya"), @@ -224,11 +247,11 @@ enum class Landcode( MEXICO("7006", "Mexico"), COSTA_RICA("7007", "Costa Rica"), GAMBIA("7008", "Gambia"), - SYRIË("7009", "Syrië"), + SYRIE("7009", "Syrië"), NEDERLANDSE_ANTILLEN("7011", "Nederlandse Antillen"), ZUIDJEMEN("7012", "Zuid-Jemen"), EGYPTE("7014", "Egypte"), - ARGENTINIË("7015", "Argentinië"), + ARGENTINIE("7015", "Argentinië"), LESOTHO("7016", "Lesotho"), HONDURAS("7017", "Honduras"), NICARAGUA("7018", "Nicaragua"), @@ -236,7 +259,7 @@ enum class Landcode( SENEGAL("7021", "Senegal"), DAHOMEY("7023", "Dahomey"), BULGARIJE("7024", "Bulgarije"), - MALEISIË("7026", "Maleisië"), + MALEISIE("7026", "Maleisië"), DOMINICAANSE_REPUBLIEK("7027", "Dominicaanse Republiek"), POLEN("7028", "Polen"), RUSLAND_OUD("7029", "Rusland (oud)"), @@ -254,15 +277,15 @@ enum class Landcode( MALDIVEN("7041", "Maldiven"), THAILAND("7042", "Thailand"), LIBANON("7043", "Libanon"), - ITALIË("7044", "Italië"), + ITALIE("7044", "Italië"), KOEWEIT("7045", "Koeweit"), INDIA("7046", "India"), - ROEMENIË("7047", "Roemenië"), + ROEMENIE("7047", "Roemenië"), TSJECHOSLOWAKIJE("7048", "Tsjecho-Slowakije"), PERU("7049", "Peru"), PORTUGAL("7050", "Portugal"), OMAN("7051", "Oman"), - MONGOLIË("7052", "Mongolië"), + MONGOLIE("7052", "Mongolië"), SAMOA("7053", "Samoa"), VERENIGDE_ARABISCHE_EMIRATEN("7054", "Verenigde Arabische Emiraten"), TIBET("7055", "Tibet"), @@ -270,16 +293,16 @@ enum class Landcode( NEDERLANDS_NIEUWGUINEA("7058", "Nederlands Nieuw-Guinea"), TANGANYIKA("7059", "Tanganyika"), PALESTINA("7060", "Palestina"), - BRITS_WESTINDIË("7062", "Brits West-Indië"), + BRITS_WESTINDIE("7062", "Brits West-Indië"), PORTUGEESAFRIKA("7063", "Portugees-Afrika"), LETLAND("7064", "Letland"), ESTLAND("7065", "Estland"), LITOUWEN("7066", "Litouwen"), BRITSAFRIKA("7067", "Brits-Afrika"), BELGISCHCONGO("7068", "Belgisch-Congo"), - BRITSINDIË("7070", "Brits-Indië"), - NOORDRHODESIË("7071", "Noord-Rhodesië"), - ZUIDRHODESIË("7072", "Zuid-Rhodesië"), + BRITSINDIE("7070", "Brits-Indië"), + NOORDRHODESIE("7071", "Noord-Rhodesië"), + ZUIDRHODESIE("7072", "Zuid-Rhodesië"), SAARLAND("7073", "Saarland"), FRANS_INDOCHINA("7074", "Frans Indochina"), BRITS_WESTBORNEO("7075", "Brits West-Borneo"), @@ -302,7 +325,7 @@ enum class Landcode( BRITS_INDISCHE_OCEAANTERRITORIUM("7096", "Brits Indische Oceaanterritorium"), COOKEILANDEN("7097", "Cookeilanden"), TOKELAU("7098", "Tokelau"), - NIEUWCALEDONIË("7099", "Nieuw-Caledonië"), + NIEUWCALEDONIE("7099", "Nieuw-Caledonië"), HAWAIIEILANDEN("8000", "Hawaii-eilanden"), GUAM("8001", "Guam"), AMERIKAANSSAMOA("8002", "Amerikaans-Samoa"), @@ -316,18 +339,18 @@ enum class Landcode( CANTON_EN_ENDERBURY("8011", "Canton en Enderbury"), CHRISTMASEILAND("8012", "Christmaseiland"), COCOSEILANDEN("8013", "Cocoseilanden"), - FAERÖER("8014", "Faeröer"), + FAEROER("8014", "Faeröer"), MONTSERRAT("8015", "Montserrat"), NORFOLK("8016", "Norfolk"), BELIZE("8017", "Belize"), - TASMANIË("8018", "Tasmanië"), + TASMANIE("8018", "Tasmanië"), TURKS_EN_CAICOSEILANDEN("8019", "Turks- en Caicoseilanden"), PUERTO_RICO("8020", "Puerto Rico"), PAPOEANIEUWGUINEA("8021", "Papoea-Nieuw-Guinea"), SALOMONSEILANDEN("8022", "Salomonseilanden"), BENIN("8023", "Benin"), VIETNAM("8024", "Vietnam"), - KAAPVERDIË("8025", "Kaapverdië"), + KAAPVERDIE("8025", "Kaapverdië"), SEYCHELLEN("8026", "Seychellen"), KIRIBATI("8027", "Kiribati"), TUVALU("8028", "Tuvalu"), @@ -364,10 +387,10 @@ enum class Landcode( PHOENIXEILANDEN("9017", "Phoenixeilanden"), PORTUGEESGUINEE("9020", "Portugees-Guinee"), DUITS_ZUIDWESTAFRIKA("9022", "Duits Zuidwest-Afrika"), - NAMIBIË("9023", "Namibië"), + NAMIBIE("9023", "Namibië"), BRITSSOMALILAND("9027", "Brits-Somaliland"), ITALIAANSSOMALILAND("9028", "Italiaans-Somaliland"), - NEDERLANDSINDIË("9030", "Nederlands-Indië"), + NEDERLANDSINDIE("9030", "Nederlands-Indië"), BRITSGUYANA("9031", "Brits-Guyana"), SWAZILAND("9036", "Swaziland"), QATAR("9037", "Qatar"), @@ -404,7 +427,7 @@ enum class Landcode( PORTUGEES_WESTAFRIKA("9073", "Portugees West-Afrika"), SHARJAH("9074", "Sharjah"), STRAITS_SETTLEMENTS("9075", "Straits Settlements"), - ABESSINIË("9076", "Abessinië"), + ABESSINIE("9076", "Abessinië"), FRANS_WESTAFRIKA("9077", "Frans West-Afrika"), FRANS_EQUATORIAALAFRIKA("9078", "Frans Equatoriaal-Afrika"), URUNDI("9081", "Urundi"), @@ -413,7 +436,7 @@ enum class Landcode( DANTZIG("9085", "Dantzig"), CENTRAALAFRIKAANSE_REPUBLIEK("9086", "Centraal-Afrikaanse Republiek"), DJIBOUTI("9087", "Djibouti"), - TRANSJORDANIË("9088", "Transjordanië"), + TRANSJORDANIE("9088", "Transjordanië"), BONDSREPUBLIEK_DUITSLAND("9089", "Bondsrepubliek Duitsland"), VANUATU("9090", "Vanuatu"), NIUE("9091", "Niue"), @@ -422,6 +445,7 @@ enum class Landcode( MICRONESIA("9094", "Micronesia"), SVALBARDEILANDEN("9095", "Svalbardeilanden"), INTERNATIONAAL_GEBIED("9999", "Internationaal gebied"), + NULL("", "Null"), ; override fun toString(): String { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt new file mode 100644 index 00000000..36e33741 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.server.operations.Mutation +import com.fasterxml.jackson.databind.node.ObjectNode +import graphql.GraphQLException +import graphql.schema.DataFetchingEnvironment +import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY +import nl.nlportal.openklant.domain.CreatePartij +import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.service.OpenKlant2Service + +class PartijMutation( + private val openklant2Service: OpenKlant2Service +) : Mutation { + @GraphQLDescription("Create Partij for user") + suspend fun createPartij( + dfe: DataFetchingEnvironment, + createPartijPayload: ObjectNode, + ): Partij? { + return openklant2Service.createPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY), createPartijPayload) + } + + @GraphQLDescription("Update user Partij") + suspend fun updatePartij( + dfe: DataFetchingEnvironment, + partijPayload: ObjectNode, + ): Partij { + return openklant2Service.updatePartij(dfe.graphQlContext.get(AUTHENTICATION_KEY), partijPayload) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt index dbc21daf..96402482 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt @@ -17,14 +17,17 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.server.operations.Query +import graphql.GraphQLException import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY import nl.nlportal.openklant.domain.Partij import nl.nlportal.openklant.service.OpenKlant2Service -class PartijQuery(private val openklant2Service: OpenKlant2Service): Query { +class PartijQuery( + private val openklant2Service: OpenKlant2Service, +) : Query { @GraphQLDescription("Get user Partij") suspend fun getPartij(dfe: DataFetchingEnvironment): Partij? { - return openklant2Service.getPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY)) + return openklant2Service.findPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY)) } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index b982a6da..d8e63188 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -15,18 +15,59 @@ */ package nl.nlportal.openklant.service +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.module.kotlin.convertValue +import mu.KotlinLogging import nl.nlportal.commonground.authentication.CommonGroundAuthentication +import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.path.Partijen import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.domain.asSoortPartij +import org.springframework.util.MultiValueMapAdapter +import org.springframework.web.reactive.function.client.WebClientResponseException class OpenKlant2Service( - private val enabled: Boolean = false, - private val openKlant2Client: OpenKlant2Client + private val openKlant2Client: OpenKlant2Client, ) { + suspend fun findPartij(authentication: CommonGroundAuthentication): Partij? { + val searchVariables = + MultiValueMapAdapter( + mapOf( + "soortPartij" to listOf(authentication.asSoortPartij()), + "partijIdentificator__objectId" to listOf(authentication.userId), + ), + ) - suspend fun getPartij(authentication: CommonGroundAuthentication): Partij? { - if (!enabled) return null + try { + return openKlant2Client.path().find(searchVariables) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to find Partij: ${ex.responseBodyAsString}", ex) + return null + } + } + + suspend fun createPartij( + authentication: CommonGroundAuthentication, + partij: ObjectNode, + ): Partij? { + try { + return openKlant2Client.path().create(objectMapper.convertValue(partij)) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to create Partij: ${ex.responseBodyAsString}", ex) + return null + } + } + + suspend fun updatePartij( + authentication: CommonGroundAuthentication, + partij: ObjectNode, + ): Partij { + return objectMapper.convertValue(partij) + } - return openKlant2Client.findPartij(authentication) + companion object { + private val objectMapper = Mapper.get() + private val logger = KotlinLogging.logger {} } } \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt index 302a3f67..b008528b 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt @@ -15,6 +15,7 @@ */ package nl.nlportal.openklant +import com.expediagroup.graphql.server.operations.Query import nl.nlportal.core.security.OauthSecurityAutoConfiguration import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication @@ -41,4 +42,15 @@ class TestApplication { } .build() } + + @Bean + fun testQuery(): Query { + return TestQuery() + } + + class TestQuery: Query { + fun runTest(): String { + return "Test" + } + } } \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt index db3c9f29..c11bbf53 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt @@ -15,15 +15,248 @@ */ package nl.nlportal.openklant -import okhttp3.mockwebserver.MockResponse - object TestHelper { - fun mockResponseFromFile(fileName: String): MockResponse { - return MockResponse() - .addHeader("Content-Type", "application/json; charset=utf-8") - .setResponseCode(200) - .setBody(readFileAsString(fileName)) - } + object Partijen { + val createPartijRequest = + """ + { + "digitaleAdressen": null, + "voorkeursDigitaalAdres": null, + "vertegenwoordigden": null, + "rekeningnummers": null, + "voorkeursRekeningnummer": null, + "partijIdentificatoren": null, + "soortPartij": "persoon", + "indicatieGeheimhouding": true, + "indicatieActief": true, + "partijIdentificatie": { + "contactnaam": { + "voorletters": "A.", + "voornaam": "Anna", + "voorvoegselAchternaam": "", + "achternaam": "Vissart" + }, + "volledigeNaam": "Anna Vissart" + } + } + """.trimIndent() + val persoonPartijResponse = + """ + { + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "uuid": "9f8e8009-2d1c-40ae-931e-c08861ba7207", + "url": "http://localhost:8007/klantinteracties/api/v1/partijen/9f8e8009-2d1c-40ae-931e-c08861ba7207", + "nummer": "0000000001", + "interneNotitie": "", + "betrokkenen": [ + { + "uuid": "d5de314b-58a4-4d02-9d66-4e68e8927a90", + "url": "http://localhost:8007/klantinteracties/api/v1/betrokkenen/d5de314b-58a4-4d02-9d66-4e68e8927a90" + } + ], + "categorieRelaties": [], + "digitaleAdressen": [ + { + "uuid": "1300d2ab-13cb-4c12-9818-3b76e2a5d993", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/1300d2ab-13cb-4c12-9818-3b76e2a5d993" + }, + { + "uuid": "2596d218-05fa-4d8f-ab29-8a5c3029dcf2", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/2596d218-05fa-4d8f-ab29-8a5c3029dcf2" + } + ], + "voorkeursDigitaalAdres": { + "uuid": "1300d2ab-13cb-4c12-9818-3b76e2a5d993", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/1300d2ab-13cb-4c12-9818-3b76e2a5d993" + }, + "vertegenwoordigden": [], + "rekeningnummers": [], + "voorkeursRekeningnummer": null, + "partijIdentificatoren": [ + { + "uuid": "dd328a2e-7b8e-4809-be28-f9f894c11c34", + "url": "http://localhost:8007/klantinteracties/api/v1/partij-identificatoren/dd328a2e-7b8e-4809-be28-f9f894c11c34" + } + ], + "soortPartij": "persoon", + "indicatieGeheimhouding": true, + "voorkeurstaal": "nld", + "indicatieActief": true, + "bezoekadres": { + "nummeraanduidingId": "", + "adresregel1": "", + "adresregel2": "", + "adresregel3": "", + "land": "" + }, + "correspondentieadres": { + "nummeraanduidingId": "", + "adresregel1": "", + "adresregel2": "", + "adresregel3": "", + "land": "" + }, + "partijIdentificatie": { + "contactnaam": { + "voorletters": "L.", + "voornaam": "Lucas", + "voorvoegselAchternaam": "", + "achternaam": "Boom" + }, + "volledigeNaam": "Lucas Boom" + }, + "_expand": { + "betrokkenen": [ + { + "uuid": "d5de314b-58a4-4d02-9d66-4e68e8927a90", + "url": "http://localhost:8007/klantinteracties/api/v1/betrokkenen/d5de314b-58a4-4d02-9d66-4e68e8927a90", + "wasPartij": { + "uuid": "9f8e8009-2d1c-40ae-931e-c08861ba7207", + "url": "http://localhost:8007/klantinteracties/api/v1/partijen/9f8e8009-2d1c-40ae-931e-c08861ba7207" + }, + "hadKlantcontact": { + "uuid": "33549ba5-95f0-44d2-9c63-776ec126bc55", + "url": "http://localhost:8007/klantinteracties/api/v1/klantcontacten/33549ba5-95f0-44d2-9c63-776ec126bc55" + }, + "digitaleAdressen": [ + { + "uuid": "1300d2ab-13cb-4c12-9818-3b76e2a5d993", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/1300d2ab-13cb-4c12-9818-3b76e2a5d993" + }, + { + "uuid": "2596d218-05fa-4d8f-ab29-8a5c3029dcf2", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/2596d218-05fa-4d8f-ab29-8a5c3029dcf2" + } + ], + "bezoekadres": { + "nummeraanduidingId": "", + "adresregel1": "", + "adresregel2": "", + "adresregel3": "", + "land": "" + }, + "correspondentieadres": { + "nummeraanduidingId": "", + "adresregel1": "", + "adresregel2": "", + "adresregel3": "", + "land": "" + }, + "contactnaam": { + "voorletters": "L.", + "voornaam": "Lucas", + "voorvoegselAchternaam": "", + "achternaam": "Boom" + }, + "volledigeNaam": "Lucas Boom", + "rol": "klant", + "organisatienaam": "", + "initiator": true, + "_expand": { + "hadKlantcontact": { + "uuid": "33549ba5-95f0-44d2-9c63-776ec126bc55", + "url": "http://localhost:8007/klantinteracties/api/v1/klantcontacten/33549ba5-95f0-44d2-9c63-776ec126bc55", + "gingOverOnderwerpobjecten": [ + { + "uuid": "896821a7-0e35-45a8-84d1-0f4f033ee7c5", + "url": "http://localhost:8007/klantinteracties/api/v1/onderwerpobjecten/896821a7-0e35-45a8-84d1-0f4f033ee7c5" + } + ], + "hadBetrokkenActoren": [ + { + "uuid": "02d4cea3-ebf4-4826-956e-7a5ca1be85ca", + "url": "http://localhost:8007/klantinteracties/api/v1/actoren/02d4cea3-ebf4-4826-956e-7a5ca1be85ca", + "naam": "Jasmijn", + "soortActor": "medewerker", + "indicatieActief": true, + "actoridentificator": { + "objectId": "", + "codeObjecttype": "", + "codeRegister": "", + "codeSoortObjectId": "" + }, + "actorIdentificatie": { + "functie": "receptioniste", + "emailadres": "jasmijn@email.com", + "telefoonnummer": "693624816" + } + } + ], + "omvatteBijlagen": [], + "hadBetrokkenen": [ + { + "uuid": "d5de314b-58a4-4d02-9d66-4e68e8927a90", + "url": "http://localhost:8007/klantinteracties/api/v1/betrokkenen/d5de314b-58a4-4d02-9d66-4e68e8927a90" + } + ], + "leiddeTotInterneTaken": [ + { + "uuid": "58d26043-0cdc-4a46-9110-6acca6e200f2", + "url": "http://localhost:8007/klantinteracties/api/v1/internetaken/58d26043-0cdc-4a46-9110-6acca6e200f2" + } + ], + "nummer": "0000000001", + "kanaal": "E-mail", + "onderwerp": "Vraag over vergunningsaanvraag", + "inhoud": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras ut aliquam velit. Vestibulum tempus purus vitae vehicula blandit. Aliquam erat volutpat. Suspendisse potenti. Maecenas ultrices condimentum lorem, sit amet aliquet sem sagittis at. Aenean lorem neque, tincidunt at ultrices ut, condimentum sed dui. Quisque sagittis eros eget sapien tempor lobortis. Aliquam magna nisi, ultrices vitae condimentum quis, ullamcorper luctus nulla. Proin condimentum diam lobortis lacinia accumsan. Etiam gravida neque quis lectus facilisis eleifend. Proin finibus non sapien a feugiat. Vestibulum consequat felis vitae felis aliquam faucibus. Morbi pellentesque quam velit, sed interdum quam cursus sed. Curabitur suscipit nunc eu cursus cursus. Etiam suscipit massa vel mauris tristique, non tristique tortor eleifend.", + "indicatieContactGelukt": true, + "taal": "nld", + "vertrouwelijk": true, + "plaatsgevondenOp": "2024-03-06T11:02:24Z" + } + } + } + ], + "digitaleAdressen": [ + { + "uuid": "1300d2ab-13cb-4c12-9818-3b76e2a5d993", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/1300d2ab-13cb-4c12-9818-3b76e2a5d993", + "verstrektDoorBetrokkene": { + "uuid": "d5de314b-58a4-4d02-9d66-4e68e8927a90", + "url": "http://localhost:8007/klantinteracties/api/v1/betrokkenen/d5de314b-58a4-4d02-9d66-4e68e8927a90" + }, + "verstrektDoorPartij": { + "uuid": "9f8e8009-2d1c-40ae-931e-c08861ba7207", + "url": "http://localhost:8007/klantinteracties/api/v1/partijen/9f8e8009-2d1c-40ae-931e-c08861ba7207" + }, + "adres": "lucas@boom.nl", + "soortDigitaalAdres": "Email", + "omschrijving": "Persoonlijke email adres" + }, + { + "uuid": "2596d218-05fa-4d8f-ab29-8a5c3029dcf2", + "url": "http://localhost:8007/klantinteracties/api/v1/digitaleadressen/2596d218-05fa-4d8f-ab29-8a5c3029dcf2", + "verstrektDoorBetrokkene": { + "uuid": "d5de314b-58a4-4d02-9d66-4e68e8927a90", + "url": "http://localhost:8007/klantinteracties/api/v1/betrokkenen/d5de314b-58a4-4d02-9d66-4e68e8927a90" + }, + "verstrektDoorPartij": { + "uuid": "9f8e8009-2d1c-40ae-931e-c08861ba7207", + "url": "http://localhost:8007/klantinteracties/api/v1/partijen/9f8e8009-2d1c-40ae-931e-c08861ba7207" + }, + "adres": "0611111111", + "soortDigitaalAdres": "Telefoon", + "omschrijving": "Telefoonnummer van de klant" + } + ] + } + } + ] + } + """.trimIndent() - private fun readFileAsString(fileName: String): String = this::class.java.getResource(fileName).readText(Charsets.UTF_8) + val emptyPage = + """ + { + "count": 0, + "next": null, + "previous": null, + "results": [] + } + """.trimIndent() + } } \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt new file mode 100644 index 00000000..60c8d23a --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client + +import kotlinx.coroutines.test.runTest +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.web.reactive.function.client.awaitBodilessEntity + +class OpenKlantClientTest { + private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration + private lateinit var mockServer: MockWebServer + private lateinit var openKlant2Client: OpenKlant2Client + private lateinit var hostUrl: String + private lateinit var apiUrl: String + + @BeforeEach + fun setUp() { + mockServer = MockWebServer() + mockServer.start() + + hostUrl = "http://${mockServer.hostName}:${mockServer.port}/" + apiUrl = "http://${mockServer.hostName}:${mockServer.port}/myapi/v1" + openklantModuleConfiguration = + OpenKlantModuleConfiguration( + enabled = true, + properties = + OpenKlantConfigurationProperties( + url = mockServer.url("/myapi/v1").toUri(), + token = "SuperSecretToken1234", + ), + ) + openKlant2Client = OpenKlant2Client(openklantModuleConfiguration.properties) + } + + @AfterEach + internal fun tearDown() { + mockServer.shutdown() + } + + @Test + fun `should provide configured webclient`() = + runTest { + // when + mockServer.enqueue(MockResponse().setResponseCode(200)) + + // given + openKlant2Client.webClient().get().uri("mypath").retrieve().awaitBodilessEntity() + val request = mockServer.takeRequest() + + // then + assertEquals("${apiUrl}mypath", request.requestUrl.toString()) + assertEquals("Token SuperSecretToken1234", request.getHeader("Authorization")) + assertEquals("EPSG:4326", request.getHeader("Accept-Crs")) + assertEquals("EPSG:4326", request.getHeader("Content-Crs")) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt new file mode 100644 index 00000000..5f4a5240 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.configuration + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.NullNode +import com.fasterxml.jackson.module.kotlin.readValue +import kotlinx.coroutines.test.runTest +import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.core.io.ClassPathResource +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.web.reactive.function.BodyInserters +import java.nio.charset.Charset + +@SpringBootTest +@AutoConfigureWebTestClient(timeout = "36000") +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +@ActiveProfiles("openklant-disabled") +class ModuleConfigurationIT( + @Autowired private val webTestClient: WebTestClient, + @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, +) { + @Test + fun `should not expose Partij type when module is disabled`() = runTest { + // when + val responseBodyContent = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val typeResponse = + objectMapper + .readValue(responseBodyContent!!) + .get("data") + ?.get("__type") + + // then + assertFalse(openKlantModuleConfiguration.enabled) + assertTrue(typeResponse is NullNode) + } + + companion object { + private val objectMapper = Mapper.get() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt new file mode 100644 index 00000000..195fa919 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.module.kotlin.readValue +import com.fasterxml.jackson.module.kotlin.treeToValue +import kotlinx.coroutines.test.runTest +import nl.nlportal.commonground.authentication.WithBurgerUser +import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.TestHelper +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration +import nl.nlportal.openklant.domain.CreatePartij.PersoonsIdentificatie +import nl.nlportal.openklant.domain.SoortPartij +import nl.nlportal.openklant.service.OpenKlant2Service +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.assertDoesNotThrow +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.mock.mockito.SpyBean +import org.springframework.core.io.ClassPathResource +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.web.reactive.function.BodyInserters +import java.nio.charset.Charset + +@SpringBootTest +@AutoConfigureWebTestClient(timeout = "36000") +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +class PartijQueryIT( + @Autowired private val webTestClient: WebTestClient, + @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, +) { + @SpyBean + lateinit var openKlant2Service: OpenKlant2Service + + lateinit var mockOpenKlant: MockWebServer + + @BeforeEach + fun setUp() { + mockOpenKlant = MockWebServer() + mockOpenKlant.start() + openKlantModuleConfiguration.properties.url = mockOpenKlant.url("/").toUri() + } + + @AfterEach + internal fun tearDown() { + mockOpenKlant.shutdown() + } + + @Test + fun `should introspect Partij type`() = runTest { + // when + val responseBodyContent = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val typeResponse = + objectMapper + .readValue(responseBodyContent!!) + .get("data") + ?.get("__type") + + // then + assertEquals("OBJECT", typeResponse?.get("kind")?.textValue()) + assertEquals("Partij", typeResponse?.get("name")?.textValue()) + assertEquals("A Type that represents a Klantinteracties API Partij object", typeResponse?.get("description")?.textValue()) + } + + @Test + @WithBurgerUser("999990755") + fun `should return Partij for authenticated user`() = + runTest { + // given + val partijenResponse = + MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json") + .setBody(TestHelper.Partijen.persoonPartijResponse) + + with(mockOpenKlant) { + enqueue(partijenResponse) + } + + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getPartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val responsePartij = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("getPartij") + + val recordedRequest = mockOpenKlant.takeRequest() + + // then + verify(openKlant2Service, times(1)).findPartij(any()) + + assertTrue(recordedRequest.requestUrl.toString().contains("999990755")) + assertTrue(recordedRequest.requestUrl.toString().contains("persoon")) + assertNotNull(responsePartij) + assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) + assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } + assertEquals("Lucas Boom", responsePartij?.requiredAt("/partijIdentificatie/volledigeNaam")?.textValue()) + } + + @Test + @WithBurgerUser("111111110") + fun `should return null when no Partij was found for authenticated user`() = + runTest { + // given + val partijenResponse = + MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json") + .setBody(TestHelper.Partijen.emptyPage) + + with(mockOpenKlant) { + enqueue(partijenResponse) + } + + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getPartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val responsePartij = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("getPartij") + + val recordedRequest = mockOpenKlant.takeRequest() + + // then + verify(openKlant2Service, times(1)).findPartij(any()) + + assertTrue(recordedRequest.requestUrl.toString().contains("111111110")) + assertTrue(recordedRequest.requestUrl.toString().contains("persoon")) + assertTrue(responsePartij!!.isNull) + } + + companion object { + private val objectMapper = Mapper.get() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/application.yml b/zgw/openklant/src/test/resources/config/application.yml index a7c28a99..69fcb666 100644 --- a/zgw/openklant/src/test/resources/config/application.yml +++ b/zgw/openklant/src/test/resources/config/application.yml @@ -3,14 +3,43 @@ graphql: - "nl.nlportal" nl-portal: - openklant: - url: #filled in test - clientId: valtimo_client - secret: e09b8bc5-5831-4618-ab28-41411304309d + config: + openklant: + enabled: true + properties: + url: http://localhost:8007 + token: ac045222c9e7cde8120b48735560f9b920bb58cd spring: security: oauth2: resourceserver: jwt: - issuer-uri: http://localhost:8082/auth/realms/nlportal \ No newline at end of file + issuer-uri: http://localhost:8082/auth/realms/nlportal + +--- + +spring: + config: + activate: + on-profile: openklant-disabled + +nl-portal: + config: + openklant: + enabled: false + +--- + +spring: + config: + activate: + on-profile: openklant-misconfigured + +nl-portal: + config: + openklant: + enabled: true + properties: + url: + token: \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/getPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/getPartij.graphql new file mode 100644 index 00000000..34c0c9e7 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/getPartij.graphql @@ -0,0 +1,89 @@ +query { + getPartij { + betrokkenen { + uuid + url + } + bezoekadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + categorieRelaties { + beginDatum + categorieNaam + eindDatum + url + uuid + } + correspondentieadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + digitaleAdressen { + uuid + url + } + indicatieActief + indicatieGeheimhouding + interneNotitie + nummer + partijIdentificatoren { + uuid + url + } + rekeningnummers { + uuid + url + } + soortPartij + url + uuid + vertegenwoordigden { + uuid + url + } + voorkeursDigitaalAdres { + uuid + url + } + voorkeursRekeningnummer { + uuid + url + } + voorkeurstaal + partijIdentificatie { + ... on PersoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on ContactpersoonIdentificatie { + uuid + werkteVoorPartij { + uuid + url + } + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on OrganisatieIdentificatie { + naam + } + } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql b/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql new file mode 100644 index 00000000..50ddefb7 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql @@ -0,0 +1,7 @@ +query { + __type(name: "Partij") { + kind + name + description + } +} \ No newline at end of file From 5df964ead79592254a0300d04796919dc12dc645 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Sat, 28 Sep 2024 15:26:26 +0200 Subject: [PATCH 04/19] wip --- .../OpenKlantAutoConfiguration.kt | 8 +-- .../nl/nlportal/openklant/domain/Actoren.kt | 4 +- .../openklant/graphql/PartijMutation.kt | 4 +- .../nlportal/openklant/graphql/PartijQuery.kt | 1 - .../nl/nlportal/openklant/TestApplication.kt | 2 +- .../configuration/ModuleConfigurationIT.kt | 55 +++++++++-------- .../openklant/graphql/PartijQueryIT.kt | 61 ++++++++++--------- 7 files changed, 65 insertions(+), 70 deletions(-) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index 727cd5e4..b0b7ca5b 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -46,18 +46,14 @@ class OpenKlantAutoConfiguration { @Bean @ConditionalOnMissingBean(PartijQuery::class) @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun partijQuery( - openKlant2Service: OpenKlant2Service, - ): Query { + fun partijQuery(openKlant2Service: OpenKlant2Service): Query { return PartijQuery(openKlant2Service) } @Bean @ConditionalOnMissingBean(PartijMutation::class) @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun partijMutation( - openKlant2Service: OpenKlant2Service, - ): Mutation { + fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { return PartijMutation(openKlant2Service) } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt index 8e5fcf14..7ef42839 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt @@ -28,7 +28,7 @@ data class Actor( val naam: String, val soortActor: SoortActor, val indicatieActief: Boolean? = null, - val actoridentificator: Identificator? = null, + val actoridentificator: OpenKlant2Identificator? = null, ) @JsonIgnoreProperties(ignoreUnknown = true) @@ -50,7 +50,7 @@ data class PatchActor( val name: String? = null, val soortActor: SoortActor, val indicatieActief: Boolean? = null, - val actoridentificator: Identificator? = null, + val actoridentificator: OpenKlant2Identificator? = null, ) { init { require(name == null || name.length in 1..200) { "Actor name has to be between 1 and 200 characters long" } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index 36e33741..a1b70247 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -18,15 +18,13 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.server.operations.Mutation import com.fasterxml.jackson.databind.node.ObjectNode -import graphql.GraphQLException import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY -import nl.nlportal.openklant.domain.CreatePartij import nl.nlportal.openklant.domain.Partij import nl.nlportal.openklant.service.OpenKlant2Service class PartijMutation( - private val openklant2Service: OpenKlant2Service + private val openklant2Service: OpenKlant2Service, ) : Mutation { @GraphQLDescription("Create Partij for user") suspend fun createPartij( diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt index 96402482..ade6cbf3 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt @@ -17,7 +17,6 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.server.operations.Query -import graphql.GraphQLException import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY import nl.nlportal.openklant.domain.Partij diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt index b008528b..00135b7d 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt @@ -48,7 +48,7 @@ class TestApplication { return TestQuery() } - class TestQuery: Query { + class TestQuery : Query { fun runTest(): String { return "Test" } diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt index 5f4a5240..48761719 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt @@ -45,35 +45,36 @@ class ModuleConfigurationIT( @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, ) { @Test - fun `should not expose Partij type when module is disabled`() = runTest { - // when - val responseBodyContent = - webTestClient - .post() - .uri { builder -> - builder - .path("/graphql") - .build() - } - .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) - .exchange() - .expectStatus().isOk - .expectBody() - .returnResult() - .responseBodyContent - ?.toString(Charset.defaultCharset()) + fun `should not expose Partij type when module is disabled`() = + runTest { + // when + val responseBodyContent = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) - val typeResponse = - objectMapper - .readValue(responseBodyContent!!) - .get("data") - ?.get("__type") + val typeResponse = + objectMapper + .readValue(responseBodyContent!!) + .get("data") + ?.get("__type") - // then - assertFalse(openKlantModuleConfiguration.enabled) - assertTrue(typeResponse is NullNode) - } + // then + assertFalse(openKlantModuleConfiguration.enabled) + assertTrue(typeResponse is NullNode) + } companion object { private val objectMapper = Mapper.get() diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt index 195fa919..226e59b9 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt @@ -75,36 +75,37 @@ class PartijQueryIT( } @Test - fun `should introspect Partij type`() = runTest { - // when - val responseBodyContent = - webTestClient - .post() - .uri { builder -> - builder - .path("/graphql") - .build() - } - .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) - .exchange() - .expectStatus().isOk - .expectBody() - .returnResult() - .responseBodyContent - ?.toString(Charset.defaultCharset()) - - val typeResponse = - objectMapper - .readValue(responseBodyContent!!) - .get("data") - ?.get("__type") - - // then - assertEquals("OBJECT", typeResponse?.get("kind")?.textValue()) - assertEquals("Partij", typeResponse?.get("name")?.textValue()) - assertEquals("A Type that represents a Klantinteracties API Partij object", typeResponse?.get("description")?.textValue()) - } + fun `should introspect Partij type`() = + runTest { + // when + val responseBodyContent = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val typeResponse = + objectMapper + .readValue(responseBodyContent!!) + .get("data") + ?.get("__type") + + // then + assertEquals("OBJECT", typeResponse?.get("kind")?.textValue()) + assertEquals("Partij", typeResponse?.get("name")?.textValue()) + assertEquals("A Type that represents a Klantinteracties API Partij object", typeResponse?.get("description")?.textValue()) + } @Test @WithBurgerUser("999990755") From e75c011038c646874b0d9fdeb50cbd2cdb4b322d Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Thu, 3 Oct 2024 10:40:04 +0200 Subject: [PATCH 05/19] improve gradle setup so that docker compose can be used for integration testing on macOS --- build.gradle.kts | 16 +- case/build.gradle.kts | 11 +- .../imports/openklant-2/database/init.sh | 5 + .../database/sql/1-add-authtoken.sql | 1 + .../database/sql/fill-data-on-startup.sh | 20 +++ .../imports/openklant-2/init/init.sh | 21 +++ form/build.gradle.kts | 11 +- gradle.properties | 4 +- gradle/testing.gradle.kts | 30 ++++ zgw/openklant/build.gradle.kts | 11 +- zgw/openklant/docker-compose-override.yml | 43 +++++ .../OpenKlantAutoConfiguration.kt | 2 +- .../OpenKlantModuleConfiguration.kt | 2 +- .../openklant/client/OpenKlant2Client.kt | 2 +- .../openklant/{ => client}/domain/Actoren.kt | 35 +--- .../{ => client}/domain/Betrokkenen.kt | 6 +- .../{ => client}/domain/CategorieRelaties.kt | 4 +- .../{ => client}/domain/DigitaleAdressen.kt | 4 +- .../{ => client}/domain/KlantContacten.kt | 4 +- .../client/domain/PartijIdentificatoren.kt | 40 +++++ .../openklant/{ => client}/domain/Partijen.kt | 132 ++++++---------- .../{ => client}/domain/ResultPage.kt | 4 +- .../openklant/{ => client}/domain/Shared.kt | 29 +++- .../client/path/KlantInteractiesPath.kt | 2 +- .../client/path/PartijIdentificatoren.kt | 64 ++++++++ .../openklant/client/path/Partijen.kt | 57 +++++-- .../openklant/graphql/PartijMutation.kt | 24 +-- .../nlportal/openklant/graphql/PartijQuery.kt | 27 +++- .../openklant/graphql/domain/PartijRequest.kt | 59 +++++++ .../openklant/service/OpenKlant2Service.kt | 81 ++++++++-- ...ot.autoconfigure.AutoConfiguration.imports | 16 ++ .../nl/nlportal/openklant/TestApplication.kt | 2 +- .../nl/nlportal/openklant/TestHelper.kt | 2 +- .../openklant/client/OpenKlantClientTest.kt | 2 +- .../configuration/ModuleConfigurationIT.kt | 6 +- .../openklant/graphql/PartijMutationIT.kt | 99 ++++++++++++ .../openklant/graphql/PartijQueryIT.kt | 149 ++++++++++-------- .../service/OpenKlant2ServiceTest.kt | 55 +++++++ .../src/test/resources/config/application.yml | 2 +- .../config/graphql/createPartij.graphql | 121 ++++++++++++++ ...tPartij.graphql => findUserPartij.graphql} | 2 +- .../config/graphql/getUserPartij.graphql | 89 +++++++++++ .../graphql/partijTypeIntrospection.graphql | 2 +- 43 files changed, 1030 insertions(+), 268 deletions(-) create mode 100755 docker-resources/imports/openklant-2/database/init.sh create mode 100644 docker-resources/imports/openklant-2/database/sql/1-add-authtoken.sql create mode 100755 docker-resources/imports/openklant-2/database/sql/fill-data-on-startup.sh create mode 100755 docker-resources/imports/openklant-2/init/init.sh create mode 100644 gradle/testing.gradle.kts create mode 100644 zgw/openklant/docker-compose-override.yml rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/Actoren.kt (60%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/Betrokkenen.kt (90%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/CategorieRelaties.kt (92%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/DigitaleAdressen.kt (95%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/KlantContacten.kt (93%) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/Partijen.kt (57%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/ResultPage.kt (91%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/{ => client}/domain/Shared.kt (96%) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt create mode 100644 zgw/openklant/src/test/resources/config/graphql/createPartij.graphql rename zgw/openklant/src/test/resources/config/graphql/{getPartij.graphql => findUserPartij.graphql} (98%) create mode 100644 zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql diff --git a/build.gradle.kts b/build.gradle.kts index e8f5a4b9..ccbe73d2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,6 @@ import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension +import io.spring.gradle.dependencymanagement.org.codehaus.plexus.interpolation.os.Os.FAMILY_MAC +import org.apache.tools.ant.taskdefs.condition.Os import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import java.net.URI @@ -134,10 +136,6 @@ subprojects { } } - tasks.withType { - useJUnitPlatform() - } - publishing { repositories { maven { @@ -208,6 +206,16 @@ subprojects { sign(publishing.publications["default"]) } } + + apply(from = "${rootProject.projectDir}/gradle/testing.gradle.kts") + + if (Os.isFamily(FAMILY_MAC)) { + println("Configure docker compose for macOs") + dockerCompose { + executable = "/usr/local/bin/docker-compose" + dockerExecutable = "/usr/local/bin/docker" + } + } } tasks.register("htmlDependencyReport") diff --git a/case/build.gradle.kts b/case/build.gradle.kts index ceabb618..22f1934a 100644 --- a/case/build.gradle.kts +++ b/case/build.gradle.kts @@ -1,6 +1,3 @@ -import io.spring.gradle.dependencymanagement.org.codehaus.plexus.interpolation.os.Os.FAMILY_MAC -import org.apache.tools.ant.taskdefs.condition.Os - /* * Copyright 2015-2023 Ritense BV, the Netherlands. * @@ -21,12 +18,8 @@ plugins { } dockerCompose { - if (Os.isFamily(FAMILY_MAC)) { - executable = "/usr/local/bin/docker-compose" - dockerExecutable = "/usr/local/bin/docker" - } - projectNamePrefix = "case" - isRequiredBy(tasks.getByName("test")) + setProjectName("$name-test") + isRequiredBy(tasks.getByName("integrationTest")) useComposeFiles.addAll("../docker-resources/docker-compose-base-test.yml", "docker-compose-override.yml") } diff --git a/docker-resources/imports/openklant-2/database/init.sh b/docker-resources/imports/openklant-2/database/init.sh new file mode 100755 index 00000000..26d2a8c1 --- /dev/null +++ b/docker-resources/imports/openklant-2/database/init.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo ">>>> Starting Open Klant data import script <<<<" + +sh /docker-entrypoint-initdb.d/sql/fill-data-on-startup.sh & \ No newline at end of file diff --git a/docker-resources/imports/openklant-2/database/sql/1-add-authtoken.sql b/docker-resources/imports/openklant-2/database/sql/1-add-authtoken.sql new file mode 100644 index 00000000..85907bc7 --- /dev/null +++ b/docker-resources/imports/openklant-2/database/sql/1-add-authtoken.sql @@ -0,0 +1 @@ +INSERT INTO public.token_tokenauth (id, token, contact_person, email, organization, last_modified, created, application, administration) VALUES (1, 'ac045222c9e7cde8120b48735560f9b920bb58cd', 'Admin', 'admin@example.com', '', '2024-09-06 07:26:53.703312 +00:00', '2024-09-06 07:26:53.703384 +00:00', '', ''); \ No newline at end of file diff --git a/docker-resources/imports/openklant-2/database/sql/fill-data-on-startup.sh b/docker-resources/imports/openklant-2/database/sql/fill-data-on-startup.sh new file mode 100755 index 00000000..6c346ba9 --- /dev/null +++ b/docker-resources/imports/openklant-2/database/sql/fill-data-on-startup.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +echo ">>>> Waiting until Open Klant has initialized the database <<<<" +while true +do + initiated=$(psql -U openklant -d openklant -t -A -c "SELECT EXISTS (SELECT table_name FROM information_schema.tables WHERE table_name = 'accounts_user');") + if [ "t" = "${initiated}" ] + then + echo "Running database setup scripts" + for file in /docker-entrypoint-initdb.d/sql/*.sql + do + echo "Running $file" + psql -U openklant -d openklant -f $file + done + break + else + echo "Open Klanten is not initiated yet" + sleep 5 + fi +done \ No newline at end of file diff --git a/docker-resources/imports/openklant-2/init/init.sh b/docker-resources/imports/openklant-2/init/init.sh new file mode 100755 index 00000000..4ab75166 --- /dev/null +++ b/docker-resources/imports/openklant-2/init/init.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Apply database migrations +>&2 echo "Apply database migrations" +python src/manage.py migrate + +exists=$(echo "from django.contrib.auth import get_user_model; User = get_user_model(); print(User.objects.filter(username='admin').exists())" | python src/manage.py shell) +if [ "False" = "${exists}" ] +then + echo "Creating user 'admin'" + python src/manage.py createsuperuser --username=admin --email=admin@example.com --noinput +else + echo "User 'admin' already exists" +fi +echo "Setting 'admin' password." +echo "from django.contrib.auth import get_user_model; User = get_user_model(); user = User.objects.get(username='admin'); user.set_password('admin'); user.save()" | python src/manage.py shell +echo "Loading fixtures" +python src/manage.py loaddata klantinteracties contactgegevens +echo "Finished setup" + +sh /start.sh \ No newline at end of file diff --git a/form/build.gradle.kts b/form/build.gradle.kts index 8165e798..bce27cd8 100644 --- a/form/build.gradle.kts +++ b/form/build.gradle.kts @@ -1,6 +1,3 @@ -import io.spring.gradle.dependencymanagement.org.codehaus.plexus.interpolation.os.Os.FAMILY_MAC -import org.apache.tools.ant.taskdefs.condition.Os - /* * Copyright 2015-2023 Ritense BV, the Netherlands. * @@ -21,12 +18,8 @@ plugins { } dockerCompose { - if (Os.isFamily(FAMILY_MAC)) { - executable = "/usr/local/bin/docker-compose" - dockerExecutable = "/usr/local/bin/docker" - } - projectNamePrefix = "form" - isRequiredBy(tasks.getByName("test")) + setProjectName("$name-test") + isRequiredBy(tasks.getByName("integrationTest")) useComposeFiles.addAll("../docker-resources/docker-compose-base-test.yml", "docker-compose-override.yml") } diff --git a/gradle.properties b/gradle.properties index 311d8711..9b14f491 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,9 +9,9 @@ springDependencyManagementVersion=1.1.6 benManesVersionsVersion=0.51.0 ktlintVersion=12.1.1 spotlessVersion=6.25.0 -gradleDockerComposeVersion=0.17.7 +gradleDockerComposeVersion=0.17.8 dokkaVersion=1.9.20 org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2048m org.gradle.workers.max=10 -version=1.4.20-SNAPSHOT +version=1.4.20-SNAPSHOT \ No newline at end of file diff --git a/gradle/testing.gradle.kts b/gradle/testing.gradle.kts new file mode 100644 index 00000000..0c19840f --- /dev/null +++ b/gradle/testing.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright 2015-2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +tasks.register("integrationTest") { + group = "verification" + useJUnitPlatform { + includeTags("integration") + } + + mustRunAfter(tasks.getByName("check")) +} + +tasks.named("test") { + useJUnitPlatform { + excludeTags("integration") + } +} \ No newline at end of file diff --git a/zgw/openklant/build.gradle.kts b/zgw/openklant/build.gradle.kts index ea1d4b4b..f9fe885a 100644 --- a/zgw/openklant/build.gradle.kts +++ b/zgw/openklant/build.gradle.kts @@ -1,3 +1,5 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + /* * Copyright (c) 2024 Ritense BV, the Netherlands. * @@ -19,12 +21,19 @@ plugins { val isLib = true +dockerCompose { + setProjectName("$name-test") + isRequiredBy(tasks.getByName("integrationTest")) + useComposeFiles.addAll("../../docker-resources/docker-compose-base-test.yml", "docker-compose-override.yml") +} + dependencies { api(project(":graphql")) api(project(":portal-authentication")) api(project(":zgw:common-ground-authentication")) testImplementation(project(":zgw:common-ground-authentication-test")) + testImplementation(TestDependencies.postgresql) testImplementation("org.springframework.boot", "spring-boot-starter-test") testImplementation("org.springframework.security", "spring-security-test") testImplementation(TestDependencies.kotlinCoroutines) @@ -34,7 +43,7 @@ dependencies { } val jar: Jar by tasks -val bootJar: org.springframework.boot.gradle.tasks.bundling.BootJar by tasks +val bootJar: BootJar by tasks bootJar.enabled = false jar.enabled = true diff --git a/zgw/openklant/docker-compose-override.yml b/zgw/openklant/docker-compose-override.yml new file mode 100644 index 00000000..efd4d53f --- /dev/null +++ b/zgw/openklant/docker-compose-override.yml @@ -0,0 +1,43 @@ +services: + + # openklant 2 + openklant-2: + image: maykinmedia/open-klant:2.1.0 + container_name: openklant-2-test + ports: + - "9007:8000" + depends_on: + - openklant-2-db + - redis + environment: + - DJANGO_SETTINGS_MODULE=openklant.conf.docker + - IS_HTTPS=no + - DB_NAME=openklant + - DB_USER=openklant + - DB_PASSWORD=openklant + - DB_HOST=openklant-2-db + - ALLOWED_HOSTS=* + - CACHE_DEFAULT=redis-test:6379/0 + - CACHE_AXES=redis-test:6379/0 + - SUBPATH=${SUBPATH:-/} + - SECRET_KEY=${SECRET_KEY:-django-insecure-f8s@b*ds4t84-q_2#c0j0506@!l2q6r5_pq5e!vm^_9c*#^66b} + - CELERY_BROKER_URL=redis://redis-test:6379/0 + - CELERY_RESULT_BACKEND=redis://redis-test:6379/0 + - DISABLE_2FA=true + volumes: + - ./imports/openklant-2/init:/app/init + command: sh /app/init/init.sh + + openklant-2-db: + image: postgres:15 + container_name: openklant-2-db-test + environment: + - POSTGRES_USER=openklant + - POSTGRES_PASSWORD=openklant + - POSTGRES_DB=openklant + volumes: + - ./imports/openklant-2/database:/docker-entrypoint-initdb.d/ + + redis: + image: redis:6.2.6 + container_name: redis-test \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index b0b7ca5b..c28348d9 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt index b8ff0aba..a2e8c1e1 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt index d5943e8b..766103f0 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Actoren.kt similarity index 60% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Actoren.kt index 7ef42839..2b36acfc 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Actoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Actoren.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude @@ -21,39 +21,18 @@ import com.fasterxml.jackson.annotation.JsonValue import java.util.UUID @JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) data class Actor( - val uuid: UUID, - val url: String, + @JsonInclude(JsonInclude.Include.NON_NULL) + val uuid: UUID? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val url: String? = null, val naam: String, val soortActor: SoortActor, val indicatieActief: Boolean? = null, val actoridentificator: OpenKlant2Identificator? = null, -) - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -data class CreateActor( - val name: String, - val indicatieActief: Boolean, - val soortActor: SoortActor, -) { - init { - require(name.length in 1..200) { "Actor name has to be between 1 and 200 characters long" } - } -} - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -data class PatchActor( - val uuid: UUID, - val name: String? = null, - val soortActor: SoortActor, - val indicatieActief: Boolean? = null, - val actoridentificator: OpenKlant2Identificator? = null, ) { init { - require(name == null || name.length in 1..200) { "Actor name has to be between 1 and 200 characters long" } + require(naam == null || naam.length in 1..200) { "Actor name has to be between 1 and 200 characters long" } } } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkenen.kt similarity index 90% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkenen.kt index e4a38cfe..1693c6cf 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Betrokkenen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkenen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain - -import nl.nlportal.openklant.domain.CreatePartij.Contactnaam +package nl.nlportal.openklant.client.domain data class Betrokkene( val bezoekadres: OpenKlant2Adres? = null, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt similarity index 92% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt index 62eeca3b..b1c98e97 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/CategorieRelaties.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain import java.time.LocalDate diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt similarity index 95% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt index 8d5301fa..96698790 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/DigitaleAdressen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/KlantContacten.kt similarity index 93% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/KlantContacten.kt index 7af40e39..a8f9649f 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/KlantContacten.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/KlantContacten.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain data class HadKlantcontact( val gingOverOnderwerpobjecten: List, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt new file mode 100644 index 00000000..9a6d4c4f --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client.domain + +import com.fasterxml.jackson.annotation.JsonInclude +import java.util.UUID + +data class OpenKlant2PartijIdentificator( + @JsonInclude(JsonInclude.Include.NON_NULL) + val uuid: UUID? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val url: String? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val anderePartijIdentificator: String? = null, + val identificeerdePartij: OpenKlant2IdentificeerdePartij? = null, + val partijIdentificator: OpenKlant2Identificator? = null, +) { + init { + require(anderePartijIdentificator == null || anderePartijIdentificator.length <= 200) { + "Andere partij indetificator can't be longer than 200 characters" + } + } +} + +data class OpenKlant2IdentificeerdePartij( + val uuid: UUID, +) \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt similarity index 57% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt index c7781cb4..ec6b2c29 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.fasterxml.jackson.annotation.JsonIgnoreProperties @@ -26,79 +26,40 @@ import com.fasterxml.jackson.annotation.JsonValue import nl.nlportal.commonground.authentication.BedrijfAuthentication import nl.nlportal.commonground.authentication.BurgerAuthentication import nl.nlportal.commonground.authentication.CommonGroundAuthentication -import nl.nlportal.openklant.domain.CreatePartij.ContactpersoonIdentificatie -import nl.nlportal.openklant.domain.CreatePartij.OrganisatieIdentificatie -import nl.nlportal.openklant.domain.CreatePartij.PartijIdentificatie -import nl.nlportal.openklant.domain.CreatePartij.PersoonsIdentificatie import java.time.LocalDate import java.util.Locale import java.util.UUID @GraphQLDescription(value = "A Type that represents a Klantinteracties API Partij object") @JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -data class Partij( - val betrokkenen: List = emptyList(), +data class OpenKlant2Partij( + @JsonInclude(JsonInclude.Include.NON_NULL) + val betrokkenen: List? = null, val bezoekadres: OpenKlant2Adres? = null, - val categorieRelaties: List, + @JsonInclude(JsonInclude.Include.NON_NULL) + val categorieRelaties: List? = null, val correspondentieadres: OpenKlant2Adres? = null, val digitaleAdressen: List? = null, val indicatieActief: Boolean, - val indicatieGeheimhouding: Boolean? = null, + val indicatieGeheimhouding: Boolean, + @JsonInclude(JsonInclude.Include.NON_NULL) val interneNotitie: String? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) val nummer: String? = null, - val partijIdentificatoren: List, + @JsonInclude(JsonInclude.Include.NON_NULL) + val partijIdentificatoren: List? = null, val rekeningnummers: List? = null, val soortPartij: SoortPartij, - val url: String, - val uuid: UUID, - val vertegenwoordigden: List, - val voorkeursDigitaalAdres: OpenKlant2ForeignKey? = null, - val voorkeursRekeningnummer: OpenKlant2ForeignKey? = null, - val voorkeurstaal: String?, - @JsonTypeInfo(include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "soortPartij", use = JsonTypeInfo.Id.NAME) - @JsonSubTypes( - Type(PersoonsIdentificatie::class, name = "persoon"), - Type(OrganisatieIdentificatie::class, name = "organisatie"), - Type(ContactpersoonIdentificatie::class, name = "contactpersoon"), - ) - val partijIdentificatie: PartijIdentificatie, - @JsonProperty("_expand") - val expand: PartijExpand? = null, -) { - init { - require(voorkeurstaal == null || voorkeurstaal in Locale.getAvailableLocales().map { it.isO3Language }) { - "Voorkeurstaal must be a valid Language in the ISO 639-2/B format" - } - require(interneNotitie == null || interneNotitie.length <= 1000) { - "Interne notitie can't be longer than 1000 characters." - } - require(nummer == null || nummer.length <= 10) { - "Nummer can't be longer than 10 characters." - } - } -} - -@JsonIgnoreProperties(ignoreUnknown = true) -data class CreatePartij( @JsonInclude(JsonInclude.Include.NON_NULL) - val nummer: String? = null, + val url: String? = null, @JsonInclude(JsonInclude.Include.NON_NULL) - val interneNotitie: String? = null, - val digitaleAdressen: List? = null, + val uuid: UUID? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val vertegenwoordigden: List? = null, val voorkeursDigitaalAdres: OpenKlant2ForeignKey? = null, - val rekeningnummers: List? = null, val voorkeursRekeningnummer: OpenKlant2ForeignKey? = null, - val soortPartij: SoortPartij, - val indicatieGeheimhouding: Boolean, @JsonInclude(JsonInclude.Include.NON_NULL) val voorkeurstaal: String? = null, - val indicatieActief: Boolean, - @JsonInclude(JsonInclude.Include.NON_NULL) - val bezoekadres: OpenKlant2Adres? = null, - @JsonInclude(JsonInclude.Include.NON_NULL) - val correspondentieadres: OpenKlant2Adres? = null, - val partijIdentificatoren: List, @JsonTypeInfo(include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "soortPartij", use = JsonTypeInfo.Id.NAME) @JsonSubTypes( Type(PersoonsIdentificatie::class, name = "persoon"), @@ -106,6 +67,9 @@ data class CreatePartij( Type(ContactpersoonIdentificatie::class, name = "contactpersoon"), ) val partijIdentificatie: PartijIdentificatie, + @JsonProperty("_expand") + @JsonInclude(JsonInclude.Include.NON_NULL) + val expand: PartijExpand? = null, ) { init { require(voorkeurstaal == null || voorkeurstaal in Locale.getAvailableLocales().map { it.isO3Language }) { @@ -118,40 +82,40 @@ data class CreatePartij( "Nummer can't be longer than 10 characters." } } +} - @JsonIgnoreProperties(ignoreUnknown = true) - @JsonInclude(JsonInclude.Include.NON_NULL) - open class PersoonsIdentificatie( - val contactnaam: Contactnaam? = null, - val volledigeNaam: String? = null, - ) : PartijIdentificatie +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +open class PersoonsIdentificatie( + val contactnaam: Contactnaam? = null, + val volledigeNaam: String? = null, +) : PartijIdentificatie - @JsonIgnoreProperties(ignoreUnknown = true) - @JsonInclude(JsonInclude.Include.NON_NULL) - data class ContactpersoonIdentificatie( - val uuid: UUID? = null, - val werkteVoorPartij: OpenKlant2ForeignKey? = null, - val contactnaam: Contactnaam? = null, - val volledigeNaam: String? = null, - ) : PartijIdentificatie +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class ContactpersoonIdentificatie( + val uuid: UUID? = null, + val werkteVoorPartij: OpenKlant2ForeignKey? = null, + val contactnaam: Contactnaam? = null, + val volledigeNaam: String? = null, +) : PartijIdentificatie - @JsonIgnoreProperties(ignoreUnknown = true) - @JsonInclude(JsonInclude.Include.NON_NULL) - data class OrganisatieIdentificatie( - val naam: String? = null, - ) : PartijIdentificatie +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class OrganisatieIdentificatie( + val naam: String? = null, +) : PartijIdentificatie - interface PartijIdentificatie +interface PartijIdentificatie - @JsonIgnoreProperties(ignoreUnknown = true) - @JsonInclude(JsonInclude.Include.NON_NULL) - data class Contactnaam( - val voorletters: String? = null, - val voornaam: String? = null, - val voorvoegselAchternaam: String? = null, - val achternaam: String? = null, - ) -} +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +data class Contactnaam( + val voorletters: String? = null, + val voornaam: String? = null, + val voorvoegselAchternaam: String? = null, + val achternaam: String? = null, +) class PartijExpand( val betrokkenen: List? = null, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/ResultPage.kt similarity index 91% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/ResultPage.kt index f71efe90..3d7337b2 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/ResultPage.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/ResultPage.kt @@ -1,5 +1,5 @@ /* - * Copyright 2015-2023 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain import java.net.URI diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt similarity index 96% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt index e94ee065..f1816212 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/domain/Shared.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.nlportal.openklant.domain +package nl.nlportal.openklant.client.domain import com.fasterxml.jackson.annotation.JsonValue @@ -23,11 +23,26 @@ data class OpenKlant2ForeignKey( ) data class OpenKlant2Identificator( - val objectId: String, - val codeObjecttype: String, - val codeRegister: String, - val codeSoortObjectId: String, -) + val objectId: String = "", + val codeObjecttype: String = "", + val codeRegister: String = "", + val codeSoortObjectId: String = "", +) { + init { + require(objectId.length <= 200) { + "ObjectID can't be longer than 200 characters" + } + require(codeObjecttype.length <= 200) { + "ObjectID can't be longer than 200 characters" + } + require(codeRegister.length <= 200) { + "ObjectID can't be longer than 200 characters" + } + require(codeSoortObjectId.length <= 200) { + "ObjectID can't be longer than 200 characters" + } + } +} data class OpenKlant2Adres( val adresregel1: String? = null, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt index adbbfb49..00e43b19 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt new file mode 100644 index 00000000..345186bc --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client.path + +import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator +import nl.nlportal.openklant.client.domain.ResultPage +import org.springframework.http.MediaType +import org.springframework.util.MultiValueMapAdapter +import org.springframework.web.reactive.function.BodyInserters +import org.springframework.web.reactive.function.client.awaitBody + +class PartijIdentificatoren(val client: OpenKlant2Client) : KlantInteractiesPath() { + override val path: String = "/partij-identificatoren" + + suspend fun find(searchVariables: MultiValueMapAdapter? = null): List { + val response: ResultPage = + client + .webClient() + .get() + .uri { uriBuilder -> + uriBuilder + .path(path) + searchVariables?.let { uriBuilder.queryParams(it) } + uriBuilder.build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results + } + + suspend fun create(partijIdentificatorRequest: OpenKlant2PartijIdentificator): OpenKlant2PartijIdentificator { + val response: OpenKlant2PartijIdentificator = + client + .webClient() + .post() + .uri { uriBuilder -> + uriBuilder + .path(path) + .build() + } + .body(BodyInserters.fromValue(partijIdentificatorRequest)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt index 2e95df9c..fdce9c87 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -16,19 +16,21 @@ package nl.nlportal.openklant.client.path import nl.nlportal.openklant.client.OpenKlant2Client -import nl.nlportal.openklant.domain.CreatePartij -import nl.nlportal.openklant.domain.Partij -import nl.nlportal.openklant.domain.ResultPage +import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.client.domain.ResultPage import org.springframework.http.MediaType import org.springframework.util.MultiValueMap import org.springframework.web.reactive.function.BodyInserters +import org.springframework.web.reactive.function.client.awaitBodilessEntity import org.springframework.web.reactive.function.client.awaitBody +import org.springframework.web.reactive.function.client.awaitBodyOrNull +import java.util.UUID class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { - override val path = "/klantinteracties/api/v1/partijen" + override val path = "/partijen" - suspend fun find(queryParams: MultiValueMap? = null): Partij? { - val response: ResultPage = + suspend fun find(queryParams: MultiValueMap? = null): OpenKlant2Partij? { + val response: ResultPage = client .webClient() .get() @@ -45,8 +47,25 @@ class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { return response.results.singleOrNull() } - suspend fun create(createPartij: CreatePartij): Partij { - val response: Partij = + suspend fun get(partijId: UUID): OpenKlant2Partij? { + val response: OpenKlant2Partij? = + client + .webClient() + .get() + .uri { uriBuilder -> + uriBuilder + .path("$path/$partijId") + .build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodyOrNull() + + return response + } + + suspend fun create(partijRequest: OpenKlant2Partij): OpenKlant2Partij { + val response: OpenKlant2Partij = client .webClient() .post() @@ -55,7 +74,7 @@ class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { .path(path) .build() } - .body(BodyInserters.fromValue(createPartij)) + .body(BodyInserters.fromValue(partijRequest)) .accept(MediaType.APPLICATION_JSON) .retrieve() .awaitBody() @@ -63,8 +82,8 @@ class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { return response } - suspend fun put(partij: Partij): Partij? { - val response: ResultPage = + suspend fun put(partij: OpenKlant2Partij): OpenKlant2Partij? { + val response: ResultPage = client .webClient() .put() @@ -80,4 +99,18 @@ class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { return response.results.singleOrNull() } + + suspend fun delete(uuid: UUID) { + client + .webClient() + .delete() + .uri { uriBuilder -> + uriBuilder + .path("$path/$uuid") + .build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodilessEntity() + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index a1b70247..f09c60b7 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.server.operations.Mutation -import com.fasterxml.jackson.databind.node.ObjectNode import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY -import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.graphql.domain.PartijRequest import nl.nlportal.openklant.service.OpenKlant2Service class PartijMutation( @@ -29,16 +29,22 @@ class PartijMutation( @GraphQLDescription("Create Partij for user") suspend fun createPartij( dfe: DataFetchingEnvironment, - createPartijPayload: ObjectNode, - ): Partij? { - return openklant2Service.createPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY), createPartijPayload) + partijRequest: PartijRequest, + ): OpenKlant2Partij? { + return openklant2Service.createPartijWithIdentificator( + authentication = dfe.graphQlContext.get(AUTHENTICATION_KEY), + partijRequest = partijRequest.asOpenKlant2Partij(), + ) } @GraphQLDescription("Update user Partij") suspend fun updatePartij( dfe: DataFetchingEnvironment, - partijPayload: ObjectNode, - ): Partij { - return openklant2Service.updatePartij(dfe.graphQlContext.get(AUTHENTICATION_KEY), partijPayload) + partijRequest: PartijRequest, + ): OpenKlant2Partij { + return openklant2Service.updatePartij( + dfe.graphQlContext.get(AUTHENTICATION_KEY), + partijRequest.asOpenKlant2Partij(), + ) } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt index ade6cbf3..973cd022 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,34 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.server.operations.Query import graphql.schema.DataFetchingEnvironment +import nl.nlportal.commonground.authentication.CommonGroundAuthentication import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY -import nl.nlportal.openklant.domain.Partij +import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.service.OpenKlant2Service +import java.util.UUID class PartijQuery( private val openklant2Service: OpenKlant2Service, ) : Query { - @GraphQLDescription("Get user Partij") - suspend fun getPartij(dfe: DataFetchingEnvironment): Partij? { + @GraphQLDescription("Find the Partij of the authenticated user.") + suspend fun findUserPartij(dfe: DataFetchingEnvironment): OpenKlant2Partij? { return openklant2Service.findPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY)) } + + @GraphQLDescription("Get Partij by Id for authenticated user.") + suspend fun getUserPartij( + dfe: DataFetchingEnvironment, + partijId: UUID, + ): OpenKlant2Partij? { + val authentication: CommonGroundAuthentication = dfe.graphQlContext.get(AUTHENTICATION_KEY) + val userPartijen = + openklant2Service + .findPartijIdentificatoren(authentication) + ?.mapNotNull { it.identificeerdePartij?.uuid } + + if (userPartijen == null || partijId !in userPartijen) return null + val partijResponse = openklant2Service.getPartij(partijId = partijId) + + return partijResponse + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt new file mode 100644 index 00000000..e5a17b0a --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql.domain + +import nl.nlportal.openklant.client.domain.ContactpersoonIdentificatie +import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.client.domain.OrganisatieIdentificatie +import nl.nlportal.openklant.client.domain.PartijIdentificatie +import nl.nlportal.openklant.client.domain.PersoonsIdentificatie +import nl.nlportal.openklant.client.domain.SoortPartij +import nl.nlportal.openklant.client.domain.SoortPartij.CONTACTPERSOON +import nl.nlportal.openklant.client.domain.SoortPartij.ORGANISATIE +import nl.nlportal.openklant.client.domain.SoortPartij.PERSOON + +data class PartijRequest( + val indicatieGeheimhouding: Boolean, + val indicatieActief: Boolean, + val soortPartij: SoortPartij, + val persoonIdentification: PersoonsIdentificatie? = null, + val organisatieIdentificatie: OrganisatieIdentificatie? = null, + val contactpersoonIdentificatie: ContactpersoonIdentificatie? = null, +) { + private val identificatie: PartijIdentificatie = + when (soortPartij) { + PERSOON -> + requireNotNull(persoonIdentification) { + "{persoonIdentification} can not be null when is $soortPartij" + } + ORGANISATIE -> + requireNotNull(organisatieIdentificatie) { + "{organisatieIdentificatie} can not be null when is $soortPartij" + } + CONTACTPERSOON -> + requireNotNull(contactpersoonIdentificatie) { + "{contactpersoonIdentificatie} can not be null when is $soortPartij" + } + } + + fun asOpenKlant2Partij(): OpenKlant2Partij = + OpenKlant2Partij( + indicatieGeheimhouding = indicatieGeheimhouding, + indicatieActief = indicatieActief, + soortPartij = soortPartij, + partijIdentificatie = identificatie, + ) +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index d8e63188..2bfc385c 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,26 @@ */ package nl.nlportal.openklant.service -import com.fasterxml.jackson.databind.node.ObjectNode import com.fasterxml.jackson.module.kotlin.convertValue import mu.KotlinLogging import nl.nlportal.commonground.authentication.CommonGroundAuthentication import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.domain.OpenKlant2Identificator +import nl.nlportal.openklant.client.domain.OpenKlant2IdentificeerdePartij +import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator +import nl.nlportal.openklant.client.domain.asSoortPartij +import nl.nlportal.openklant.client.path.PartijIdentificatoren import nl.nlportal.openklant.client.path.Partijen -import nl.nlportal.openklant.domain.Partij -import nl.nlportal.openklant.domain.asSoortPartij import org.springframework.util.MultiValueMapAdapter import org.springframework.web.reactive.function.client.WebClientResponseException +import java.util.UUID class OpenKlant2Service( private val openKlant2Client: OpenKlant2Client, ) { - suspend fun findPartij(authentication: CommonGroundAuthentication): Partij? { + suspend fun findPartij(authentication: CommonGroundAuthentication): OpenKlant2Partij? { val searchVariables = MultiValueMapAdapter( mapOf( @@ -47,25 +51,76 @@ class OpenKlant2Service( } } - suspend fun createPartij( - authentication: CommonGroundAuthentication, - partij: ObjectNode, - ): Partij? { + suspend fun getPartij(partijId: UUID): OpenKlant2Partij? { try { - return openKlant2Client.path().create(objectMapper.convertValue(partij)) + return openKlant2Client.path().get(partijId) } catch (ex: WebClientResponseException) { - logger.debug("Failed to create Partij: ${ex.responseBodyAsString}", ex) + logger.debug("Failed to find Partij: ${ex.responseBodyAsString}", ex) return null } } + suspend fun createPartijWithIdentificator( + authentication: CommonGroundAuthentication, + partijRequest: OpenKlant2Partij, + ): OpenKlant2Partij? { + val partijIdentificator = + OpenKlant2PartijIdentificator( + partijIdentificator = + OpenKlant2Identificator( + objectId = authentication.userId, + ), + ) + val partijResponse = + try { + openKlant2Client.path().create(partijRequest) + .also { + try { + openKlant2Client + .path() + .create( + partijIdentificator + .copy( + identificeerdePartij = OpenKlant2IdentificeerdePartij(it.uuid!!), + ), + ) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to create PartijIdentificator") + openKlant2Client.path().delete(it.uuid!!) + throw ex + } + } + } catch (ex: WebClientResponseException) { + logger.debug("Failed to create Partij: ${ex.responseBodyAsString}", ex) + return null + } + + return partijResponse + } + suspend fun updatePartij( authentication: CommonGroundAuthentication, - partij: ObjectNode, - ): Partij { + partij: OpenKlant2Partij, + ): OpenKlant2Partij { return objectMapper.convertValue(partij) } + suspend fun findPartijIdentificatoren(authentication: CommonGroundAuthentication): List? { + val searchVariables = + MultiValueMapAdapter( + mapOf( + "partij_identificator_object_id" to listOf(authentication.userId), + ), + ) + + try { + return openKlant2Client.path().find(searchVariables) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to find Partij Identificatoren: ${ex.responseBodyAsString}", ex) + return null + } + } + companion object { private val objectMapper = Mapper.get() private val logger = KotlinLogging.logger {} diff --git a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 0651fb78..bfe73899 100644 --- a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,17 @@ +# +# Copyright 2024 Ritense BV, the Netherlands. +# +# Licensed under EUPL, Version 1.2 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt index 00135b7d..32c941a7 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestApplication.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt index c11bbf53..788aa0a3 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt index 60c8d23a..46395a59 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt index 48761719..dd4ea710 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.springframework.beans.factory.annotation.Autowired @@ -37,9 +38,10 @@ import org.springframework.web.reactive.function.BodyInserters import java.nio.charset.Charset @SpringBootTest +@Tag("integration") +@ActiveProfiles("openklant-disabled") @AutoConfigureWebTestClient(timeout = "36000") @TestInstance(TestInstance.Lifecycle.PER_METHOD) -@ActiveProfiles("openklant-disabled") class ModuleConfigurationIT( @Autowired private val webTestClient: WebTestClient, @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt new file mode 100644 index 00000000..3b938d62 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.module.kotlin.readValue +import com.fasterxml.jackson.module.kotlin.treeToValue +import kotlinx.coroutines.test.runTest +import nl.nlportal.commonground.authentication.WithBurgerUser +import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.client.domain.PersoonsIdentificatie +import nl.nlportal.openklant.client.domain.SoortPartij +import nl.nlportal.openklant.service.OpenKlant2Service +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.assertDoesNotThrow +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.mock.mockito.SpyBean +import org.springframework.core.io.ClassPathResource +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.web.reactive.function.BodyInserters +import java.nio.charset.Charset + +@SpringBootTest +@Tag("integration") +@AutoConfigureWebTestClient(timeout = "36000") +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +class PartijMutationIT( + @Autowired private val webTestClient: WebTestClient, +) { + @SpyBean + lateinit var openKlant2Service: OpenKlant2Service + + @Test + @Disabled("Not implemented yet") + @WithBurgerUser("999990755") + fun `should create Partij for authenticated user`() = + runTest { + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val responsePartij = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("getPartij") + + // then + verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) + + assertNotNull(responsePartij) + assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) + assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } + assertEquals("Lucas Boom", responsePartij?.requiredAt("/partijIdentificatie/volledigeNaam")?.textValue()) + } + + companion object { + private val objectMapper = Mapper.get() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt index 226e59b9..7e012af9 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Ritense BV, the Netherlands. + * Copyright 2024 Ritense BV, the Netherlands. * * Licensed under EUPL, Version 1.2 (the "License"); * you may not use this file except in compliance with the License. @@ -21,18 +21,13 @@ import com.fasterxml.jackson.module.kotlin.treeToValue import kotlinx.coroutines.test.runTest import nl.nlportal.commonground.authentication.WithBurgerUser import nl.nlportal.core.util.Mapper -import nl.nlportal.openklant.TestHelper -import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration -import nl.nlportal.openklant.domain.CreatePartij.PersoonsIdentificatie -import nl.nlportal.openklant.domain.SoortPartij +import nl.nlportal.openklant.client.domain.PersoonsIdentificatie +import nl.nlportal.openklant.client.domain.SoortPartij import nl.nlportal.openklant.service.OpenKlant2Service -import okhttp3.mockwebserver.MockResponse -import okhttp3.mockwebserver.MockWebServer -import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.assertDoesNotThrow @@ -51,29 +46,15 @@ import org.springframework.web.reactive.function.BodyInserters import java.nio.charset.Charset @SpringBootTest +@Tag("integration") @AutoConfigureWebTestClient(timeout = "36000") @TestInstance(TestInstance.Lifecycle.PER_METHOD) class PartijQueryIT( @Autowired private val webTestClient: WebTestClient, - @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, ) { @SpyBean lateinit var openKlant2Service: OpenKlant2Service - lateinit var mockOpenKlant: MockWebServer - - @BeforeEach - fun setUp() { - mockOpenKlant = MockWebServer() - mockOpenKlant.start() - openKlantModuleConfiguration.properties.url = mockOpenKlant.url("/").toUri() - } - - @AfterEach - internal fun tearDown() { - mockOpenKlant.shutdown() - } - @Test fun `should introspect Partij type`() = runTest { @@ -103,25 +84,17 @@ class PartijQueryIT( // then assertEquals("OBJECT", typeResponse?.get("kind")?.textValue()) - assertEquals("Partij", typeResponse?.get("name")?.textValue()) - assertEquals("A Type that represents a Klantinteracties API Partij object", typeResponse?.get("description")?.textValue()) + assertEquals("OpenKlant2Partij", typeResponse?.get("name")?.textValue()) + assertEquals( + "A Type that represents a Klantinteracties API Partij object", + typeResponse?.get("description")?.textValue(), + ) } @Test - @WithBurgerUser("999990755") - fun `should return Partij for authenticated user`() = + @WithBurgerUser("123456788") + fun `should find Partij for authenticated user`() = runTest { - // given - val partijenResponse = - MockResponse() - .setResponseCode(200) - .addHeader("Content-Type", "application/json") - .setBody(TestHelper.Partijen.persoonPartijResponse) - - with(mockOpenKlant) { - enqueue(partijenResponse) - } - // when val responseBody = webTestClient @@ -132,7 +105,7 @@ class PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.graphql"))) .exchange() .expectStatus().isOk .expectBody() @@ -144,15 +117,11 @@ class PartijQueryIT( objectMapper .readValue(responseBody!!) .get("data") - ?.get("getPartij") - - val recordedRequest = mockOpenKlant.takeRequest() + ?.get("findUserPartij") // then verify(openKlant2Service, times(1)).findPartij(any()) - assertTrue(recordedRequest.requestUrl.toString().contains("999990755")) - assertTrue(recordedRequest.requestUrl.toString().contains("persoon")) assertNotNull(responsePartij) assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } @@ -160,20 +129,46 @@ class PartijQueryIT( } @Test - @WithBurgerUser("111111110") - fun `should return null when no Partij was found for authenticated user`() = + @WithBurgerUser("123456788") + fun `should get Partij by Id for authenticated user`() = runTest { - // given - val partijenResponse = - MockResponse() - .setResponseCode(200) - .addHeader("Content-Type", "application/json") - .setBody(TestHelper.Partijen.emptyPage) + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserPartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val responsePartij = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("getUserPartij") - with(mockOpenKlant) { - enqueue(partijenResponse) - } + // then + verify(openKlant2Service, times(1)).getPartij(any()) + assertNotNull(responsePartij) + assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) + assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } + assertEquals("Lucas Boom", responsePartij?.requiredAt("/partijIdentificatie/volledigeNaam")?.textValue()) + } + + @Test + @WithBurgerUser("99990755") + fun `should return null when user is not allowed to request Partij`() = + runTest { // when val responseBody = webTestClient @@ -184,7 +179,7 @@ class PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserPartij.graphql"))) .exchange() .expectStatus().isOk .expectBody() @@ -196,15 +191,45 @@ class PartijQueryIT( objectMapper .readValue(responseBody!!) .get("data") - ?.get("getPartij") + ?.get("getUserPartij") - val recordedRequest = mockOpenKlant.takeRequest() + // then + verify(openKlant2Service, times(1)).findPartijIdentificatoren(any()) + verify(openKlant2Service, times(0)).getPartij(any()) + + assertTrue(responsePartij!!.isNull) + } + + @Test + @WithBurgerUser("111111110") + fun `should return null when no Partij was found for authenticated user`() = + runTest { + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val responsePartij = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("findUserPartij") // then verify(openKlant2Service, times(1)).findPartij(any()) - - assertTrue(recordedRequest.requestUrl.toString().contains("111111110")) - assertTrue(recordedRequest.requestUrl.toString().contains("persoon")) assertTrue(responsePartij!!.isNull) } diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt new file mode 100644 index 00000000..19fe8fa2 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.service + +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties +import nl.nlportal.openklant.client.OpenKlant2Client +import okhttp3.mockwebserver.MockWebServer +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach + +class OpenKlant2ServiceTest() { + private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration + private lateinit var mockServer: MockWebServer + private lateinit var openKlant2Client: OpenKlant2Client + private lateinit var hostUrl: String + private lateinit var apiUrl: String + + @BeforeEach + fun setUp() { + mockServer = MockWebServer() + mockServer.start() + + hostUrl = "http://${mockServer.hostName}:${mockServer.port}/" + apiUrl = "http://${mockServer.hostName}:${mockServer.port}/myapi/v1" + openklantModuleConfiguration = + OpenKlantModuleConfiguration( + enabled = true, + properties = + OpenKlantConfigurationProperties( + url = mockServer.url("/myapi/v1").toUri(), + token = "SuperSecretToken1234", + ), + ) + openKlant2Client = OpenKlant2Client(openklantModuleConfiguration.properties) + } + + @AfterEach + internal fun tearDown() { + mockServer.shutdown() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/application.yml b/zgw/openklant/src/test/resources/config/application.yml index 69fcb666..56dc4a3d 100644 --- a/zgw/openklant/src/test/resources/config/application.yml +++ b/zgw/openklant/src/test/resources/config/application.yml @@ -7,7 +7,7 @@ nl-portal: openklant: enabled: true properties: - url: http://localhost:8007 + url: http://localhost:9007/klantinteracties/api/v1 token: ac045222c9e7cde8120b48735560f9b920bb58cd spring: diff --git a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql new file mode 100644 index 00000000..442a2a39 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql @@ -0,0 +1,121 @@ +mutation { + createPartij( + createPartijPayload: { + "soortPartij": "persoon", + "partijIdentificatie": { + "contactnaam": { + "voorletters": "A.", + "voornaam": "Anna", + "voorvoegselAchternaam": "", + "achternaam": "Vissart" + } + } + ) { + betrokkenen { + uuid + url + } + bezoekadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + categorieRelaties { + beginDatum + categorieNaam + eindDatum + url + uuid + } + correspondentieadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + digitaleAdressen { + uuid + url + } + indicatieActief + indicatieGeheimhouding + interneNotitie + nummer + partijIdentificatoren { + uuid + url + } + rekeningnummers { + uuid + url + } + soortPartij + url + uuid + vertegenwoordigden { + uuid + url + } + voorkeursDigitaalAdres { + uuid + url + } + voorkeursRekeningnummer { + uuid + url + } + voorkeurstaal + partijIdentificatie { + ... on PersoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on ContactpersoonIdentificatie { + uuid + werkteVoorPartij { + uuid + url + } + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on OrganisatieIdentificatie { + naam + } + } + } +} + +{ + "digitaleAdressen": null, + "voorkeursDigitaalAdres": null, + "vertegenwoordigden": null, + "rekeningnummers": null, + "voorkeursRekeningnummer": null, + "partijIdentificatoren": null, + "soortPartij": "persoon", + "indicatieGeheimhouding": true, + "indicatieActief": true, + "partijIdentificatie": { + "contactnaam": { + "voorletters": "A.", + "voornaam": "Anna", + "voorvoegselAchternaam": "", + "achternaam": "Vissart" + }, + "volledigeNaam": "Anna Vissart" + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/getPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql similarity index 98% rename from zgw/openklant/src/test/resources/config/graphql/getPartij.graphql rename to zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql index 34c0c9e7..37539244 100644 --- a/zgw/openklant/src/test/resources/config/graphql/getPartij.graphql +++ b/zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql @@ -1,5 +1,5 @@ query { - getPartij { + findUserPartij { betrokkenen { uuid url diff --git a/zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql new file mode 100644 index 00000000..5405dfc6 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql @@ -0,0 +1,89 @@ +query { + getUserPartij(partijId: "9f8e8009-2d1c-40ae-931e-c08861ba7207") { + betrokkenen { + uuid + url + } + bezoekadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + categorieRelaties { + beginDatum + categorieNaam + eindDatum + url + uuid + } + correspondentieadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + digitaleAdressen { + uuid + url + } + indicatieActief + indicatieGeheimhouding + interneNotitie + nummer + partijIdentificatoren { + uuid + url + } + rekeningnummers { + uuid + url + } + soortPartij + url + uuid + vertegenwoordigden { + uuid + url + } + voorkeursDigitaalAdres { + uuid + url + } + voorkeursRekeningnummer { + uuid + url + } + voorkeurstaal + partijIdentificatie { + ... on PersoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on ContactpersoonIdentificatie { + uuid + werkteVoorPartij { + uuid + url + } + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on OrganisatieIdentificatie { + naam + } + } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql b/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql index 50ddefb7..25ae5eb8 100644 --- a/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql +++ b/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql @@ -1,5 +1,5 @@ query { - __type(name: "Partij") { + __type(name: "OpenKlant2Partij") { kind name description From 4875c1c9a3fc6fe94694606c6fac363e6f7aa858 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Thu, 3 Oct 2024 14:52:31 +0200 Subject: [PATCH 06/19] * make filtering easier to apply to OpenKlant requests * fix integration tests not running on check/build * remove unnecessary Create* dto's --- app/src/main/resources/config/application.yml | 4 +-- docker-resources/docker-compose-base-test.yml | 1 - gradle/testing.gradle.kts | 4 +-- .../domain/{Betrokkenen.kt => Betrokkene.kt} | 13 -------- .../client/domain/CategorieRelaties.kt | 7 ---- .../{DigitaleAdressen.kt => DigitaleAdres.kt} | 10 ------ .../client/domain/PartijIdentificatoren.kt | 16 ++++++++- .../openklant/client/domain/Partijen.kt | 33 ++++++++++++++++++- .../openklant/client/domain/Shared.kt | 10 ++++-- .../client/path/KlantInteractiesPath.kt | 9 +++++ .../client/path/PartijIdentificatoren.kt | 8 +++-- .../openklant/client/path/Partijen.kt | 6 ++-- .../openklant/service/OpenKlant2Service.kt | 22 ++++++------- ...tClientTest.kt => OpenKlant2ClientTest.kt} | 2 +- ....kt => OpenKlant2ModuleConfigurationIT.kt} | 2 +- ...ionIT.kt => OpenKlant2PartijMutationIT.kt} | 2 +- ...jQueryIT.kt => OpenKlant2PartijQueryIT.kt} | 2 +- 17 files changed, 89 insertions(+), 62 deletions(-) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/{Betrokkenen.kt => Betrokkene.kt} (72%) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/{DigitaleAdressen.kt => DigitaleAdres.kt} (81%) rename zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/{OpenKlantClientTest.kt => OpenKlant2ClientTest.kt} (99%) rename zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/{ModuleConfigurationIT.kt => OpenKlant2ModuleConfigurationIT.kt} (98%) rename zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/{PartijMutationIT.kt => OpenKlant2PartijMutationIT.kt} (99%) rename zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/{PartijQueryIT.kt => OpenKlant2PartijQueryIT.kt} (99%) diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index 4546d1f8..db449d89 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -76,7 +76,7 @@ nl-portal: openklant: enabled: true properties: - url: http://localhost:8007 + url: http://localhost:8007/klantinteracties/api/v1 token: ac045222c9e7cde8120b48735560f9b920bb58cd zgw: catalogiapi: @@ -175,4 +175,4 @@ nl-portal: shaInKey: de14f0e3-2ff0-45eb-95a6-1cdc35ca7a00 shaOutKey: de14f0e3-2ff0-45eb-95a6-1cdc35ca7a00 failureUrl: http://localhost:3000 - successUrl: http://localhost:3000 + successUrl: http://localhost:3000 \ No newline at end of file diff --git a/docker-resources/docker-compose-base-test.yml b/docker-resources/docker-compose-base-test.yml index deaa43e7..f4fa28bd 100644 --- a/docker-resources/docker-compose-base-test.yml +++ b/docker-resources/docker-compose-base-test.yml @@ -1,4 +1,3 @@ -version: '3.9' services: db: image: "postgres" diff --git a/gradle/testing.gradle.kts b/gradle/testing.gradle.kts index 0c19840f..8dd5a23e 100644 --- a/gradle/testing.gradle.kts +++ b/gradle/testing.gradle.kts @@ -19,12 +19,12 @@ tasks.register("integrationTest") { useJUnitPlatform { includeTags("integration") } - - mustRunAfter(tasks.getByName("check")) } tasks.named("test") { useJUnitPlatform { excludeTags("integration") } + + dependsOn(tasks.getByName("integrationTest")) } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkenen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkene.kt similarity index 72% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkenen.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkene.kt index 1693c6cf..a369267d 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkenen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Betrokkene.kt @@ -28,17 +28,4 @@ data class Betrokkene( val uuid: String, val volledigeNaam: String, val wasPartij: OpenKlant2ForeignKey? = null, -) - -data class CreateBetrokkene( - val bezoekadres: OpenKlant2Adres? = null, - val contactnaam: Contactnaam? = null, - val correspondentieadres: OpenKlant2Adres? = null, - val digitaleAdressen: List, - val hadKlantcontact: OpenKlant2ForeignKey, - val initiator: Boolean, - val organisatienaam: String, - val rol: String, - val volledigeNaam: String, - val wasPartij: OpenKlant2ForeignKey? = null, ) \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt index b1c98e97..0d9fbada 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/CategorieRelaties.kt @@ -26,13 +26,6 @@ data class CategorieRelatie( val uuid: String, ) -data class CreateCategorieRelatie( - val beginDatum: LocalDate? = null, - val categorie: Categorie? = null, - val eindDatum: LocalDate? = null, - val partij: OpenKlant2ForeignKey? = null, -) - data class Categorie( val naam: String, val url: String, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdres.kt similarity index 81% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdres.kt index 96698790..6ec372e9 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdres.kt @@ -28,16 +28,6 @@ data class DigitaleAdres( val uuid: String, val verstrektDoorBetrokkene: OpenKlant2ForeignKey? = null, val verstrektDoorPartij: OpenKlant2ForeignKey? = null, -) - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -data class CreateDigitaleAdres( - val adres: String, - val omschrijving: String, - val soortDigitaalAdres: String, - val verstrektDoorBetrokkene: OpenKlant2ForeignKey? = null, - val verstrektDoorPartij: OpenKlant2ForeignKey? = null, ) { init { require(adres.length <= 80) { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt index 9a6d4c4f..392accdf 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.client.domain import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonValue import java.util.UUID data class OpenKlant2PartijIdentificator( @@ -37,4 +38,17 @@ data class OpenKlant2PartijIdentificator( data class OpenKlant2IdentificeerdePartij( val uuid: UUID, -) \ No newline at end of file +) + +enum class OpenKlant2PartijIdentificatorenFilters( + @JsonValue val value: String, +) : OpenKlant2Filters { + ANDERE_PARTIJ_IDENTIFICATOR("andere_partij_identificator"), + PARTIJ_IDENTIFICATOR_CODE_OBJECTTYPE("partij_identificator_code_objecttype"), + PARTIJ_IDENTIFICATOR_CODE_SOORT_OBJECT_ID("partij_identificator_code_soort_object_id"), + PARTIJ_IDENTIFICATOR_OBJECT_ID("partij_identificator_object_id"), + PARTIJ_IDENTIFICATOR_CODE_REGISTER("partij_identificator_code_register"), + ; + + override fun toString() = this.value +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt index ec6b2c29..89fe7a52 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt @@ -117,7 +117,7 @@ data class Contactnaam( val achternaam: String? = null, ) -class PartijExpand( +data class PartijExpand( val betrokkenen: List? = null, val hadKlantcontact: List? = null, val categorieRelaties: List? = null, @@ -132,6 +132,37 @@ data class CategorieRelatieForeignKey( val uuid: String, ) +enum class OpenKlant2PartijenFilters( + @JsonValue val value: String, +) : OpenKlant2Filters { + VERTEGENWOORDIGDE_PARTIJ_UUID("vertegenwoordigde_partij__uuid"), + VERTEGENWOORDIGDE_PARTIJ_URL("vertegenwoordigde_partij__url"), + PARTIJ_IDENTIFICATOR_CODE_OBJECTTYPE("partij_identificator__code_objecttype"), + PARTIJ_IDENTIFICATOR_CODE_SOORT_OBJECT_ID("partij_identificator__code_soort_object_id"), + PARTIJ_IDENTIFICATOR_OBJECT_ID("partij_identificator__object_id"), + PARTIJ_IDENTIFICATOR_CODE_REGISTER("partij_identificator__code_register"), + CATEGORIERELATIE__CATEGORIE_NAAM("categorierelatie__categorie__naam"), + NUMMER("nummer"), + INDICATIE_GEHEIMHOUDING("indicatie_geheimhouding"), + INDICATIE_ACTIEF("indicatie_actief"), + SOORT_PARTIJ("soort_partij"), + BEZOEKADRES_NUMMERAANDUIDING_ID("bezoekadres_nummeraanduiding_id"), + BEZOEKADRES_ADRESREGEL1("bezoekadres_adresregel1"), + BEZOEKADRES_ADRESREGEL2("bezoekadres_adresregel2"), + BEZOEKADRES_ADRESREGEL3("bezoekadres_adresregel3"), + BEZOEKADRES_LAND("bezoekadres_land"), + CORRESPONDENTIEADRES_NUMMERAANDUIDING_ID("correspondentieadres_nummeraanduiding_id"), + CORRESPONDENTIEADRES_ADRESREGEL1("correspondentieadres_adresregel1"), + CORRESPONDENTIEADRES_ADRESREGEL2("correspondentieadres_adresregel2"), + CORRESPONDENTIEADRES_ADRESREGEL3("correspondentieadres_adresregel3"), + CORRESPONDENTIEADRES_LAND("correspondentieadres_land"), + ; + + override fun toString(): String { + return this.value + } +} + enum class SoortPartij( @JsonValue val value: String, ) { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt index f1816212..17066403 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt @@ -15,6 +15,7 @@ */ package nl.nlportal.openklant.client.domain +import com.expediagroup.graphql.generator.annotations.GraphQLIgnore import com.fasterxml.jackson.annotation.JsonValue data class OpenKlant2ForeignKey( @@ -48,7 +49,7 @@ data class OpenKlant2Adres( val adresregel1: String? = null, val adresregel2: String? = null, val adresregel3: String? = null, - val land: Landcode? = null, + val land: OpenKlant2Landcode? = null, val nummeraanduidingId: String? = null, ) { init { @@ -67,7 +68,10 @@ data class OpenKlant2Adres( } } -enum class Landcode( +@GraphQLIgnore +interface OpenKlant2Filters + +enum class OpenKlant2Landcode( @JsonValue val landcode: String, val landnaam: String, ) { @@ -460,7 +464,7 @@ enum class Landcode( MICRONESIA("9094", "Micronesia"), SVALBARDEILANDEN("9095", "Svalbardeilanden"), INTERNATIONAAL_GEBIED("9999", "Internationaal gebied"), - NULL("", "Null"), + NONE("", ""), ; override fun toString(): String { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt index 00e43b19..2b42f0eb 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt @@ -15,6 +15,15 @@ */ package nl.nlportal.openklant.client.path +import nl.nlportal.openklant.client.domain.OpenKlant2Filters +import org.springframework.web.util.UriBuilder + open class KlantInteractiesPath { open val path: String = "/" + + fun UriBuilder.queryParams(filters: List>? = null): UriBuilder { + return apply { + filters?.forEach { queryParam(it.first.toString(), it.second) } + } + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt index 345186bc..e45e4160 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt @@ -17,16 +17,18 @@ package nl.nlportal.openklant.client.path import nl.nlportal.openklant.client.OpenKlant2Client import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator +import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilters import nl.nlportal.openklant.client.domain.ResultPage import org.springframework.http.MediaType -import org.springframework.util.MultiValueMapAdapter import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.awaitBody class PartijIdentificatoren(val client: OpenKlant2Client) : KlantInteractiesPath() { override val path: String = "/partij-identificatoren" - suspend fun find(searchVariables: MultiValueMapAdapter? = null): List { + suspend fun find( + searchFilters: List>? = null, + ): List { val response: ResultPage = client .webClient() @@ -34,7 +36,7 @@ class PartijIdentificatoren(val client: OpenKlant2Client) : KlantInteractiesPath .uri { uriBuilder -> uriBuilder .path(path) - searchVariables?.let { uriBuilder.queryParams(it) } + .queryParams(searchFilters) uriBuilder.build() } .accept(MediaType.APPLICATION_JSON) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt index fdce9c87..c10dbc47 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -17,9 +17,9 @@ package nl.nlportal.openklant.client.path import nl.nlportal.openklant.client.OpenKlant2Client import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters import nl.nlportal.openklant.client.domain.ResultPage import org.springframework.http.MediaType -import org.springframework.util.MultiValueMap import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.awaitBodilessEntity import org.springframework.web.reactive.function.client.awaitBody @@ -29,7 +29,7 @@ import java.util.UUID class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { override val path = "/partijen" - suspend fun find(queryParams: MultiValueMap? = null): OpenKlant2Partij? { + suspend fun find(searchFilters: List>? = null): OpenKlant2Partij? { val response: ResultPage = client .webClient() @@ -37,7 +37,7 @@ class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { .uri { uriBuilder -> uriBuilder .path(path) - queryParams?.let { uriBuilder.queryParams(it) } + .queryParams(filters = searchFilters) uriBuilder.build() } .accept(MediaType.APPLICATION_JSON) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index 2bfc385c..db05ac9b 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -24,10 +24,12 @@ import nl.nlportal.openklant.client.domain.OpenKlant2Identificator import nl.nlportal.openklant.client.domain.OpenKlant2IdentificeerdePartij import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator +import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilters +import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID +import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters import nl.nlportal.openklant.client.domain.asSoortPartij import nl.nlportal.openklant.client.path.PartijIdentificatoren import nl.nlportal.openklant.client.path.Partijen -import org.springframework.util.MultiValueMapAdapter import org.springframework.web.reactive.function.client.WebClientResponseException import java.util.UUID @@ -36,11 +38,9 @@ class OpenKlant2Service( ) { suspend fun findPartij(authentication: CommonGroundAuthentication): OpenKlant2Partij? { val searchVariables = - MultiValueMapAdapter( - mapOf( - "soortPartij" to listOf(authentication.asSoortPartij()), - "partijIdentificator__objectId" to listOf(authentication.userId), - ), + listOf( + OpenKlant2PartijenFilters.SOORT_PARTIJ to authentication.asSoortPartij(), + OpenKlant2PartijenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID to authentication.userId, ) try { @@ -106,15 +106,13 @@ class OpenKlant2Service( } suspend fun findPartijIdentificatoren(authentication: CommonGroundAuthentication): List? { - val searchVariables = - MultiValueMapAdapter( - mapOf( - "partij_identificator_object_id" to listOf(authentication.userId), - ), + val searchFilters: List> = + listOf( + PARTIJ_IDENTIFICATOR_OBJECT_ID to authentication.userId, ) try { - return openKlant2Client.path().find(searchVariables) + return openKlant2Client.path().find(searchFilters) } catch (ex: WebClientResponseException) { logger.debug("Failed to find Partij Identificatoren: ${ex.responseBodyAsString}", ex) return null diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2ClientTest.kt similarity index 99% rename from zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt rename to zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2ClientTest.kt index 46395a59..c7b5fa18 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlantClientTest.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2ClientTest.kt @@ -26,7 +26,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.web.reactive.function.client.awaitBodilessEntity -class OpenKlantClientTest { +class OpenKlant2ClientTest { private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration private lateinit var mockServer: MockWebServer private lateinit var openKlant2Client: OpenKlant2Client diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationIT.kt similarity index 98% rename from zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt rename to zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationIT.kt index dd4ea710..85566d21 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/ModuleConfigurationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationIT.kt @@ -42,7 +42,7 @@ import java.nio.charset.Charset @ActiveProfiles("openklant-disabled") @AutoConfigureWebTestClient(timeout = "36000") @TestInstance(TestInstance.Lifecycle.PER_METHOD) -class ModuleConfigurationIT( +class OpenKlant2ModuleConfigurationIT( @Autowired private val webTestClient: WebTestClient, @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, ) { diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt similarity index 99% rename from zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt rename to zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index 3b938d62..52b55398 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -49,7 +49,7 @@ import java.nio.charset.Charset @Tag("integration") @AutoConfigureWebTestClient(timeout = "36000") @TestInstance(TestInstance.Lifecycle.PER_METHOD) -class PartijMutationIT( +class OpenKlant2PartijMutationIT( @Autowired private val webTestClient: WebTestClient, ) { @SpyBean diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt similarity index 99% rename from zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt rename to zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt index 7e012af9..96cc4d3f 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/PartijQueryIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt @@ -49,7 +49,7 @@ import java.nio.charset.Charset @Tag("integration") @AutoConfigureWebTestClient(timeout = "36000") @TestInstance(TestInstance.Lifecycle.PER_METHOD) -class PartijQueryIT( +class OpenKlant2PartijQueryIT( @Autowired private val webTestClient: WebTestClient, ) { @SpyBean From 7c74b2edbc7308d83d11bbf5ce422eff558c04cb Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Thu, 3 Oct 2024 15:45:16 +0200 Subject: [PATCH 07/19] * separate contactgegevens api from klantinteracties api in OpenKlant Module --- app/src/main/resources/config/application.yml | 3 ++- .../autoconfigure/OpenKlantAutoConfiguration.kt | 10 +++++----- .../autoconfigure/OpenKlantModuleConfiguration.kt | 10 +++++++--- ...t2Client.kt => OpenKlant2KlantinteractiesClient.kt} | 4 ++-- .../openklant/client/path/PartijIdentificatoren.kt | 4 ++-- .../nl/nlportal/openklant/client/path/Partijen.kt | 4 ++-- .../nl/nlportal/openklant/service/OpenKlant2Service.kt | 4 ++-- ...Test.kt => OpenKlant2KlantinteractiesClientTest.kt} | 8 ++++---- .../openklant/service/OpenKlant2ServiceTest.kt | 8 ++++---- .../src/test/resources/config/application.yml | 3 ++- 10 files changed, 32 insertions(+), 26 deletions(-) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/{OpenKlant2Client.kt => OpenKlant2KlantinteractiesClient.kt} (93%) rename zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/{OpenKlant2ClientTest.kt => OpenKlant2KlantinteractiesClientTest.kt} (89%) diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index db449d89..41f49291 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -76,7 +76,8 @@ nl-portal: openklant: enabled: true properties: - url: http://localhost:8007/klantinteracties/api/v1 + contactgegevens-api-url: http://localhost:8007/contactgegevens/api/v1 + klantinteracties-api-url: http://localhost:8007/klantinteracties/api/v1 token: ac045222c9e7cde8120b48735560f9b920bb58cd zgw: catalogiapi: diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index c28348d9..46889060 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -18,7 +18,7 @@ package nl.nlportal.openklant.autoconfigure import com.expediagroup.graphql.server.operations.Mutation import com.expediagroup.graphql.server.operations.Query import mu.KotlinLogging -import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import nl.nlportal.openklant.graphql.PartijMutation import nl.nlportal.openklant.graphql.PartijQuery import nl.nlportal.openklant.service.OpenKlant2Service @@ -32,14 +32,14 @@ import org.springframework.context.annotation.Bean ) class OpenKlantAutoConfiguration { @Bean - @ConditionalOnMissingBean(OpenKlant2Client::class) - fun openKlant2Client(openklantModuleConfiguration: OpenKlantModuleConfiguration): OpenKlant2Client { - return OpenKlant2Client(openKlantConfigurationProperties = openklantModuleConfiguration.properties) + @ConditionalOnMissingBean(OpenKlant2KlantinteractiesClient::class) + fun openKlant2Client(openklantModuleConfiguration: OpenKlantModuleConfiguration): OpenKlant2KlantinteractiesClient { + return OpenKlant2KlantinteractiesClient(openKlantConfigurationProperties = openklantModuleConfiguration.properties) } @Bean @ConditionalOnMissingBean(OpenKlant2Service::class) - fun openKlant2Service(openklant2Client: OpenKlant2Client): OpenKlant2Service { + fun openKlant2Service(openklant2Client: OpenKlant2KlantinteractiesClient): OpenKlant2Service { return OpenKlant2Service(openklant2Client) } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt index a2e8c1e1..0ae22de0 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt @@ -25,8 +25,11 @@ data class OpenKlantModuleConfiguration( ) { init { if (enabled) { - requireNotNull(properties.url) { - "OpenKlant URL not configured" + requireNotNull(properties.contactgegevensApiUrl) { + "OpenKlant Contactgegevens API URL not configured" + } + requireNotNull(properties.klantinteractiesApiUrl) { + "OpenKlant Klantinteracties API URL not configured" } requireNotNull(properties.token) { "OpenKlant token not configured" @@ -35,7 +38,8 @@ data class OpenKlantModuleConfiguration( } data class OpenKlantConfigurationProperties( - var url: URI? = null, + var contactgegevensApiUrl: URI? = null, + var klantinteractiesApiUrl: URI? = null, var token: String? = null, ) } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2KlantinteractiesClient.kt similarity index 93% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2KlantinteractiesClient.kt index 766103f0..b27f4854 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2Client.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/OpenKlant2KlantinteractiesClient.kt @@ -28,14 +28,14 @@ import reactor.netty.http.client.HttpClient import reactor.netty.transport.logging.AdvancedByteBufFormat.TEXTUAL import kotlin.reflect.full.primaryConstructor -class OpenKlant2Client(private val openKlantConfigurationProperties: OpenKlantConfigurationProperties) { +class OpenKlant2KlantinteractiesClient(private val openKlantConfigurationProperties: OpenKlantConfigurationProperties) { inline fun path(): P { return P::class.primaryConstructor!!.call(this) } fun webClient(): WebClient { return webclientBuilder - .baseUrl(openKlantConfigurationProperties.url.toString()) + .baseUrl(openKlantConfigurationProperties.klantinteractiesApiUrl.toString()) .defaultHeader("Accept-Crs", "EPSG:4326") .defaultHeader("Content-Crs", "EPSG:4326") .defaultHeader("Authorization", "Token ${openKlantConfigurationProperties.token}") diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt index e45e4160..0b27c098 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt @@ -15,7 +15,7 @@ */ package nl.nlportal.openklant.client.path -import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilters import nl.nlportal.openklant.client.domain.ResultPage @@ -23,7 +23,7 @@ import org.springframework.http.MediaType import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.awaitBody -class PartijIdentificatoren(val client: OpenKlant2Client) : KlantInteractiesPath() { +class PartijIdentificatoren(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { override val path: String = "/partij-identificatoren" suspend fun find( diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt index c10dbc47..ce0f3d03 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -15,7 +15,7 @@ */ package nl.nlportal.openklant.client.path -import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters import nl.nlportal.openklant.client.domain.ResultPage @@ -26,7 +26,7 @@ import org.springframework.web.reactive.function.client.awaitBody import org.springframework.web.reactive.function.client.awaitBodyOrNull import java.util.UUID -class Partijen(val client: OpenKlant2Client) : KlantInteractiesPath() { +class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { override val path = "/partijen" suspend fun find(searchFilters: List>? = null): OpenKlant2Partij? { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index db05ac9b..c16b11d3 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -19,7 +19,7 @@ import com.fasterxml.jackson.module.kotlin.convertValue import mu.KotlinLogging import nl.nlportal.commonground.authentication.CommonGroundAuthentication import nl.nlportal.core.util.Mapper -import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import nl.nlportal.openklant.client.domain.OpenKlant2Identificator import nl.nlportal.openklant.client.domain.OpenKlant2IdentificeerdePartij import nl.nlportal.openklant.client.domain.OpenKlant2Partij @@ -34,7 +34,7 @@ import org.springframework.web.reactive.function.client.WebClientResponseExcepti import java.util.UUID class OpenKlant2Service( - private val openKlant2Client: OpenKlant2Client, + private val openKlant2Client: OpenKlant2KlantinteractiesClient, ) { suspend fun findPartij(authentication: CommonGroundAuthentication): OpenKlant2Partij? { val searchVariables = diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2ClientTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2KlantinteractiesClientTest.kt similarity index 89% rename from zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2ClientTest.kt rename to zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2KlantinteractiesClientTest.kt index c7b5fa18..f5a634df 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2ClientTest.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/OpenKlant2KlantinteractiesClientTest.kt @@ -26,10 +26,10 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.web.reactive.function.client.awaitBodilessEntity -class OpenKlant2ClientTest { +class OpenKlant2KlantinteractiesClientTest { private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration private lateinit var mockServer: MockWebServer - private lateinit var openKlant2Client: OpenKlant2Client + private lateinit var openKlant2Client: OpenKlant2KlantinteractiesClient private lateinit var hostUrl: String private lateinit var apiUrl: String @@ -45,11 +45,11 @@ class OpenKlant2ClientTest { enabled = true, properties = OpenKlantConfigurationProperties( - url = mockServer.url("/myapi/v1").toUri(), + klantinteractiesApiUrl = mockServer.url("/myapi/v1").toUri(), token = "SuperSecretToken1234", ), ) - openKlant2Client = OpenKlant2Client(openklantModuleConfiguration.properties) + openKlant2Client = OpenKlant2KlantinteractiesClient(openklantModuleConfiguration.properties) } @AfterEach diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt index 19fe8fa2..0d5faedf 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/service/OpenKlant2ServiceTest.kt @@ -17,7 +17,7 @@ package nl.nlportal.openklant.service import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties -import nl.nlportal.openklant.client.OpenKlant2Client +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import okhttp3.mockwebserver.MockWebServer import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach @@ -25,7 +25,7 @@ import org.junit.jupiter.api.BeforeEach class OpenKlant2ServiceTest() { private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration private lateinit var mockServer: MockWebServer - private lateinit var openKlant2Client: OpenKlant2Client + private lateinit var openKlant2Client: OpenKlant2KlantinteractiesClient private lateinit var hostUrl: String private lateinit var apiUrl: String @@ -41,11 +41,11 @@ class OpenKlant2ServiceTest() { enabled = true, properties = OpenKlantConfigurationProperties( - url = mockServer.url("/myapi/v1").toUri(), + klantinteractiesApiUrl = mockServer.url("/myapi/v1").toUri(), token = "SuperSecretToken1234", ), ) - openKlant2Client = OpenKlant2Client(openklantModuleConfiguration.properties) + openKlant2Client = OpenKlant2KlantinteractiesClient(openklantModuleConfiguration.properties) } @AfterEach diff --git a/zgw/openklant/src/test/resources/config/application.yml b/zgw/openklant/src/test/resources/config/application.yml index 56dc4a3d..718c1c00 100644 --- a/zgw/openklant/src/test/resources/config/application.yml +++ b/zgw/openklant/src/test/resources/config/application.yml @@ -7,7 +7,8 @@ nl-portal: openklant: enabled: true properties: - url: http://localhost:9007/klantinteracties/api/v1 + contactgegevens-api-url: http://localhost:9007/contactgegevens/api/v1 + klantinteracties-api-url: http://localhost:9007/klantinteracties/api/v1 token: ac045222c9e7cde8120b48735560f9b920bb58cd spring: From 5ba4541807f682a10a197f9a28df92451c662ab7 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Thu, 3 Oct 2024 16:16:12 +0200 Subject: [PATCH 08/19] * more gradle test fixes * expand filtering with page --- app/src/main/resources/config/application.yml | 1 - gradle/testing.gradle.kts | 2 ++ .../OpenKlantModuleConfiguration.kt | 3 --- .../client/domain/PartijIdentificatoren.kt | 1 + .../openklant/client/domain/Partijen.kt | 1 + .../openklant/client/path/Partijen.kt | 20 ++++++++++++++++++- .../src/test/resources/config/application.yml | 3 +-- 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index 41f49291..33d12cb6 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -76,7 +76,6 @@ nl-portal: openklant: enabled: true properties: - contactgegevens-api-url: http://localhost:8007/contactgegevens/api/v1 klantinteracties-api-url: http://localhost:8007/klantinteracties/api/v1 token: ac045222c9e7cde8120b48735560f9b920bb58cd zgw: diff --git a/gradle/testing.gradle.kts b/gradle/testing.gradle.kts index 8dd5a23e..53fa34cc 100644 --- a/gradle/testing.gradle.kts +++ b/gradle/testing.gradle.kts @@ -25,6 +25,8 @@ tasks.named("test") { useJUnitPlatform { excludeTags("integration") } +} +tasks.named("check") { dependsOn(tasks.getByName("integrationTest")) } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt index 0ae22de0..0ebb196e 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantModuleConfiguration.kt @@ -25,9 +25,6 @@ data class OpenKlantModuleConfiguration( ) { init { if (enabled) { - requireNotNull(properties.contactgegevensApiUrl) { - "OpenKlant Contactgegevens API URL not configured" - } requireNotNull(properties.klantinteractiesApiUrl) { "OpenKlant Klantinteracties API URL not configured" } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt index 392accdf..2e45c03a 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/PartijIdentificatoren.kt @@ -44,6 +44,7 @@ enum class OpenKlant2PartijIdentificatorenFilters( @JsonValue val value: String, ) : OpenKlant2Filters { ANDERE_PARTIJ_IDENTIFICATOR("andere_partij_identificator"), + PAGE("page"), PARTIJ_IDENTIFICATOR_CODE_OBJECTTYPE("partij_identificator_code_objecttype"), PARTIJ_IDENTIFICATOR_CODE_SOORT_OBJECT_ID("partij_identificator_code_soort_object_id"), PARTIJ_IDENTIFICATOR_OBJECT_ID("partij_identificator_object_id"), diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt index 89fe7a52..dd09aa60 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt @@ -143,6 +143,7 @@ enum class OpenKlant2PartijenFilters( PARTIJ_IDENTIFICATOR_CODE_REGISTER("partij_identificator__code_register"), CATEGORIERELATIE__CATEGORIE_NAAM("categorierelatie__categorie__naam"), NUMMER("nummer"), + PAGE("page"), INDICATIE_GEHEIMHOUDING("indicatie_geheimhouding"), INDICATIE_ACTIEF("indicatie_actief"), SOORT_PARTIJ("soort_partij"), diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt index ce0f3d03..01a42947 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -38,7 +38,7 @@ class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesP uriBuilder .path(path) .queryParams(filters = searchFilters) - uriBuilder.build() + .build() } .accept(MediaType.APPLICATION_JSON) .retrieve() @@ -47,6 +47,24 @@ class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesP return response.results.singleOrNull() } + suspend fun get(searchFilters: List>? = null): List? { + val response: ResultPage? = + client + .webClient() + .get() + .uri { uriBuilder -> + uriBuilder + .path("$path") + .queryParams(filters = searchFilters) + .build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodyOrNull() + + return response?.results + } + suspend fun get(partijId: UUID): OpenKlant2Partij? { val response: OpenKlant2Partij? = client diff --git a/zgw/openklant/src/test/resources/config/application.yml b/zgw/openklant/src/test/resources/config/application.yml index 718c1c00..ce1caab3 100644 --- a/zgw/openklant/src/test/resources/config/application.yml +++ b/zgw/openklant/src/test/resources/config/application.yml @@ -7,7 +7,6 @@ nl-portal: openklant: enabled: true properties: - contactgegevens-api-url: http://localhost:9007/contactgegevens/api/v1 klantinteracties-api-url: http://localhost:9007/klantinteracties/api/v1 token: ac045222c9e7cde8120b48735560f9b920bb58cd @@ -42,5 +41,5 @@ nl-portal: openklant: enabled: true properties: - url: + klantinteracties-api-url: token: \ No newline at end of file From 029f02daa26e252a32a8302dc3637517ffeb1d3c Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Fri, 4 Oct 2024 10:48:15 +0200 Subject: [PATCH 09/19] * added partijen path test * refactored some functions and class names --- .../client/path/KlantInteractiesPath.kt | 4 +- .../client/path/PartijIdentificatoren.kt | 41 +++++- .../openklant/client/path/Partijen.kt | 31 ++-- .../openklant/graphql/PartijMutation.kt | 6 +- ...artijRequest.kt => CreatePartijRequest.kt} | 2 +- .../nl/nlportal/openklant/TestHelper.kt | 20 +-- .../client/path/OpenKlant2PartijenPathTest.kt | 138 ++++++++++++++++++ 7 files changed, 200 insertions(+), 42 deletions(-) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/{PartijRequest.kt => CreatePartijRequest.kt} (98%) create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt index 2b42f0eb..3bb5a9da 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/KlantInteractiesPath.kt @@ -21,9 +21,9 @@ import org.springframework.web.util.UriBuilder open class KlantInteractiesPath { open val path: String = "/" - fun UriBuilder.queryParams(filters: List>? = null): UriBuilder { + fun UriBuilder.applyFilters(filters: List>? = null): UriBuilder { return apply { - filters?.forEach { queryParam(it.first.toString(), it.second) } + filters?.forEach { queryParam(it.first.toString(), it.second.toString()) } } } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt index 0b27c098..b1f8691d 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt @@ -21,14 +21,15 @@ import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilter import nl.nlportal.openklant.client.domain.ResultPage import org.springframework.http.MediaType import org.springframework.web.reactive.function.BodyInserters +import org.springframework.web.reactive.function.client.awaitBodilessEntity import org.springframework.web.reactive.function.client.awaitBody +import org.springframework.web.reactive.function.client.awaitBodyOrNull +import java.util.UUID class PartijIdentificatoren(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { override val path: String = "/partij-identificatoren" - suspend fun find( - searchFilters: List>? = null, - ): List { + suspend fun find(searchFilters: List>? = null): List { val response: ResultPage = client .webClient() @@ -36,7 +37,7 @@ class PartijIdentificatoren(val client: OpenKlant2KlantinteractiesClient) : Klan .uri { uriBuilder -> uriBuilder .path(path) - .queryParams(searchFilters) + .applyFilters(searchFilters) uriBuilder.build() } .accept(MediaType.APPLICATION_JSON) @@ -63,4 +64,36 @@ class PartijIdentificatoren(val client: OpenKlant2KlantinteractiesClient) : Klan return response } + + suspend fun put(partijIdentificatorRequest: OpenKlant2PartijIdentificator): OpenKlant2PartijIdentificator? { + val response: OpenKlant2PartijIdentificator? = + client + .webClient() + .put() + .uri { uriBuilder -> + uriBuilder + .path("$path/${partijIdentificatorRequest.uuid}") + .build() + } + .body(BodyInserters.fromValue(partijIdentificatorRequest)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodyOrNull() + + return response + } + + suspend fun delete(uuid: UUID) { + client + .webClient() + .delete() + .uri { uriBuilder -> + uriBuilder + .path("$path/$uuid") + .build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodilessEntity() + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt index 01a42947..75707f02 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -29,33 +29,20 @@ import java.util.UUID class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { override val path = "/partijen" - suspend fun find(searchFilters: List>? = null): OpenKlant2Partij? { - val response: ResultPage = - client - .webClient() - .get() - .uri { uriBuilder -> - uriBuilder - .path(path) - .queryParams(filters = searchFilters) - .build() - } - .accept(MediaType.APPLICATION_JSON) - .retrieve() - .awaitBody() - - return response.results.singleOrNull() + suspend fun find(searchFilters: List>? = null): OpenKlant2Partij? { + val results = get(searchFilters) + return results?.singleOrNull() } - suspend fun get(searchFilters: List>? = null): List? { + suspend fun get(searchFilters: List>? = null): List? { val response: ResultPage? = client .webClient() .get() .uri { uriBuilder -> uriBuilder - .path("$path") - .queryParams(filters = searchFilters) + .path(path) + .applyFilters(filters = searchFilters) .build() } .accept(MediaType.APPLICATION_JSON) @@ -101,7 +88,7 @@ class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesP } suspend fun put(partij: OpenKlant2Partij): OpenKlant2Partij? { - val response: ResultPage = + val response: OpenKlant2Partij? = client .webClient() .put() @@ -113,9 +100,9 @@ class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesP .body(BodyInserters.fromValue(partij)) .accept(MediaType.APPLICATION_JSON) .retrieve() - .awaitBody() + .awaitBodyOrNull() - return response.results.singleOrNull() + return response } suspend fun delete(uuid: UUID) { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index f09c60b7..a84f6a8d 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -20,7 +20,7 @@ import com.expediagroup.graphql.server.operations.Mutation import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY import nl.nlportal.openklant.client.domain.OpenKlant2Partij -import nl.nlportal.openklant.graphql.domain.PartijRequest +import nl.nlportal.openklant.graphql.domain.CreatePartijRequest import nl.nlportal.openklant.service.OpenKlant2Service class PartijMutation( @@ -29,7 +29,7 @@ class PartijMutation( @GraphQLDescription("Create Partij for user") suspend fun createPartij( dfe: DataFetchingEnvironment, - partijRequest: PartijRequest, + partijRequest: CreatePartijRequest, ): OpenKlant2Partij? { return openklant2Service.createPartijWithIdentificator( authentication = dfe.graphQlContext.get(AUTHENTICATION_KEY), @@ -40,7 +40,7 @@ class PartijMutation( @GraphQLDescription("Update user Partij") suspend fun updatePartij( dfe: DataFetchingEnvironment, - partijRequest: PartijRequest, + partijRequest: CreatePartijRequest, ): OpenKlant2Partij { return openklant2Service.updatePartij( dfe.graphQlContext.get(AUTHENTICATION_KEY), diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/CreatePartijRequest.kt similarity index 98% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/CreatePartijRequest.kt index e5a17b0a..dd180202 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/CreatePartijRequest.kt @@ -25,7 +25,7 @@ import nl.nlportal.openklant.client.domain.SoortPartij.CONTACTPERSOON import nl.nlportal.openklant.client.domain.SoortPartij.ORGANISATIE import nl.nlportal.openklant.client.domain.SoortPartij.PERSOON -data class PartijRequest( +data class CreatePartijRequest( val indicatieGeheimhouding: Boolean, val indicatieActief: Boolean, val soortPartij: SoortPartij, diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt index 788aa0a3..15a34426 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/TestHelper.kt @@ -16,6 +16,16 @@ package nl.nlportal.openklant object TestHelper { + val emptyPage = + """ + { + "count": 0, + "next": null, + "previous": null, + "results": [] + } + """.trimIndent() + object Partijen { val createPartijRequest = """ @@ -248,15 +258,5 @@ object TestHelper { ] } """.trimIndent() - - val emptyPage = - """ - { - "count": 0, - "next": null, - "previous": null, - "results": [] - } - """.trimIndent() } } \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt new file mode 100644 index 00000000..c6a1f8b4 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt @@ -0,0 +1,138 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client.path + +import kotlinx.coroutines.test.runTest +import nl.nlportal.openklant.TestHelper +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration +import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient +import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters +import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID +import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters.SOORT_PARTIJ +import nl.nlportal.openklant.client.domain.SoortPartij +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.mockito.Mockito.times + +class OpenKlant2PartijenPathTest { + private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration + private lateinit var mockServer: MockWebServer + private lateinit var openKlant2Client: OpenKlant2KlantinteractiesClient + + @BeforeEach + fun setUp() { + mockServer = MockWebServer() + mockServer.start() + + openklantModuleConfiguration = + OpenKlantModuleConfiguration( + enabled = true, + properties = + OpenKlantConfigurationProperties( + klantinteractiesApiUrl = mockServer.url(API_PATH).toUri(), + token = "SuperSecretToken1234", + ), + ) + openKlant2Client = OpenKlant2KlantinteractiesClient(openklantModuleConfiguration.properties) + } + + @AfterEach + internal fun tearDown() { + mockServer.shutdown() + } + + @Test + fun `should apply path to request`() = + runTest { + // when + mockServer.enqueue( + MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json"), + ) + + // given + openKlant2Client.path().get() + val request = mockServer.takeRequest() + + // then + assertEquals("$API_PATH$PATH", request.requestUrl?.encodedPath) + } + + @Test + fun `get - should apply query parameters to request`() = + runTest { + // when + val filters = + listOf( + OpenKlant2PartijenFilters.PAGE to 1, + SOORT_PARTIJ to SoortPartij.PERSOON, + PARTIJ_IDENTIFICATOR_OBJECT_ID to "999990755", + ) + mockServer.enqueue( + MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json"), + ) + + // given + openKlant2Client.path().get(filters) + val request = mockServer.takeRequest() + + // then + assertEquals("1", request.requestUrl?.queryParameter("page")) + assertEquals("persoon", request.requestUrl?.queryParameter(SOORT_PARTIJ.toString())) + assertEquals("999990755", request.requestUrl?.queryParameter(PARTIJ_IDENTIFICATOR_OBJECT_ID.toString())) + } + + @Test + fun `find - should return single`() = + runTest { + // when + val filters = + listOf( + OpenKlant2PartijenFilters.PAGE to 1, + SOORT_PARTIJ to SoortPartij.PERSOON, + PARTIJ_IDENTIFICATOR_OBJECT_ID to "999990755", + ) + mockServer.enqueue( + MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json") + .setBody(TestHelper.Partijen.persoonPartijResponse), + ) + + // given + val response = openKlant2Client.path().find(filters) + + // then + assertNotNull(response) + assertTrue(response is OpenKlant2Partij) + } + + companion object { + const val PATH = "/partijen" + const val API_PATH = "/myapi/v1" + } +} \ No newline at end of file From ca546405397ce0ced4a01d61aa3a7e526eedb2fe Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Fri, 4 Oct 2024 12:05:58 +0200 Subject: [PATCH 10/19] * wip PartijMutation --- .../OpenKlantAutoConfiguration.kt | 5 - .../openklant/client/path/Partijen.kt | 5 - .../openklant/graphql/PartijMutation.kt | 33 ++--- .../nlportal/openklant/graphql/PartijQuery.kt | 2 +- ...reatePartijRequest.kt => PartijRequest.kt} | 2 +- .../graphql/domain/PartijResponse.kt | 43 +++++++ .../openklant/service/OpenKlant2Service.kt | 8 +- .../client/path/OpenKlant2PartijenPathTest.kt | 30 ----- .../graphql/OpenKlant2PartijMutationIT.kt | 22 ++-- .../graphql/OpenKlant2PartijQueryIT.kt | 4 +- .../config/graphql/createPartij.graphql | 118 +----------------- 11 files changed, 79 insertions(+), 193 deletions(-) rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/{CreatePartijRequest.kt => PartijRequest.kt} (98%) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index 46889060..2d3f69e2 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -17,7 +17,6 @@ package nl.nlportal.openklant.autoconfigure import com.expediagroup.graphql.server.operations.Mutation import com.expediagroup.graphql.server.operations.Query -import mu.KotlinLogging import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import nl.nlportal.openklant.graphql.PartijMutation import nl.nlportal.openklant.graphql.PartijQuery @@ -56,8 +55,4 @@ class OpenKlantAutoConfiguration { fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { return PartijMutation(openKlant2Service) } - - companion object { - private val logger = KotlinLogging.logger {} - } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt index 75707f02..c83c3591 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/Partijen.kt @@ -29,11 +29,6 @@ import java.util.UUID class Partijen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { override val path = "/partijen" - suspend fun find(searchFilters: List>? = null): OpenKlant2Partij? { - val results = get(searchFilters) - return results?.singleOrNull() - } - suspend fun get(searchFilters: List>? = null): List? { val response: ResultPage? = client diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index a84f6a8d..4a8b9f62 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -19,8 +19,8 @@ import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.server.operations.Mutation import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY -import nl.nlportal.openklant.client.domain.OpenKlant2Partij -import nl.nlportal.openklant.graphql.domain.CreatePartijRequest +import nl.nlportal.openklant.graphql.domain.PartijRequest +import nl.nlportal.openklant.graphql.domain.PartijResponse import nl.nlportal.openklant.service.OpenKlant2Service class PartijMutation( @@ -29,22 +29,27 @@ class PartijMutation( @GraphQLDescription("Create Partij for user") suspend fun createPartij( dfe: DataFetchingEnvironment, - partijRequest: CreatePartijRequest, - ): OpenKlant2Partij? { - return openklant2Service.createPartijWithIdentificator( - authentication = dfe.graphQlContext.get(AUTHENTICATION_KEY), - partijRequest = partijRequest.asOpenKlant2Partij(), - ) + partijRequest: PartijRequest, + ): PartijResponse? { + val partij = + openklant2Service.createPartijWithIdentificator( + authentication = dfe.graphQlContext.get(AUTHENTICATION_KEY), + partij = partijRequest.asOpenKlant2Partij(), + ) + return partij?.let { PartijResponse.fromOpenKlant2Partij(partij) } } @GraphQLDescription("Update user Partij") suspend fun updatePartij( dfe: DataFetchingEnvironment, - partijRequest: CreatePartijRequest, - ): OpenKlant2Partij { - return openklant2Service.updatePartij( - dfe.graphQlContext.get(AUTHENTICATION_KEY), - partijRequest.asOpenKlant2Partij(), - ) + partijRequest: PartijRequest, + ): PartijResponse { + val partij = + openklant2Service.updatePartij( + dfe.graphQlContext.get(AUTHENTICATION_KEY), + partijRequest.asOpenKlant2Partij(), + ) + + return PartijResponse.fromOpenKlant2Partij(partij) } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt index 973cd022..a839ceea 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt @@ -29,7 +29,7 @@ class PartijQuery( ) : Query { @GraphQLDescription("Find the Partij of the authenticated user.") suspend fun findUserPartij(dfe: DataFetchingEnvironment): OpenKlant2Partij? { - return openklant2Service.findPartij(dfe.graphQlContext.get(AUTHENTICATION_KEY)) + return openklant2Service.findPartijByAuthentication(dfe.graphQlContext.get(AUTHENTICATION_KEY)) } @GraphQLDescription("Get Partij by Id for authenticated user.") diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/CreatePartijRequest.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt similarity index 98% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/CreatePartijRequest.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt index dd180202..e5a17b0a 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/CreatePartijRequest.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt @@ -25,7 +25,7 @@ import nl.nlportal.openklant.client.domain.SoortPartij.CONTACTPERSOON import nl.nlportal.openklant.client.domain.SoortPartij.ORGANISATIE import nl.nlportal.openklant.client.domain.SoortPartij.PERSOON -data class CreatePartijRequest( +data class PartijRequest( val indicatieGeheimhouding: Boolean, val indicatieActief: Boolean, val soortPartij: SoortPartij, diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt new file mode 100644 index 00000000..d7f646dc --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql.domain + +import nl.nlportal.openklant.client.domain.ContactpersoonIdentificatie +import nl.nlportal.openklant.client.domain.OpenKlant2Partij +import nl.nlportal.openklant.client.domain.OrganisatieIdentificatie +import nl.nlportal.openklant.client.domain.PersoonsIdentificatie +import nl.nlportal.openklant.client.domain.SoortPartij + +data class PartijResponse( + val indicatieGeheimhouding: Boolean, + val indicatieActief: Boolean, + val soortPartij: SoortPartij, + val persoonIdentification: PersoonsIdentificatie? = null, + val organisatieIdentificatie: OrganisatieIdentificatie? = null, + val contactpersoonIdentificatie: ContactpersoonIdentificatie? = null, +) { + companion object { + fun fromOpenKlant2Partij(openKlant2Partij: OpenKlant2Partij): PartijResponse = + PartijResponse( + indicatieGeheimhouding = openKlant2Partij.indicatieGeheimhouding, + indicatieActief = openKlant2Partij.indicatieActief, + soortPartij = openKlant2Partij.soortPartij, + persoonIdentification = openKlant2Partij.partijIdentificatie as? PersoonsIdentificatie, + organisatieIdentificatie = openKlant2Partij.partijIdentificatie as? OrganisatieIdentificatie, + contactpersoonIdentificatie = openKlant2Partij.partijIdentificatie as? ContactpersoonIdentificatie, + ) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index c16b11d3..46f4f860 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -36,7 +36,7 @@ import java.util.UUID class OpenKlant2Service( private val openKlant2Client: OpenKlant2KlantinteractiesClient, ) { - suspend fun findPartij(authentication: CommonGroundAuthentication): OpenKlant2Partij? { + suspend fun findPartijByAuthentication(authentication: CommonGroundAuthentication): OpenKlant2Partij? { val searchVariables = listOf( OpenKlant2PartijenFilters.SOORT_PARTIJ to authentication.asSoortPartij(), @@ -44,7 +44,7 @@ class OpenKlant2Service( ) try { - return openKlant2Client.path().find(searchVariables) + return openKlant2Client.path().get(searchVariables)?.singleOrNull() } catch (ex: WebClientResponseException) { logger.debug("Failed to find Partij: ${ex.responseBodyAsString}", ex) return null @@ -62,7 +62,7 @@ class OpenKlant2Service( suspend fun createPartijWithIdentificator( authentication: CommonGroundAuthentication, - partijRequest: OpenKlant2Partij, + partij: OpenKlant2Partij, ): OpenKlant2Partij? { val partijIdentificator = OpenKlant2PartijIdentificator( @@ -73,7 +73,7 @@ class OpenKlant2Service( ) val partijResponse = try { - openKlant2Client.path().create(partijRequest) + openKlant2Client.path().create(partij) .also { try { openKlant2Client diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt index c6a1f8b4..396a2bd1 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/client/path/OpenKlant2PartijenPathTest.kt @@ -16,11 +16,9 @@ package nl.nlportal.openklant.client.path import kotlinx.coroutines.test.runTest -import nl.nlportal.openklant.TestHelper import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration.OpenKlantConfigurationProperties import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient -import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters.SOORT_PARTIJ @@ -29,11 +27,8 @@ import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.mockito.Mockito.times class OpenKlant2PartijenPathTest { private lateinit var openklantModuleConfiguration: OpenKlantModuleConfiguration @@ -106,31 +101,6 @@ class OpenKlant2PartijenPathTest { assertEquals("999990755", request.requestUrl?.queryParameter(PARTIJ_IDENTIFICATOR_OBJECT_ID.toString())) } - @Test - fun `find - should return single`() = - runTest { - // when - val filters = - listOf( - OpenKlant2PartijenFilters.PAGE to 1, - SOORT_PARTIJ to SoortPartij.PERSOON, - PARTIJ_IDENTIFICATOR_OBJECT_ID to "999990755", - ) - mockServer.enqueue( - MockResponse() - .setResponseCode(200) - .addHeader("Content-Type", "application/json") - .setBody(TestHelper.Partijen.persoonPartijResponse), - ) - - // given - val response = openKlant2Client.path().find(filters) - - // then - assertNotNull(response) - assertTrue(response is OpenKlant2Partij) - } - companion object { const val PATH = "/partijen" const val API_PATH = "/myapi/v1" diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index 52b55398..37513e55 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -17,20 +17,14 @@ package nl.nlportal.openklant.graphql import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.readValue -import com.fasterxml.jackson.module.kotlin.treeToValue import kotlinx.coroutines.test.runTest import nl.nlportal.commonground.authentication.WithBurgerUser import nl.nlportal.core.util.Mapper -import nl.nlportal.openklant.client.domain.PersoonsIdentificatie -import nl.nlportal.openklant.client.domain.SoortPartij import nl.nlportal.openklant.service.OpenKlant2Service -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.assertDoesNotThrow import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.kotlin.any @@ -56,7 +50,7 @@ class OpenKlant2PartijMutationIT( lateinit var openKlant2Service: OpenKlant2Service @Test - @Disabled("Not implemented yet") + @Disabled @WithBurgerUser("999990755") fun `should create Partij for authenticated user`() = runTest { @@ -70,7 +64,7 @@ class OpenKlant2PartijMutationIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/createPartij.graphql"))) .exchange() .expectStatus().isOk .expectBody() @@ -82,15 +76,15 @@ class OpenKlant2PartijMutationIT( objectMapper .readValue(responseBody!!) .get("data") - ?.get("getPartij") + ?.get("createPartij") // then verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) - - assertNotNull(responsePartij) - assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) - assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } - assertEquals("Lucas Boom", responsePartij?.requiredAt("/partijIdentificatie/volledigeNaam")?.textValue()) +// +// assertNotNull(responsePartij) +// assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) +// assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } +// assertEquals("Lucas Boom", responsePartij?.requiredAt("/partijIdentificatie/volledigeNaam")?.textValue()) } companion object { diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt index 96cc4d3f..34bb48f7 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt @@ -120,7 +120,7 @@ class OpenKlant2PartijQueryIT( ?.get("findUserPartij") // then - verify(openKlant2Service, times(1)).findPartij(any()) + verify(openKlant2Service, times(1)).findPartijByAuthentication(any()) assertNotNull(responsePartij) assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) @@ -229,7 +229,7 @@ class OpenKlant2PartijQueryIT( ?.get("findUserPartij") // then - verify(openKlant2Service, times(1)).findPartij(any()) + verify(openKlant2Service, times(1)).findPartijByAuthentication(any()) assertTrue(responsePartij!!.isNull) } diff --git a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql index 442a2a39..232970dd 100644 --- a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql +++ b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql @@ -1,121 +1,5 @@ mutation { - createPartij( - createPartijPayload: { - "soortPartij": "persoon", - "partijIdentificatie": { - "contactnaam": { - "voorletters": "A.", - "voornaam": "Anna", - "voorvoegselAchternaam": "", - "achternaam": "Vissart" - } - } - ) { - betrokkenen { - uuid - url - } - bezoekadres { - adresregel1 - adresregel2 - adresregel3 - land - nummeraanduidingId - } - categorieRelaties { - beginDatum - categorieNaam - eindDatum - url - uuid - } - correspondentieadres { - adresregel1 - adresregel2 - adresregel3 - land - nummeraanduidingId - } - digitaleAdressen { - uuid - url - } - indicatieActief - indicatieGeheimhouding - interneNotitie - nummer - partijIdentificatoren { - uuid - url - } - rekeningnummers { - uuid - url - } + createPartij(partijRequest: { soortPartij: PERSOON, indicatieActief: true, indicatieGeheimhouding: true }) { soortPartij - url - uuid - vertegenwoordigden { - uuid - url - } - voorkeursDigitaalAdres { - uuid - url - } - voorkeursRekeningnummer { - uuid - url - } - voorkeurstaal - partijIdentificatie { - ... on PersoonsIdentificatie { - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - ... on ContactpersoonIdentificatie { - uuid - werkteVoorPartij { - uuid - url - } - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - ... on OrganisatieIdentificatie { - naam - } - } - } -} - -{ - "digitaleAdressen": null, - "voorkeursDigitaalAdres": null, - "vertegenwoordigden": null, - "rekeningnummers": null, - "voorkeursRekeningnummer": null, - "partijIdentificatoren": null, - "soortPartij": "persoon", - "indicatieGeheimhouding": true, - "indicatieActief": true, - "partijIdentificatie": { - "contactnaam": { - "voorletters": "A.", - "voornaam": "Anna", - "voorvoegselAchternaam": "", - "achternaam": "Vissart" - }, - "volledigeNaam": "Anna Vissart" } } \ No newline at end of file From b06f4c6c1d7dc1cb1a1da2f184dab9b7637f0d18 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Fri, 4 Oct 2024 12:46:49 +0200 Subject: [PATCH 11/19] * add initial PartijMutation test --- .../openklant/graphql/domain/PartijRequest.kt | 23 +++++++-------- .../graphql/domain/PartijResponse.kt | 9 +++--- .../openklant/graphql/domain/PartijType.kt | 29 +++++++++++++++++++ .../graphql/OpenKlant2PartijMutationIT.kt | 17 +++++------ .../config/graphql/createPartij.graphql | 15 ++++++++-- 5 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijType.kt diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt index e5a17b0a..8c70ab24 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijRequest.kt @@ -20,32 +20,31 @@ import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OrganisatieIdentificatie import nl.nlportal.openklant.client.domain.PartijIdentificatie import nl.nlportal.openklant.client.domain.PersoonsIdentificatie -import nl.nlportal.openklant.client.domain.SoortPartij -import nl.nlportal.openklant.client.domain.SoortPartij.CONTACTPERSOON -import nl.nlportal.openklant.client.domain.SoortPartij.ORGANISATIE -import nl.nlportal.openklant.client.domain.SoortPartij.PERSOON +import nl.nlportal.openklant.graphql.domain.PartijType.CONTACTPERSOON +import nl.nlportal.openklant.graphql.domain.PartijType.ORGANISATIE +import nl.nlportal.openklant.graphql.domain.PartijType.PERSOON data class PartijRequest( val indicatieGeheimhouding: Boolean, val indicatieActief: Boolean, - val soortPartij: SoortPartij, - val persoonIdentification: PersoonsIdentificatie? = null, + val type: PartijType, + val persoonsIdentificatie: PersoonsIdentificatie? = null, val organisatieIdentificatie: OrganisatieIdentificatie? = null, val contactpersoonIdentificatie: ContactpersoonIdentificatie? = null, ) { private val identificatie: PartijIdentificatie = - when (soortPartij) { + when (type) { PERSOON -> - requireNotNull(persoonIdentification) { - "{persoonIdentification} can not be null when is $soortPartij" + requireNotNull(persoonsIdentificatie) { + "{persoonIdentification} can not be null when is $type" } ORGANISATIE -> requireNotNull(organisatieIdentificatie) { - "{organisatieIdentificatie} can not be null when is $soortPartij" + "{organisatieIdentificatie} can not be null when is $type" } CONTACTPERSOON -> requireNotNull(contactpersoonIdentificatie) { - "{contactpersoonIdentificatie} can not be null when is $soortPartij" + "{contactpersoonIdentificatie} can not be null when is $type" } } @@ -53,7 +52,7 @@ data class PartijRequest( OpenKlant2Partij( indicatieGeheimhouding = indicatieGeheimhouding, indicatieActief = indicatieActief, - soortPartij = soortPartij, + soortPartij = type.asSoortPartij(), partijIdentificatie = identificatie, ) } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt index d7f646dc..4b75817b 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt @@ -19,13 +19,12 @@ import nl.nlportal.openklant.client.domain.ContactpersoonIdentificatie import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OrganisatieIdentificatie import nl.nlportal.openklant.client.domain.PersoonsIdentificatie -import nl.nlportal.openklant.client.domain.SoortPartij data class PartijResponse( val indicatieGeheimhouding: Boolean, val indicatieActief: Boolean, - val soortPartij: SoortPartij, - val persoonIdentification: PersoonsIdentificatie? = null, + val type: PartijType, + val persoonsIdentificatie: PersoonsIdentificatie? = null, val organisatieIdentificatie: OrganisatieIdentificatie? = null, val contactpersoonIdentificatie: ContactpersoonIdentificatie? = null, ) { @@ -34,8 +33,8 @@ data class PartijResponse( PartijResponse( indicatieGeheimhouding = openKlant2Partij.indicatieGeheimhouding, indicatieActief = openKlant2Partij.indicatieActief, - soortPartij = openKlant2Partij.soortPartij, - persoonIdentification = openKlant2Partij.partijIdentificatie as? PersoonsIdentificatie, + type = PartijType.valueOf(openKlant2Partij.soortPartij.name), + persoonsIdentificatie = openKlant2Partij.partijIdentificatie as? PersoonsIdentificatie, organisatieIdentificatie = openKlant2Partij.partijIdentificatie as? OrganisatieIdentificatie, contactpersoonIdentificatie = openKlant2Partij.partijIdentificatie as? ContactpersoonIdentificatie, ) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijType.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijType.kt new file mode 100644 index 00000000..00e66d57 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijType.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql.domain + +import nl.nlportal.openklant.client.domain.SoortPartij + +enum class PartijType { + PERSOON, + ORGANISATIE, + CONTACTPERSOON, + ; + + fun asSoortPartij(): SoortPartij { + return SoortPartij.valueOf(name) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index 37513e55..b112a687 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -20,8 +20,10 @@ import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.coroutines.test.runTest import nl.nlportal.commonground.authentication.WithBurgerUser import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.graphql.domain.PartijType.PERSOON import nl.nlportal.openklant.service.OpenKlant2Service -import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @@ -50,9 +52,8 @@ class OpenKlant2PartijMutationIT( lateinit var openKlant2Service: OpenKlant2Service @Test - @Disabled @WithBurgerUser("999990755") - fun `should create Partij for authenticated user`() = + fun `should create Partij for burger`() = runTest { // when val responseBody = @@ -72,7 +73,7 @@ class OpenKlant2PartijMutationIT( .responseBodyContent ?.toString(Charset.defaultCharset()) - val responsePartij = + val partijResponse = objectMapper .readValue(responseBody!!) .get("data") @@ -80,11 +81,9 @@ class OpenKlant2PartijMutationIT( // then verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) -// -// assertNotNull(responsePartij) -// assertEquals(SoortPartij.PERSOON.name, responsePartij?.get("soortPartij")?.textValue()) -// assertDoesNotThrow { objectMapper.treeToValue(responsePartij!!.get("partijIdentificatie")) } -// assertEquals("Lucas Boom", responsePartij?.requiredAt("/partijIdentificatie/volledigeNaam")?.textValue()) + + assertNotNull(partijResponse) + assertEquals(PERSOON.name, partijResponse?.get("type")?.textValue()) } companion object { diff --git a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql index 232970dd..0839eacd 100644 --- a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql +++ b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql @@ -1,5 +1,16 @@ mutation { - createPartij(partijRequest: { soortPartij: PERSOON, indicatieActief: true, indicatieGeheimhouding: true }) { - soortPartij + createPartij(partijRequest: { type: PERSOON, indicatieActief: true, indicatieGeheimhouding: true, persoonsIdentificatie: {contactnaam: { voornaam: "Bob", voorvoegselAchternaam: "de", achternaam: "Bouwer" }, volledigeNaam: "Bob de Bouwer" } }) { + type + indicatieActief + indicatieGeheimhouding + persoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } } } \ No newline at end of file From b7a3daed637b153554d65c5382144c7777343bed Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Mon, 7 Oct 2024 10:06:54 +0200 Subject: [PATCH 12/19] * add assertions to Partij Mutation test --- .../graphql/OpenKlant2PartijMutationIT.kt | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index b112a687..b0c687b4 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.graphql import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ObjectNode import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.coroutines.test.runTest import nl.nlportal.commonground.authentication.WithBurgerUser @@ -23,7 +24,7 @@ import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.graphql.domain.PartijType.PERSOON import nl.nlportal.openklant.service.OpenKlant2Service import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @@ -56,7 +57,7 @@ class OpenKlant2PartijMutationIT( fun `should create Partij for burger`() = runTest { // when - val responseBody = + val createPartijResponse = webTestClient .post() .uri { builder -> @@ -73,17 +74,34 @@ class OpenKlant2PartijMutationIT( .responseBodyContent ?.toString(Charset.defaultCharset()) - val partijResponse = + val createPartijResult = objectMapper - .readValue(responseBody!!) + .readValue(createPartijResponse!!) .get("data") ?.get("createPartij") - // then verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) - assertNotNull(partijResponse) - assertEquals(PERSOON.name, partijResponse?.get("type")?.textValue()) + assertTrue(createPartijResult is ObjectNode) + assertEquals(PERSOON.name, createPartijResult!!.requiredAt("/type")?.textValue()) + assertTrue(createPartijResult.requiredAt("/indicatieActief").booleanValue()) + assertTrue(createPartijResult.requiredAt("/indicatieGeheimhouding").booleanValue()) + assertEquals( + "Bob de Bouwer", + createPartijResult.requiredAt("/persoonsIdentificatie/volledigeNaam").textValue(), + ) + assertEquals( + "Bob", + createPartijResult.requiredAt("/persoonsIdentificatie/contactnaam/voornaam").textValue(), + ) + assertEquals( + "de", + createPartijResult.requiredAt("/persoonsIdentificatie/contactnaam/voorvoegselAchternaam").textValue(), + ) + assertEquals( + "Bouwer", + createPartijResult.requiredAt("/persoonsIdentificatie/contactnaam/achternaam").textValue(), + ) } companion object { From 93e32801e33ebeb306652e040fefc6a903f133eb Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Mon, 7 Oct 2024 15:04:55 +0200 Subject: [PATCH 13/19] * implement updatePartij mutation --- .../openklant/graphql/PartijMutation.kt | 4 +- .../openklant/service/OpenKlant2Service.kt | 36 ++++-- .../graphql/OpenKlant2PartijMutationIT.kt | 110 ++++++++++++++++++ .../config/graphql/updatePartij.graphql | 16 +++ 4 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index 4a8b9f62..69931720 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -43,13 +43,13 @@ class PartijMutation( suspend fun updatePartij( dfe: DataFetchingEnvironment, partijRequest: PartijRequest, - ): PartijResponse { + ): PartijResponse? { val partij = openklant2Service.updatePartij( dfe.graphQlContext.get(AUTHENTICATION_KEY), partijRequest.asOpenKlant2Partij(), ) - return PartijResponse.fromOpenKlant2Partij(partij) + return partij?.let { PartijResponse.fromOpenKlant2Partij(partij) } } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index 46f4f860..c2d821ec 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -15,10 +15,8 @@ */ package nl.nlportal.openklant.service -import com.fasterxml.jackson.module.kotlin.convertValue import mu.KotlinLogging import nl.nlportal.commonground.authentication.CommonGroundAuthentication -import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient import nl.nlportal.openklant.client.domain.OpenKlant2Identificator import nl.nlportal.openklant.client.domain.OpenKlant2IdentificeerdePartij @@ -67,9 +65,9 @@ class OpenKlant2Service( val partijIdentificator = OpenKlant2PartijIdentificator( partijIdentificator = - OpenKlant2Identificator( - objectId = authentication.userId, - ), + OpenKlant2Identificator( + objectId = authentication.userId, + ), ) val partijResponse = try { @@ -101,8 +99,31 @@ class OpenKlant2Service( suspend fun updatePartij( authentication: CommonGroundAuthentication, partij: OpenKlant2Partij, - ): OpenKlant2Partij { - return objectMapper.convertValue(partij) + ): OpenKlant2Partij? { + val previousPartij = findPartijByAuthentication(authentication) + if (previousPartij != null) { + val updatedPartij = + previousPartij.copy( + indicatieGeheimhouding = partij.indicatieGeheimhouding, + indicatieActief = partij.indicatieActief, + soortPartij = partij.soortPartij, + partijIdentificatie = partij.partijIdentificatie, + ) + val partijResponse = + try { + openKlant2Client + .path() + .put(updatedPartij) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to update Partij: ${ex.responseBodyAsString}", ex) + return null + } + + return partijResponse + } + + logger.debug("Failed to update Partij: No existing Partij found. Creating new Partij") + return createPartijWithIdentificator(authentication, partij) } suspend fun findPartijIdentificatoren(authentication: CommonGroundAuthentication): List? { @@ -120,7 +141,6 @@ class OpenKlant2Service( } companion object { - private val objectMapper = Mapper.get() private val logger = KotlinLogging.logger {} } } \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index b0c687b4..a8baba76 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -24,7 +24,9 @@ import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.graphql.domain.PartijType.PERSOON import nl.nlportal.openklant.service.OpenKlant2Service import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Order import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @@ -53,6 +55,7 @@ class OpenKlant2PartijMutationIT( lateinit var openKlant2Service: OpenKlant2Service @Test + @Order(1) @WithBurgerUser("999990755") fun `should create Partij for burger`() = runTest { @@ -104,6 +107,113 @@ class OpenKlant2PartijMutationIT( ) } + @Test + @Order(2) + @WithBurgerUser("999990755") + fun `should update existing Partij for burger`() = + runTest { + // when + val updatePartijResponse = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/updatePartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val updatePartijResult = + objectMapper + .readValue(updatePartijResponse!!) + .get("data") + ?.get("updatePartij") + // then + verify(openKlant2Service, times(1)).updatePartij(any(), any()) + + assertTrue(updatePartijResult is ObjectNode) + assertEquals(PERSOON.name, updatePartijResult!!.requiredAt("/type")?.textValue()) + assertTrue(updatePartijResult.requiredAt("/indicatieActief").booleanValue()) + assertFalse(updatePartijResult.requiredAt("/indicatieGeheimhouding").booleanValue()) + assertEquals( + "Kees de Boer", + updatePartijResult.requiredAt("/persoonsIdentificatie/volledigeNaam").textValue(), + ) + assertEquals( + "Kees", + updatePartijResult.requiredAt("/persoonsIdentificatie/contactnaam/voornaam").textValue(), + ) + assertEquals( + "de", + updatePartijResult.requiredAt("/persoonsIdentificatie/contactnaam/voorvoegselAchternaam").textValue(), + ) + assertEquals( + "Boer", + updatePartijResult.requiredAt("/persoonsIdentificatie/contactnaam/achternaam").textValue(), + ) + } + + @Test + @Order(3) + @WithBurgerUser("11111110") + fun `should create Partij when update fails due to missing Partij`() = + runTest { + // when + val updatePartijResponse = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/updatePartij.graphql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val updatePartijResult = + objectMapper + .readValue(updatePartijResponse!!) + .get("data") + ?.get("updatePartij") + // then + verify(openKlant2Service, times(1)).updatePartij(any(), any()) + verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) + + assertTrue(updatePartijResult is ObjectNode) + assertEquals(PERSOON.name, updatePartijResult!!.requiredAt("/type")?.textValue()) + assertTrue(updatePartijResult.requiredAt("/indicatieActief").booleanValue()) + assertFalse(updatePartijResult.requiredAt("/indicatieGeheimhouding").booleanValue()) + assertEquals( + "Kees de Boer", + updatePartijResult.requiredAt("/persoonsIdentificatie/volledigeNaam").textValue(), + ) + assertEquals( + "Kees", + updatePartijResult.requiredAt("/persoonsIdentificatie/contactnaam/voornaam").textValue(), + ) + assertEquals( + "de", + updatePartijResult.requiredAt("/persoonsIdentificatie/contactnaam/voorvoegselAchternaam").textValue(), + ) + assertEquals( + "Boer", + updatePartijResult.requiredAt("/persoonsIdentificatie/contactnaam/achternaam").textValue(), + ) + } + companion object { private val objectMapper = Mapper.get() } diff --git a/zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql b/zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql new file mode 100644 index 00000000..82c92246 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql @@ -0,0 +1,16 @@ +mutation { + updatePartij(partijRequest: { type: PERSOON, indicatieActief: true, indicatieGeheimhouding: false, persoonsIdentificatie: {contactnaam: { voornaam: "Kees", voorvoegselAchternaam: "de", achternaam: "Boer" }, volledigeNaam: "Kees de Boer" } }) { + type + indicatieActief + indicatieGeheimhouding + persoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + } +} \ No newline at end of file From 8a9fad95706504d9b67f567b389b27fc2a3176c1 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Mon, 7 Oct 2024 15:13:41 +0200 Subject: [PATCH 14/19] * run ktlint --- .../nl/nlportal/openklant/service/OpenKlant2Service.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index c2d821ec..0bf61abd 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -65,9 +65,9 @@ class OpenKlant2Service( val partijIdentificator = OpenKlant2PartijIdentificator( partijIdentificator = - OpenKlant2Identificator( - objectId = authentication.userId, - ), + OpenKlant2Identificator( + objectId = authentication.userId, + ), ) val partijResponse = try { From 4693329d651d06e67883149375abc541e7e678ce Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Tue, 8 Oct 2024 11:57:05 +0200 Subject: [PATCH 15/19] * refactor some tests * introduce initial DigitaleAdres related entities and queries --- build.gradle.kts | 4 + gradle/testing.gradle.kts | 5 + .../OpenKlantAutoConfiguration.kt | 19 ---- .../OpenKlantGraphqlAutoConfiguration.kt | 54 ++++++++++ .../{DigitaleAdres.kt => DigitaleAdressen.kt} | 24 +++-- .../openklant/client/domain/Partijen.kt | 15 ++- .../openklant/client/domain/Shared.kt | 7 +- .../openklant/client/path/DigitaleAdressen.kt | 100 ++++++++++++++++++ .../client/path/PartijIdentificatoren.kt | 2 +- .../graphql/DigitaleAdresMutation.kt | 59 +++++++++++ .../openklant/graphql/DigitaleAdresQuery.kt | 36 +++++++ .../openklant/graphql/PartijMutation.kt | 4 +- .../graphql/domain/DigitaleAdresRequest.kt | 33 ++++++ .../graphql/domain/DigitaleAdresResponse.kt | 44 ++++++++ .../graphql/domain/DigitaleAdresType.kt | 31 ++++++ .../graphql/domain/PartijResponse.kt | 3 + .../openklant/service/OpenKlant2Service.kt | 89 +++++++++++++++- ...ot.autoconfigure.AutoConfiguration.imports | 3 +- ...t => OpenKlant2ModuleConfigurationTest.kt} | 8 +- .../graphql/OpenKlant2PartijMutationIT.kt | 12 +-- .../graphql/OpenKlant2PartijQueryIT.kt | 16 ++- .../config/graphql/createPartij.graphql | 16 --- .../config/graphql/findUserPartij.graphql | 89 ---------------- .../config/graphql/getUserPartij.graphql | 89 ---------------- .../graphql/partijTypeIntrospection.graphql | 7 -- .../config/graphql/updatePartij.graphql | 16 --- 26 files changed, 513 insertions(+), 272 deletions(-) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt rename zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/{DigitaleAdres.kt => DigitaleAdressen.kt} (70%) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt rename zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/{OpenKlant2ModuleConfigurationIT.kt => OpenKlant2ModuleConfigurationTest.kt} (93%) delete mode 100644 zgw/openklant/src/test/resources/config/graphql/createPartij.graphql delete mode 100644 zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql delete mode 100644 zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql delete mode 100644 zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql delete mode 100644 zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql diff --git a/build.gradle.kts b/build.gradle.kts index ccbe73d2..ed446bef 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -124,6 +124,10 @@ subprojects { freeCompilerArgs.add("-Xjsr305=strict") freeCompilerArgs.add("-Xemit-jvm-type-annotations") } + val ktlintFormat: Task? by tasks + if (ktlintFormat != null) { + dependsOn(ktlintFormat) + } } println("Enabling Spring Boot Dependency Management in project ${project.name}...") diff --git a/gradle/testing.gradle.kts b/gradle/testing.gradle.kts index 53fa34cc..b99f0744 100644 --- a/gradle/testing.gradle.kts +++ b/gradle/testing.gradle.kts @@ -16,6 +16,11 @@ tasks.register("integrationTest") { group = "verification" + description = + """ + Composes docker containers and runs Tests tagged with "integration". + NB! Project root must contain a docker compose file with the following name: docker-compose-override.yml + """.trimIndent() useJUnitPlatform { includeTags("integration") } diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index 2d3f69e2..5aaaa083 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -15,14 +15,9 @@ */ package nl.nlportal.openklant.autoconfigure -import com.expediagroup.graphql.server.operations.Mutation -import com.expediagroup.graphql.server.operations.Query import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient -import nl.nlportal.openklant.graphql.PartijMutation -import nl.nlportal.openklant.graphql.PartijQuery import nl.nlportal.openklant.service.OpenKlant2Service import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean @@ -41,18 +36,4 @@ class OpenKlantAutoConfiguration { fun openKlant2Service(openklant2Client: OpenKlant2KlantinteractiesClient): OpenKlant2Service { return OpenKlant2Service(openklant2Client) } - - @Bean - @ConditionalOnMissingBean(PartijQuery::class) - @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun partijQuery(openKlant2Service: OpenKlant2Service): Query { - return PartijQuery(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean(PartijMutation::class) - @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { - return PartijMutation(openKlant2Service) - } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt new file mode 100644 index 00000000..f7242e25 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.autoconfigure + +import com.expediagroup.graphql.server.operations.Mutation +import com.expediagroup.graphql.server.operations.Query +import nl.nlportal.openklant.graphql.DigitaleAdresMutation +import nl.nlportal.openklant.graphql.DigitaleAdresQuery +import nl.nlportal.openklant.graphql.PartijMutation +import nl.nlportal.openklant.graphql.PartijQuery +import nl.nlportal.openklant.service.OpenKlant2Service +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.context.annotation.Bean + +@ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") +class OpenKlantGraphqlAutoConfiguration { + @Bean + @ConditionalOnMissingBean(PartijQuery::class) + fun partijQuery(openKlant2Service: OpenKlant2Service): Query { + return PartijQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(PartijMutation::class) + fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { + return PartijMutation(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(DigitaleAdresQuery::class) + fun digitaleAdresQuery(openKlant2Service: OpenKlant2Service): Query { + return DigitaleAdresQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(DigitaleAdresMutation::class) + fun digitaleAdresMutation(openKlant2Service: OpenKlant2Service): Mutation { + return DigitaleAdresMutation(openKlant2Service) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdres.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt similarity index 70% rename from zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdres.kt rename to zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt index 6ec372e9..c67f5047 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdres.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/DigitaleAdressen.kt @@ -17,17 +17,20 @@ package nl.nlportal.openklant.client.domain import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonValue +import java.util.UUID @JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -data class DigitaleAdres( +data class OpenKlant2DigitaleAdres( val adres: String, val omschrijving: String, val soortDigitaalAdres: String, - val url: String, - val uuid: String, - val verstrektDoorBetrokkene: OpenKlant2ForeignKey? = null, - val verstrektDoorPartij: OpenKlant2ForeignKey? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val url: String? = null, + @JsonInclude(JsonInclude.Include.NON_NULL) + val uuid: UUID? = null, + val verstrektDoorBetrokkene: OpenKlant2UUID? = null, + val verstrektDoorPartij: OpenKlant2UUID? = null, ) { init { require(adres.length <= 80) { @@ -40,4 +43,13 @@ data class DigitaleAdres( "soortDigitaalAdres can't be longer than 10 characters." } } +} + +enum class OpenKlant2DigitaleAdressenFilters( + @JsonValue val value: String, +) : OpenKlant2Filters { + PAGE("page"), + ; + + override fun toString() = this.value } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt index dd09aa60..528da594 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Partijen.kt @@ -121,9 +121,21 @@ data class PartijExpand( val betrokkenen: List? = null, val hadKlantcontact: List? = null, val categorieRelaties: List? = null, - val digitaleAdressen: List? = null, + val digitaleAdressen: List? = null, ) +enum class PartijExpandOptions( + @JsonValue val value: String, +) : OpenKlant2Filters { + BETROKKENEN("betrokkenen"), + HAD_KLANTCONTACT("hadKlantcontact"), + CATEGORIE_RELATIES("categorieRelaties"), + DIGITALE_ADRESSEN("digitaleAdressen"), + ; + + override fun toString() = value +} + data class CategorieRelatieForeignKey( val beginDatum: LocalDate? = null, val categorieNaam: String, @@ -144,6 +156,7 @@ enum class OpenKlant2PartijenFilters( CATEGORIERELATIE__CATEGORIE_NAAM("categorierelatie__categorie__naam"), NUMMER("nummer"), PAGE("page"), + EXPAND("expand"), INDICATIE_GEHEIMHOUDING("indicatie_geheimhouding"), INDICATIE_ACTIEF("indicatie_actief"), SOORT_PARTIJ("soort_partij"), diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt index 17066403..89084202 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/domain/Shared.kt @@ -17,10 +17,15 @@ package nl.nlportal.openklant.client.domain import com.expediagroup.graphql.generator.annotations.GraphQLIgnore import com.fasterxml.jackson.annotation.JsonValue +import java.util.UUID data class OpenKlant2ForeignKey( val url: String, - val uuid: String, + val uuid: UUID, +) + +data class OpenKlant2UUID( + val uuid: UUID, ) data class OpenKlant2Identificator( diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt new file mode 100644 index 00000000..191b26ad --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.client.path + +import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient +import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdres +import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdressenFilters +import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator +import nl.nlportal.openklant.client.domain.ResultPage +import org.springframework.http.MediaType +import org.springframework.web.reactive.function.BodyInserters +import org.springframework.web.reactive.function.client.awaitBodilessEntity +import org.springframework.web.reactive.function.client.awaitBody +import org.springframework.web.reactive.function.client.awaitBodyOrNull +import java.util.UUID + +class DigitaleAdressen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { + override val path: String = "/digitale-adressen" + + suspend fun get(searchFilters: List>? = null): List { + val response: ResultPage = + client + .webClient() + .get() + .uri { uriBuilder -> + uriBuilder + .path(path) + .applyFilters(searchFilters) + uriBuilder.build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBody() + + return response.results + } + + suspend fun create(digitaleAdres: OpenKlant2DigitaleAdres): OpenKlant2DigitaleAdres? { + val response: OpenKlant2DigitaleAdres? = + client + .webClient() + .post() + .uri { uriBuilder -> + uriBuilder + .path(path) + .build() + } + .body(BodyInserters.fromValue(digitaleAdres)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodyOrNull() + + return response + } + + suspend fun put(digitaleAdres: OpenKlant2DigitaleAdres): OpenKlant2DigitaleAdres? { + val response: OpenKlant2DigitaleAdres? = + client + .webClient() + .put() + .uri { uriBuilder -> + uriBuilder + .path("$path/${digitaleAdres.uuid}") + .build() + } + .body(BodyInserters.fromValue(digitaleAdres)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodyOrNull() + + return response + } + + suspend fun delete(uuid: UUID) { + client + .webClient() + .delete() + .uri { uriBuilder -> + uriBuilder + .path("$path/$uuid") + .build() + } + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .awaitBodilessEntity() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt index b1f8691d..30478ce8 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/PartijIdentificatoren.kt @@ -29,7 +29,7 @@ import java.util.UUID class PartijIdentificatoren(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { override val path: String = "/partij-identificatoren" - suspend fun find(searchFilters: List>? = null): List { + suspend fun get(searchFilters: List>? = null): List { val response: ResultPage = client .webClient() diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt new file mode 100644 index 00000000..c3583979 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.server.operations.Mutation +import graphql.schema.DataFetchingEnvironment +import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY +import nl.nlportal.openklant.graphql.domain.DigitaleAdresRequest +import nl.nlportal.openklant.graphql.domain.DigitaleAdresResponse +import nl.nlportal.openklant.service.OpenKlant2Service +import java.util.UUID + +class DigitaleAdresMutation( + private val openklant2Service: OpenKlant2Service, +) : Mutation { + @GraphQLDescription("Create DigitaleAdres for User") + suspend fun createUserDigitaleAdres( + dfe: DataFetchingEnvironment, + digitaleAdresRequest: DigitaleAdresRequest, + ): DigitaleAdresResponse? { + val digitaleAdres = + openklant2Service.createDigitaleAdres( + authentication = dfe.graphQlContext.get(AUTHENTICATION_KEY), + digitaleAdres = digitaleAdresRequest.asOpenKlant2DigitaleAdres(), + ) + return digitaleAdres?.let { DigitaleAdresResponse.fromOpenKlant2DigitaleAdres(digitaleAdres) } + } + + @GraphQLDescription("Update DigitaleAdres of User") + suspend fun updateUserDigitaleAdres( + dfe: DataFetchingEnvironment, + digitaleAdresId: UUID, + digitaleAdresRequest: DigitaleAdresRequest, + ): DigitaleAdresResponse? { + val digitaleAdres = + openklant2Service + .updateDigitaleAdresById( + authentication = dfe.graphQlContext.get(AUTHENTICATION_KEY), + digitaleAdresId = digitaleAdresId, + digitaleAdres = digitaleAdresRequest.asOpenKlant2DigitaleAdres(), + ) + + return digitaleAdres?.let { DigitaleAdresResponse.fromOpenKlant2DigitaleAdres(digitaleAdres) } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt new file mode 100644 index 00000000..5c3b169a --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.server.operations.Query +import graphql.schema.DataFetchingEnvironment +import nl.nlportal.commonground.authentication.CommonGroundAuthentication +import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY +import nl.nlportal.openklant.graphql.domain.DigitaleAdresResponse +import nl.nlportal.openklant.service.OpenKlant2Service + +class DigitaleAdresQuery( + private val openklant2Service: OpenKlant2Service, +) : Query { + @GraphQLDescription("Get DigitaleAdressen of authenticated user.") + suspend fun getUserDigitaleAdresen(dfe: DataFetchingEnvironment): List? { + val authentication: CommonGroundAuthentication = dfe.graphQlContext.get(AUTHENTICATION_KEY) + val userDigitaleAdressen = openklant2Service.findDigitaleAdressen(authentication) + + return userDigitaleAdressen?.map { DigitaleAdresResponse.fromOpenKlant2DigitaleAdres(it) } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index 69931720..d74abb92 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -27,7 +27,7 @@ class PartijMutation( private val openklant2Service: OpenKlant2Service, ) : Mutation { @GraphQLDescription("Create Partij for user") - suspend fun createPartij( + suspend fun createUserPartij( dfe: DataFetchingEnvironment, partijRequest: PartijRequest, ): PartijResponse? { @@ -40,7 +40,7 @@ class PartijMutation( } @GraphQLDescription("Update user Partij") - suspend fun updatePartij( + suspend fun updateUserPartij( dfe: DataFetchingEnvironment, partijRequest: PartijRequest, ): PartijResponse? { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt new file mode 100644 index 00000000..2e335579 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql.domain + +import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdres +import java.util.UUID + +data class DigitaleAdresRequest( + val uuid: UUID? = null, + val waarde: String, + val type: DigitaleAdresType, + val omschrijving: String, +) { + fun asOpenKlant2DigitaleAdres(): OpenKlant2DigitaleAdres = + OpenKlant2DigitaleAdres( + adres = waarde, + omschrijving = omschrijving, + soortDigitaalAdres = type.toString(), + ) +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt new file mode 100644 index 00000000..88bb551c --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql.domain + +import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdres +import nl.nlportal.openklant.graphql.domain.DigitaleAdresType.ANDERS +import nl.nlportal.openklant.graphql.domain.DigitaleAdresType.EMAIL +import nl.nlportal.openklant.graphql.domain.DigitaleAdresType.TELEFOONNUMMER +import java.util.UUID + +data class DigitaleAdresResponse( + val uuid: UUID, + val waarde: String, + val type: DigitaleAdresType, + val omschrijving: String, +) { + companion object { + fun fromOpenKlant2DigitaleAdres(openKlant2DigitaleAdres: OpenKlant2DigitaleAdres): DigitaleAdresResponse = + DigitaleAdresResponse( + uuid = openKlant2DigitaleAdres.uuid!!, + waarde = openKlant2DigitaleAdres.adres, + omschrijving = openKlant2DigitaleAdres.omschrijving, + type = + when (openKlant2DigitaleAdres.omschrijving) { + "telefoonnummer" -> TELEFOONNUMMER + "e-mail" -> EMAIL + else -> ANDERS + }, + ) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt new file mode 100644 index 00000000..7305619c --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql.domain + +import com.fasterxml.jackson.annotation.JsonValue + +enum class DigitaleAdresType( + @JsonValue val value: String, +) { + TELEFOONNUMMER("telefoonnummer"), + EMAIL("e-mail"), + ANDERS("anders"), + ; + + override fun toString(): String { + return this.value + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt index 4b75817b..4b05b4a7 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/PartijResponse.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.graphql.domain import nl.nlportal.openklant.client.domain.ContactpersoonIdentificatie +import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdres import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OrganisatieIdentificatie import nl.nlportal.openklant.client.domain.PersoonsIdentificatie @@ -27,6 +28,7 @@ data class PartijResponse( val persoonsIdentificatie: PersoonsIdentificatie? = null, val organisatieIdentificatie: OrganisatieIdentificatie? = null, val contactpersoonIdentificatie: ContactpersoonIdentificatie? = null, + val digitaleAdressen: List? = null, ) { companion object { fun fromOpenKlant2Partij(openKlant2Partij: OpenKlant2Partij): PartijResponse = @@ -37,6 +39,7 @@ data class PartijResponse( persoonsIdentificatie = openKlant2Partij.partijIdentificatie as? PersoonsIdentificatie, organisatieIdentificatie = openKlant2Partij.partijIdentificatie as? OrganisatieIdentificatie, contactpersoonIdentificatie = openKlant2Partij.partijIdentificatie as? ContactpersoonIdentificatie, + digitaleAdressen = openKlant2Partij.expand?.digitaleAdressen, ) } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index 0bf61abd..4d2d96de 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -18,14 +18,17 @@ package nl.nlportal.openklant.service import mu.KotlinLogging import nl.nlportal.commonground.authentication.CommonGroundAuthentication import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient +import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdres import nl.nlportal.openklant.client.domain.OpenKlant2Identificator import nl.nlportal.openklant.client.domain.OpenKlant2IdentificeerdePartij import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificator import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilters -import nl.nlportal.openklant.client.domain.OpenKlant2PartijIdentificatorenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID import nl.nlportal.openklant.client.domain.OpenKlant2PartijenFilters +import nl.nlportal.openklant.client.domain.OpenKlant2UUID +import nl.nlportal.openklant.client.domain.PartijExpandOptions.DIGITALE_ADRESSEN import nl.nlportal.openklant.client.domain.asSoortPartij +import nl.nlportal.openklant.client.path.DigitaleAdressen import nl.nlportal.openklant.client.path.PartijIdentificatoren import nl.nlportal.openklant.client.path.Partijen import org.springframework.web.reactive.function.client.WebClientResponseException @@ -129,17 +132,97 @@ class OpenKlant2Service( suspend fun findPartijIdentificatoren(authentication: CommonGroundAuthentication): List? { val searchFilters: List> = listOf( - PARTIJ_IDENTIFICATOR_OBJECT_ID to authentication.userId, + OpenKlant2PartijIdentificatorenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID to authentication.userId, ) try { - return openKlant2Client.path().find(searchFilters) + return openKlant2Client.path().get(searchFilters) } catch (ex: WebClientResponseException) { logger.debug("Failed to find Partij Identificatoren: ${ex.responseBodyAsString}", ex) return null } } + suspend fun findDigitaleAdressen(authentication: CommonGroundAuthentication): List? { + val searchVariables = + listOf( + OpenKlant2PartijenFilters.SOORT_PARTIJ to authentication.asSoortPartij(), + OpenKlant2PartijenFilters.PARTIJ_IDENTIFICATOR_OBJECT_ID to authentication.userId, + OpenKlant2PartijenFilters.EXPAND to DIGITALE_ADRESSEN, + ) + + val response = + try { + openKlant2Client.path().get(searchVariables)?.singleOrNull() + } catch (ex: WebClientResponseException) { + logger.debug("Failed to get Partij with DigitaleAdressen: ${ex.responseBodyAsString}", ex) + return null + } + + return response?.expand?.digitaleAdressen + } + + suspend fun createDigitaleAdres( + authentication: CommonGroundAuthentication, + digitaleAdres: OpenKlant2DigitaleAdres, + ): OpenKlant2DigitaleAdres? { + val userPartijId = + findPartijIdentificatoren(authentication) + ?.singleOrNull { it.partijIdentificator?.objectId == authentication.userId } + ?.identificeerdePartij + ?.uuid + + if (userPartijId == null) { + logger.debug("Failed to create Digitale Adres: Authenticated User does not have a Partij") + return null + } + + val digitaleAdresResponse = + try { + openKlant2Client + .path() + .create( + digitaleAdres + .copy(verstrektDoorPartij = OpenKlant2UUID(userPartijId)), + ) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to create DigitaleAdres: ${ex.responseBodyAsString}", ex) + return null + } + + return digitaleAdresResponse + } + + suspend fun updateDigitaleAdresById( + authentication: CommonGroundAuthentication, + digitaleAdresId: UUID, + digitaleAdres: OpenKlant2DigitaleAdres, + ): OpenKlant2DigitaleAdres? { + val previousDigitaleAdres = findDigitaleAdressen(authentication)?.singleOrNull { it.uuid == digitaleAdresId } + if (previousDigitaleAdres == null) { + return null + } + val updatedDigitaleAdres = + previousDigitaleAdres.copy( + adres = digitaleAdres.adres, + omschrijving = digitaleAdres.omschrijving, + soortDigitaalAdres = digitaleAdres.soortDigitaalAdres, + verstrektDoorBetrokkene = digitaleAdres.verstrektDoorBetrokkene, + verstrektDoorPartij = digitaleAdres.verstrektDoorPartij, + ) + val digitaleAdresResponse = + try { + openKlant2Client + .path() + .put(updatedDigitaleAdres) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to update DigitaleAdres: ${ex.responseBodyAsString}", ex) + return null + } + + return digitaleAdresResponse + } + companion object { private val logger = KotlinLogging.logger {} } diff --git a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index bfe73899..3a55b94f 100644 --- a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -14,4 +14,5 @@ # limitations under the License. # -nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration \ No newline at end of file +nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration +nl.nlportal.openklant.autoconfigure.OpenKlantGraphqlAutoConfiguration \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt similarity index 93% rename from zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationIT.kt rename to zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt index 85566d21..e45a146c 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt @@ -23,7 +23,6 @@ import nl.nlportal.core.util.Mapper import nl.nlportal.openklant.autoconfigure.OpenKlantModuleConfiguration import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.springframework.beans.factory.annotation.Autowired @@ -38,16 +37,15 @@ import org.springframework.web.reactive.function.BodyInserters import java.nio.charset.Charset @SpringBootTest -@Tag("integration") @ActiveProfiles("openklant-disabled") @AutoConfigureWebTestClient(timeout = "36000") @TestInstance(TestInstance.Lifecycle.PER_METHOD) -class OpenKlant2ModuleConfigurationIT( +class OpenKlant2ModuleConfigurationTest( @Autowired private val webTestClient: WebTestClient, @Autowired private val openKlantModuleConfiguration: OpenKlantModuleConfiguration, ) { @Test - fun `should not expose Partij type when module is disabled`() = + fun `should not expose openklant type when module is disabled`() = runTest { // when val responseBodyContent = @@ -59,7 +57,7 @@ class OpenKlant2ModuleConfigurationIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/openKlant2TypeIntrospection.gql"))) .exchange() .expectStatus().isOk .expectBody() diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index a8baba76..2bb8f91f 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -69,7 +69,7 @@ class OpenKlant2PartijMutationIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/createPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/createUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -81,7 +81,7 @@ class OpenKlant2PartijMutationIT( objectMapper .readValue(createPartijResponse!!) .get("data") - ?.get("createPartij") + ?.get("createUserPartij") // then verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) @@ -122,7 +122,7 @@ class OpenKlant2PartijMutationIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/updatePartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/updateUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -134,7 +134,7 @@ class OpenKlant2PartijMutationIT( objectMapper .readValue(updatePartijResponse!!) .get("data") - ?.get("updatePartij") + ?.get("updateUserPartij") // then verify(openKlant2Service, times(1)).updatePartij(any(), any()) @@ -175,7 +175,7 @@ class OpenKlant2PartijMutationIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/updatePartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/updateUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -187,7 +187,7 @@ class OpenKlant2PartijMutationIT( objectMapper .readValue(updatePartijResponse!!) .get("data") - ?.get("updatePartij") + ?.get("updateUserPartij") // then verify(openKlant2Service, times(1)).updatePartij(any(), any()) verify(openKlant2Service, times(1)).createPartijWithIdentificator(any(), any()) diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt index 34bb48f7..eeaef6df 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt @@ -68,7 +68,7 @@ class OpenKlant2PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijTypeIntrospection.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/openKlant2TypeIntrospection.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -84,11 +84,7 @@ class OpenKlant2PartijQueryIT( // then assertEquals("OBJECT", typeResponse?.get("kind")?.textValue()) - assertEquals("OpenKlant2Partij", typeResponse?.get("name")?.textValue()) - assertEquals( - "A Type that represents a Klantinteracties API Partij object", - typeResponse?.get("description")?.textValue(), - ) + assertEquals("PartijResponse", typeResponse?.get("name")?.textValue()) } @Test @@ -105,7 +101,7 @@ class OpenKlant2PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -142,7 +138,7 @@ class OpenKlant2PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -179,7 +175,7 @@ class OpenKlant2PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() @@ -214,7 +210,7 @@ class OpenKlant2PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.graphql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/findUserPartij.gql"))) .exchange() .expectStatus().isOk .expectBody() diff --git a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql deleted file mode 100644 index 0839eacd..00000000 --- a/zgw/openklant/src/test/resources/config/graphql/createPartij.graphql +++ /dev/null @@ -1,16 +0,0 @@ -mutation { - createPartij(partijRequest: { type: PERSOON, indicatieActief: true, indicatieGeheimhouding: true, persoonsIdentificatie: {contactnaam: { voornaam: "Bob", voorvoegselAchternaam: "de", achternaam: "Bouwer" }, volledigeNaam: "Bob de Bouwer" } }) { - type - indicatieActief - indicatieGeheimhouding - persoonsIdentificatie { - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - } -} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql deleted file mode 100644 index 37539244..00000000 --- a/zgw/openklant/src/test/resources/config/graphql/findUserPartij.graphql +++ /dev/null @@ -1,89 +0,0 @@ -query { - findUserPartij { - betrokkenen { - uuid - url - } - bezoekadres { - adresregel1 - adresregel2 - adresregel3 - land - nummeraanduidingId - } - categorieRelaties { - beginDatum - categorieNaam - eindDatum - url - uuid - } - correspondentieadres { - adresregel1 - adresregel2 - adresregel3 - land - nummeraanduidingId - } - digitaleAdressen { - uuid - url - } - indicatieActief - indicatieGeheimhouding - interneNotitie - nummer - partijIdentificatoren { - uuid - url - } - rekeningnummers { - uuid - url - } - soortPartij - url - uuid - vertegenwoordigden { - uuid - url - } - voorkeursDigitaalAdres { - uuid - url - } - voorkeursRekeningnummer { - uuid - url - } - voorkeurstaal - partijIdentificatie { - ... on PersoonsIdentificatie { - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - ... on ContactpersoonIdentificatie { - uuid - werkteVoorPartij { - uuid - url - } - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - ... on OrganisatieIdentificatie { - naam - } - } - } -} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql b/zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql deleted file mode 100644 index 5405dfc6..00000000 --- a/zgw/openklant/src/test/resources/config/graphql/getUserPartij.graphql +++ /dev/null @@ -1,89 +0,0 @@ -query { - getUserPartij(partijId: "9f8e8009-2d1c-40ae-931e-c08861ba7207") { - betrokkenen { - uuid - url - } - bezoekadres { - adresregel1 - adresregel2 - adresregel3 - land - nummeraanduidingId - } - categorieRelaties { - beginDatum - categorieNaam - eindDatum - url - uuid - } - correspondentieadres { - adresregel1 - adresregel2 - adresregel3 - land - nummeraanduidingId - } - digitaleAdressen { - uuid - url - } - indicatieActief - indicatieGeheimhouding - interneNotitie - nummer - partijIdentificatoren { - uuid - url - } - rekeningnummers { - uuid - url - } - soortPartij - url - uuid - vertegenwoordigden { - uuid - url - } - voorkeursDigitaalAdres { - uuid - url - } - voorkeursRekeningnummer { - uuid - url - } - voorkeurstaal - partijIdentificatie { - ... on PersoonsIdentificatie { - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - ... on ContactpersoonIdentificatie { - uuid - werkteVoorPartij { - uuid - url - } - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - ... on OrganisatieIdentificatie { - naam - } - } - } -} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql b/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql deleted file mode 100644 index 25ae5eb8..00000000 --- a/zgw/openklant/src/test/resources/config/graphql/partijTypeIntrospection.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query { - __type(name: "OpenKlant2Partij") { - kind - name - description - } -} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql b/zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql deleted file mode 100644 index 82c92246..00000000 --- a/zgw/openklant/src/test/resources/config/graphql/updatePartij.graphql +++ /dev/null @@ -1,16 +0,0 @@ -mutation { - updatePartij(partijRequest: { type: PERSOON, indicatieActief: true, indicatieGeheimhouding: false, persoonsIdentificatie: {contactnaam: { voornaam: "Kees", voorvoegselAchternaam: "de", achternaam: "Boer" }, volledigeNaam: "Kees de Boer" } }) { - type - indicatieActief - indicatieGeheimhouding - persoonsIdentificatie { - contactnaam { - voorletters - voornaam - voorvoegselAchternaam - achternaam - } - volledigeNaam - } - } -} \ No newline at end of file From ed556269c0514d07fbc3586395612ea968d963e9 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Tue, 8 Oct 2024 13:55:50 +0200 Subject: [PATCH 16/19] * change default loglevels for app to info * disable sql logging for app * fix DigitaleAdresType serialization * add authentication requirement to all openklant queries and mutations * add delete DigitaleAdres mutation --- app/src/main/resources/config/application.yml | 4 +-- .../openklant/client/path/DigitaleAdressen.kt | 2 +- .../graphql/DigitaleAdresMutation.kt | 15 ++++++++++ .../openklant/graphql/DigitaleAdresQuery.kt | 2 ++ .../openklant/graphql/PartijMutation.kt | 2 ++ .../nlportal/openklant/graphql/PartijQuery.kt | 2 ++ .../graphql/domain/DigitaleAdresRequest.kt | 2 +- .../graphql/domain/DigitaleAdresResponse.kt | 11 +++----- .../graphql/domain/DigitaleAdresType.kt | 17 +++-------- .../openklant/service/OpenKlant2Service.kt | 28 +++++++++++++++++++ 10 files changed, 61 insertions(+), 24 deletions(-) diff --git a/app/src/main/resources/config/application.yml b/app/src/main/resources/config/application.yml index 33d12cb6..abd30087 100644 --- a/app/src/main/resources/config/application.yml +++ b/app/src/main/resources/config/application.yml @@ -38,7 +38,7 @@ spring: jpa: database-platform: org.hibernate.dialect.PostgreSQLDialect database: postgresql - show_sql: true + show_sql: false open-in-view: false properties: hibernate: @@ -69,7 +69,7 @@ graphql: logging: level: - org.springframework.amqp: DEBUG + root: INFO nl-portal: config: diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt index 191b26ad..8ecc7dfc 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/client/path/DigitaleAdressen.kt @@ -28,7 +28,7 @@ import org.springframework.web.reactive.function.client.awaitBodyOrNull import java.util.UUID class DigitaleAdressen(val client: OpenKlant2KlantinteractiesClient) : KlantInteractiesPath() { - override val path: String = "/digitale-adressen" + override val path: String = "/digitaleadressen" suspend fun get(searchFilters: List>? = null): List { val response: ResultPage = diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt index c3583979..eeb281b3 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.generator.federation.directives.AuthenticatedDirective import com.expediagroup.graphql.server.operations.Mutation import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY @@ -24,6 +25,7 @@ import nl.nlportal.openklant.graphql.domain.DigitaleAdresResponse import nl.nlportal.openklant.service.OpenKlant2Service import java.util.UUID +@AuthenticatedDirective class DigitaleAdresMutation( private val openklant2Service: OpenKlant2Service, ) : Mutation { @@ -56,4 +58,17 @@ class DigitaleAdresMutation( return digitaleAdres?.let { DigitaleAdresResponse.fromOpenKlant2DigitaleAdres(digitaleAdres) } } + + @GraphQLDescription("Delete DigitaleAdres of User by Id") + suspend fun deleteUserDigitaleAdres( + dfe: DataFetchingEnvironment, + digitaleAdresId: UUID, + ): DigitaleAdresResponse? { + openklant2Service + .deleteDigitaleAdresById( + dfe.graphQlContext.get(AUTHENTICATION_KEY), + digitaleAdresId, + ) + return null + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt index 5c3b169a..f4482199 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresQuery.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.generator.federation.directives.AuthenticatedDirective import com.expediagroup.graphql.server.operations.Query import graphql.schema.DataFetchingEnvironment import nl.nlportal.commonground.authentication.CommonGroundAuthentication @@ -23,6 +24,7 @@ import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY import nl.nlportal.openklant.graphql.domain.DigitaleAdresResponse import nl.nlportal.openklant.service.OpenKlant2Service +@AuthenticatedDirective class DigitaleAdresQuery( private val openklant2Service: OpenKlant2Service, ) : Query { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt index d74abb92..83ef4b2f 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijMutation.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.generator.federation.directives.AuthenticatedDirective import com.expediagroup.graphql.server.operations.Mutation import graphql.schema.DataFetchingEnvironment import nl.nlportal.graphql.security.SecurityConstants.AUTHENTICATION_KEY @@ -23,6 +24,7 @@ import nl.nlportal.openklant.graphql.domain.PartijRequest import nl.nlportal.openklant.graphql.domain.PartijResponse import nl.nlportal.openklant.service.OpenKlant2Service +@AuthenticatedDirective class PartijMutation( private val openklant2Service: OpenKlant2Service, ) : Mutation { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt index a839ceea..9ae60b9e 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/PartijQuery.kt @@ -16,6 +16,7 @@ package nl.nlportal.openklant.graphql import com.expediagroup.graphql.generator.annotations.GraphQLDescription +import com.expediagroup.graphql.generator.federation.directives.AuthenticatedDirective import com.expediagroup.graphql.server.operations.Query import graphql.schema.DataFetchingEnvironment import nl.nlportal.commonground.authentication.CommonGroundAuthentication @@ -24,6 +25,7 @@ import nl.nlportal.openklant.client.domain.OpenKlant2Partij import nl.nlportal.openklant.service.OpenKlant2Service import java.util.UUID +@AuthenticatedDirective class PartijQuery( private val openklant2Service: OpenKlant2Service, ) : Query { diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt index 2e335579..514c4965 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresRequest.kt @@ -28,6 +28,6 @@ data class DigitaleAdresRequest( OpenKlant2DigitaleAdres( adres = waarde, omschrijving = omschrijving, - soortDigitaalAdres = type.toString(), + soortDigitaalAdres = type.name, ) } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt index 88bb551c..c3a76898 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresResponse.kt @@ -17,8 +17,6 @@ package nl.nlportal.openklant.graphql.domain import nl.nlportal.openklant.client.domain.OpenKlant2DigitaleAdres import nl.nlportal.openklant.graphql.domain.DigitaleAdresType.ANDERS -import nl.nlportal.openklant.graphql.domain.DigitaleAdresType.EMAIL -import nl.nlportal.openklant.graphql.domain.DigitaleAdresType.TELEFOONNUMMER import java.util.UUID data class DigitaleAdresResponse( @@ -34,11 +32,10 @@ data class DigitaleAdresResponse( waarde = openKlant2DigitaleAdres.adres, omschrijving = openKlant2DigitaleAdres.omschrijving, type = - when (openKlant2DigitaleAdres.omschrijving) { - "telefoonnummer" -> TELEFOONNUMMER - "e-mail" -> EMAIL - else -> ANDERS - }, + DigitaleAdresType + .entries + .singleOrNull { it.name == openKlant2DigitaleAdres.soortDigitaalAdres } + ?: ANDERS, ) } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt index 7305619c..1c95c1b6 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/domain/DigitaleAdresType.kt @@ -15,17 +15,8 @@ */ package nl.nlportal.openklant.graphql.domain -import com.fasterxml.jackson.annotation.JsonValue - -enum class DigitaleAdresType( - @JsonValue val value: String, -) { - TELEFOONNUMMER("telefoonnummer"), - EMAIL("e-mail"), - ANDERS("anders"), - ; - - override fun toString(): String { - return this.value - } +enum class DigitaleAdresType { + TELEFOONNUMMER, + EMAIL, + ANDERS, } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt index 4d2d96de..ddd90dba 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/service/OpenKlant2Service.kt @@ -200,6 +200,7 @@ class OpenKlant2Service( ): OpenKlant2DigitaleAdres? { val previousDigitaleAdres = findDigitaleAdressen(authentication)?.singleOrNull { it.uuid == digitaleAdresId } if (previousDigitaleAdres == null) { + logger.debug("Failed to update DigitaleAdres: No DigitaleAdres exists with provided Id") return null } val updatedDigitaleAdres = @@ -223,6 +224,33 @@ class OpenKlant2Service( return digitaleAdresResponse } + suspend fun deleteDigitaleAdresById( + authentication: CommonGroundAuthentication, + digitaleAdresId: UUID, + ) { + val userPartijId = + findPartijIdentificatoren(authentication) + ?.singleOrNull { it.partijIdentificator?.objectId == authentication.userId } + ?.identificeerdePartij + ?.uuid + + if (userPartijId == null) { + logger.debug("Failed to delete Digitale Adres: Given DigitaleAdres does not belong to Authenticated User") + return + } + + try { + openKlant2Client + .path() + .delete(digitaleAdresId) + } catch (ex: WebClientResponseException) { + logger.debug("Failed to delete DigitaleAdres: ${ex.responseBodyAsString}", ex) + return + } + + return + } + companion object { private val logger = KotlinLogging.logger {} } From f9efea2f7c5ad72b8c3d7f2372dc182b50a2511c Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Tue, 8 Oct 2024 15:06:42 +0200 Subject: [PATCH 17/19] * revert splitting autoconfiguration * change base integration test image --- docker-resources/docker-compose-base-test.yml | 2 +- .../OpenKlantAutoConfiguration.kt | 43 +++++++++++++++ .../OpenKlantGraphqlAutoConfiguration.kt | 54 ------------------- ...ot.autoconfigure.AutoConfiguration.imports | 19 +------ 4 files changed, 45 insertions(+), 73 deletions(-) delete mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt diff --git a/docker-resources/docker-compose-base-test.yml b/docker-resources/docker-compose-base-test.yml index f4fa28bd..ceb7784f 100644 --- a/docker-resources/docker-compose-base-test.yml +++ b/docker-resources/docker-compose-base-test.yml @@ -1,6 +1,6 @@ services: db: - image: "postgres" + image: postgres:15 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=test diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index 5aaaa083..d003b1d5 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -15,9 +15,16 @@ */ package nl.nlportal.openklant.autoconfigure +import com.expediagroup.graphql.server.operations.Mutation +import com.expediagroup.graphql.server.operations.Query import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient +import nl.nlportal.openklant.graphql.DigitaleAdresMutation +import nl.nlportal.openklant.graphql.DigitaleAdresQuery +import nl.nlportal.openklant.graphql.PartijMutation +import nl.nlportal.openklant.graphql.PartijQuery import nl.nlportal.openklant.service.OpenKlant2Service import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean @@ -36,4 +43,40 @@ class OpenKlantAutoConfiguration { fun openKlant2Service(openklant2Client: OpenKlant2KlantinteractiesClient): OpenKlant2Service { return OpenKlant2Service(openklant2Client) } + + @Bean + @ConditionalOnMissingBean( + PartijQuery::class, + ) + @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") + fun partijQuery(openKlant2Service: OpenKlant2Service): Query { + return PartijQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean( + PartijMutation::class, + ) + @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") + fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { + return PartijMutation(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean( + DigitaleAdresQuery::class, + ) + @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") + fun digitaleAdresQuery(openKlant2Service: OpenKlant2Service): Query { + return DigitaleAdresQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean( + DigitaleAdresMutation::class, + ) + @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") + fun digitaleAdresMutation(openKlant2Service: OpenKlant2Service): Mutation { + return DigitaleAdresMutation(openKlant2Service) + } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt deleted file mode 100644 index f7242e25..00000000 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2024 Ritense BV, the Netherlands. - * - * Licensed under EUPL, Version 1.2 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package nl.nlportal.openklant.autoconfigure - -import com.expediagroup.graphql.server.operations.Mutation -import com.expediagroup.graphql.server.operations.Query -import nl.nlportal.openklant.graphql.DigitaleAdresMutation -import nl.nlportal.openklant.graphql.DigitaleAdresQuery -import nl.nlportal.openklant.graphql.PartijMutation -import nl.nlportal.openklant.graphql.PartijQuery -import nl.nlportal.openklant.service.OpenKlant2Service -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.context.annotation.Bean - -@ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") -class OpenKlantGraphqlAutoConfiguration { - @Bean - @ConditionalOnMissingBean(PartijQuery::class) - fun partijQuery(openKlant2Service: OpenKlant2Service): Query { - return PartijQuery(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean(PartijMutation::class) - fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { - return PartijMutation(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean(DigitaleAdresQuery::class) - fun digitaleAdresQuery(openKlant2Service: OpenKlant2Service): Query { - return DigitaleAdresQuery(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean(DigitaleAdresMutation::class) - fun digitaleAdresMutation(openKlant2Service: OpenKlant2Service): Mutation { - return DigitaleAdresMutation(openKlant2Service) - } -} \ No newline at end of file diff --git a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 3a55b94f..0651fb78 100644 --- a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,18 +1 @@ -# -# Copyright 2024 Ritense BV, the Netherlands. -# -# Licensed under EUPL, Version 1.2 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration -nl.nlportal.openklant.autoconfigure.OpenKlantGraphqlAutoConfiguration \ No newline at end of file +nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration \ No newline at end of file From 42fe3f21ef3680b343cee10556ca887389de1267 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Tue, 8 Oct 2024 15:31:28 +0200 Subject: [PATCH 18/19] * add missing queries --- .../OpenKlantAutoConfiguration.kt | 43 --------- .../OpenKlantGraphqlAutoConfiguration.kt | 54 +++++++++++ ...ot.autoconfigure.AutoConfiguration.imports | 3 +- .../config/graphql/createDigitaleAdres.gql | 5 ++ .../config/graphql/createUserPartij.gql | 16 ++++ .../config/graphql/findUserPartij.gql | 89 +++++++++++++++++++ .../config/graphql/getUserPartij.gql | 89 +++++++++++++++++++ .../graphql/openKlant2TypeIntrospection.gql | 7 ++ .../config/graphql/updateUserPartij.gql | 16 ++++ 9 files changed, 278 insertions(+), 44 deletions(-) create mode 100644 zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt create mode 100644 zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/createUserPartij.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/findUserPartij.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/getUserPartij.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/openKlant2TypeIntrospection.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/updateUserPartij.gql diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt index d003b1d5..5aaaa083 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantAutoConfiguration.kt @@ -15,16 +15,9 @@ */ package nl.nlportal.openklant.autoconfigure -import com.expediagroup.graphql.server.operations.Mutation -import com.expediagroup.graphql.server.operations.Query import nl.nlportal.openklant.client.OpenKlant2KlantinteractiesClient -import nl.nlportal.openklant.graphql.DigitaleAdresMutation -import nl.nlportal.openklant.graphql.DigitaleAdresQuery -import nl.nlportal.openklant.graphql.PartijMutation -import nl.nlportal.openklant.graphql.PartijQuery import nl.nlportal.openklant.service.OpenKlant2Service import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean @@ -43,40 +36,4 @@ class OpenKlantAutoConfiguration { fun openKlant2Service(openklant2Client: OpenKlant2KlantinteractiesClient): OpenKlant2Service { return OpenKlant2Service(openklant2Client) } - - @Bean - @ConditionalOnMissingBean( - PartijQuery::class, - ) - @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun partijQuery(openKlant2Service: OpenKlant2Service): Query { - return PartijQuery(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean( - PartijMutation::class, - ) - @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { - return PartijMutation(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean( - DigitaleAdresQuery::class, - ) - @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun digitaleAdresQuery(openKlant2Service: OpenKlant2Service): Query { - return DigitaleAdresQuery(openKlant2Service) - } - - @Bean - @ConditionalOnMissingBean( - DigitaleAdresMutation::class, - ) - @ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") - fun digitaleAdresMutation(openKlant2Service: OpenKlant2Service): Mutation { - return DigitaleAdresMutation(openKlant2Service) - } } \ No newline at end of file diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt new file mode 100644 index 00000000..f7242e25 --- /dev/null +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/autoconfigure/OpenKlantGraphqlAutoConfiguration.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.autoconfigure + +import com.expediagroup.graphql.server.operations.Mutation +import com.expediagroup.graphql.server.operations.Query +import nl.nlportal.openklant.graphql.DigitaleAdresMutation +import nl.nlportal.openklant.graphql.DigitaleAdresQuery +import nl.nlportal.openklant.graphql.PartijMutation +import nl.nlportal.openklant.graphql.PartijQuery +import nl.nlportal.openklant.service.OpenKlant2Service +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.context.annotation.Bean + +@ConditionalOnProperty(prefix = "nl-portal.config.openklant", name = ["enabled"], havingValue = "true") +class OpenKlantGraphqlAutoConfiguration { + @Bean + @ConditionalOnMissingBean(PartijQuery::class) + fun partijQuery(openKlant2Service: OpenKlant2Service): Query { + return PartijQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(PartijMutation::class) + fun partijMutation(openKlant2Service: OpenKlant2Service): Mutation { + return PartijMutation(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(DigitaleAdresQuery::class) + fun digitaleAdresQuery(openKlant2Service: OpenKlant2Service): Query { + return DigitaleAdresQuery(openKlant2Service) + } + + @Bean + @ConditionalOnMissingBean(DigitaleAdresMutation::class) + fun digitaleAdresMutation(openKlant2Service: OpenKlant2Service): Mutation { + return DigitaleAdresMutation(openKlant2Service) + } +} \ No newline at end of file diff --git a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 0651fb78..6f148d10 100644 --- a/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/zgw/openklant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,2 @@ -nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration \ No newline at end of file +nl.nlportal.openklant.autoconfigure.OpenKlantAutoConfiguration +nl.nlportal.openklant.autoconfigure.OpenKlantGraphqlAutoConfiguration \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql b/zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql new file mode 100644 index 00000000..73c84553 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql @@ -0,0 +1,5 @@ +mutation { + createDigitaleAdres(digitaleAdresRequest: {waarde: "0611111111", type: TELEFOONNUMMER, omschrijving: "Privè Telefoonnummer" }) { + + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/createUserPartij.gql b/zgw/openklant/src/test/resources/config/graphql/createUserPartij.gql new file mode 100644 index 00000000..f3da9a0a --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/createUserPartij.gql @@ -0,0 +1,16 @@ +mutation { + createUserPartij(partijRequest: { type: PERSOON, indicatieActief: true, indicatieGeheimhouding: true, persoonsIdentificatie: {contactnaam: { voornaam: "Bob", voorvoegselAchternaam: "de", achternaam: "Bouwer" }, volledigeNaam: "Bob de Bouwer" } }) { + type + indicatieActief + indicatieGeheimhouding + persoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/findUserPartij.gql b/zgw/openklant/src/test/resources/config/graphql/findUserPartij.gql new file mode 100644 index 00000000..37539244 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/findUserPartij.gql @@ -0,0 +1,89 @@ +query { + findUserPartij { + betrokkenen { + uuid + url + } + bezoekadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + categorieRelaties { + beginDatum + categorieNaam + eindDatum + url + uuid + } + correspondentieadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + digitaleAdressen { + uuid + url + } + indicatieActief + indicatieGeheimhouding + interneNotitie + nummer + partijIdentificatoren { + uuid + url + } + rekeningnummers { + uuid + url + } + soortPartij + url + uuid + vertegenwoordigden { + uuid + url + } + voorkeursDigitaalAdres { + uuid + url + } + voorkeursRekeningnummer { + uuid + url + } + voorkeurstaal + partijIdentificatie { + ... on PersoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on ContactpersoonIdentificatie { + uuid + werkteVoorPartij { + uuid + url + } + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on OrganisatieIdentificatie { + naam + } + } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/getUserPartij.gql b/zgw/openklant/src/test/resources/config/graphql/getUserPartij.gql new file mode 100644 index 00000000..5405dfc6 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/getUserPartij.gql @@ -0,0 +1,89 @@ +query { + getUserPartij(partijId: "9f8e8009-2d1c-40ae-931e-c08861ba7207") { + betrokkenen { + uuid + url + } + bezoekadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + categorieRelaties { + beginDatum + categorieNaam + eindDatum + url + uuid + } + correspondentieadres { + adresregel1 + adresregel2 + adresregel3 + land + nummeraanduidingId + } + digitaleAdressen { + uuid + url + } + indicatieActief + indicatieGeheimhouding + interneNotitie + nummer + partijIdentificatoren { + uuid + url + } + rekeningnummers { + uuid + url + } + soortPartij + url + uuid + vertegenwoordigden { + uuid + url + } + voorkeursDigitaalAdres { + uuid + url + } + voorkeursRekeningnummer { + uuid + url + } + voorkeurstaal + partijIdentificatie { + ... on PersoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on ContactpersoonIdentificatie { + uuid + werkteVoorPartij { + uuid + url + } + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + ... on OrganisatieIdentificatie { + naam + } + } + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/openKlant2TypeIntrospection.gql b/zgw/openklant/src/test/resources/config/graphql/openKlant2TypeIntrospection.gql new file mode 100644 index 00000000..b78dde7f --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/openKlant2TypeIntrospection.gql @@ -0,0 +1,7 @@ +query { + __type(name: "PartijResponse") { + kind + name + description + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/updateUserPartij.gql b/zgw/openklant/src/test/resources/config/graphql/updateUserPartij.gql new file mode 100644 index 00000000..bc451cb1 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/updateUserPartij.gql @@ -0,0 +1,16 @@ +mutation { + updateUserPartij(partijRequest: { type: PERSOON, indicatieActief: true, indicatieGeheimhouding: false, persoonsIdentificatie: {contactnaam: { voornaam: "Kees", voorvoegselAchternaam: "de", achternaam: "Boer" }, volledigeNaam: "Kees de Boer" } }) { + type + indicatieActief + indicatieGeheimhouding + persoonsIdentificatie { + contactnaam { + voorletters + voornaam + voorvoegselAchternaam + achternaam + } + volledigeNaam + } + } +} \ No newline at end of file From 030fd12ed378981fa6dbdf13975f18b42ff53567 Mon Sep 17 00:00:00 2001 From: Anna Vissart Date: Tue, 8 Oct 2024 17:51:35 +0200 Subject: [PATCH 19/19] * changed return type of deleteUserDigitaleAdres mutation * integration tests for DigitaleAdres * fixed integration test ordering in test classe where it matters --- .../graphql/DigitaleAdresMutation.kt | 2 +- .../OpenKlant2ModuleConfigurationTest.kt | 2 +- .../OpenKlant2DigitaleAdresMutationIT.kt | 223 ++++++++++++++++++ .../graphql/OpenKlant2DigitaleAdresQueryIT.kt | 157 ++++++++++++ .../graphql/OpenKlant2PartijMutationIT.kt | 5 +- .../graphql/OpenKlant2PartijQueryIT.kt | 2 +- .../config/graphql/createDigitaleAdres.gql | 5 - .../graphql/createUserDigitaleAdres.gql | 8 + .../graphql/digitaleAdresIntrospection.gql | 7 + .../config/graphql/getUserDigitaleAdresen.gql | 9 + ...rospection.gql => partijIntrospection.gql} | 0 11 files changed, 411 insertions(+), 9 deletions(-) create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresMutationIT.kt create mode 100644 zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresQueryIT.kt delete mode 100644 zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/createUserDigitaleAdres.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/digitaleAdresIntrospection.gql create mode 100644 zgw/openklant/src/test/resources/config/graphql/getUserDigitaleAdresen.gql rename zgw/openklant/src/test/resources/config/graphql/{openKlant2TypeIntrospection.gql => partijIntrospection.gql} (100%) diff --git a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt index eeb281b3..0c8bc8fb 100644 --- a/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt +++ b/zgw/openklant/src/main/kotlin/nl/nlportal/openklant/graphql/DigitaleAdresMutation.kt @@ -63,7 +63,7 @@ class DigitaleAdresMutation( suspend fun deleteUserDigitaleAdres( dfe: DataFetchingEnvironment, digitaleAdresId: UUID, - ): DigitaleAdresResponse? { + ): Boolean? { openklant2Service .deleteDigitaleAdresById( dfe.graphQlContext.get(AUTHENTICATION_KEY), diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt index e45a146c..a83d833a 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/configuration/OpenKlant2ModuleConfigurationTest.kt @@ -57,7 +57,7 @@ class OpenKlant2ModuleConfigurationTest( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/openKlant2TypeIntrospection.gql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijIntrospection.gql"))) .exchange() .expectStatus().isOk .expectBody() diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresMutationIT.kt new file mode 100644 index 00000000..9225af36 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresMutationIT.kt @@ -0,0 +1,223 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.NullNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.module.kotlin.readValue +import kotlinx.coroutines.test.runTest +import nl.nlportal.commonground.authentication.WithBurgerUser +import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.graphql.domain.DigitaleAdresType +import nl.nlportal.openklant.service.OpenKlant2Service +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation +import org.junit.jupiter.api.Order +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestMethodOrder +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.mock.mockito.SpyBean +import org.springframework.core.io.ClassPathResource +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.web.reactive.function.BodyInserters +import java.nio.charset.Charset + +@SpringBootTest +@Tag("integration") +@TestMethodOrder(OrderAnnotation::class) +@AutoConfigureWebTestClient(timeout = "36000") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class OpenKlant2DigitaleAdresMutationIT( + @Autowired private val webTestClient: WebTestClient, +) { + @SpyBean + lateinit var openKlant2Service: OpenKlant2Service + + lateinit var testdigitaleAdresUUID: String + + @Test + @Order(1) + @WithBurgerUser("123456788") + fun `should create DigitaleAdres for burger`() = + runTest { + // when + val createResponse = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/createUserDigitaleAdres.gql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val createResult = + objectMapper + .readValue(createResponse!!) + .get("data") + ?.get("createUserDigitaleAdres") + // then + verify(openKlant2Service, times(1)).createDigitaleAdres(any(), any()) + + assertTrue(createResult is ObjectNode) + assertEquals(DigitaleAdresType.TELEFOONNUMMER.name, createResult!!.get("type").textValue()) + assertEquals("0611111111", createResult.get("waarde").textValue()) + assertEquals("Privè telefoonnummer", createResult.get("omschrijving").textValue()) + + testdigitaleAdresUUID = createResult.get("uuid").textValue() + } + + @Test + @Order(2) + @WithBurgerUser("123456788") + fun `should update existing DigitaleAdres for burger`() = + runTest { + // when + val createResponse = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .bodyValue( + """ + mutation { + updateUserDigitaleAdres( + digitaleAdresId: "$testdigitaleAdresUUID", + digitaleAdresRequest: { + waarde: "0611111112", type: TELEFOONNUMMER, omschrijving: "Modified" + } + ) { + uuid + waarde + type + omschrijving + } + } + """.trimIndent(), + ) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val createResult = + objectMapper + .readValue(createResponse!!) + .get("data") + ?.get("updateUserDigitaleAdres") + + // then + verify(openKlant2Service, times(1)).updateDigitaleAdresById(any(), any(), any()) + + assertTrue(createResult is ObjectNode) + assertTrue(createResult is ObjectNode) + assertEquals(DigitaleAdresType.TELEFOONNUMMER.name, createResult!!.get("type").textValue()) + assertEquals("0611111112", createResult.get("waarde").textValue()) + assertEquals("Modified", createResult.get("omschrijving").textValue()) + } + + @Test + @Order(3) + @WithBurgerUser("123456788") + fun `should delete existing DigitaleAdres for burger`() = + runTest { + // when + val createResponse = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .bodyValue( + """ + mutation { + deleteUserDigitaleAdres(digitaleAdresId: "$testdigitaleAdresUUID") + } + """.trimIndent(), + ) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val createResult = + objectMapper + .readValue(createResponse!!) + .get("data") + ?.get("deleteUserDigitaleAdres") + + // then + verify(openKlant2Service, times(1)).deleteDigitaleAdresById(any(), any()) + + assertTrue(createResult is NullNode) + + val userAdressen = + objectMapper.readTree( + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserDigitaleAdresen.gql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent, + ) + .get("data") + ?.get("getUserDigitaleAdresen") + + assertFalse(testdigitaleAdresUUID in userAdressen!!.mapNotNull { it?.get("uuid")?.textValue() }) + } + + companion object { + private val objectMapper = Mapper.get() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresQueryIT.kt new file mode 100644 index 00000000..16dcd694 --- /dev/null +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2DigitaleAdresQueryIT.kt @@ -0,0 +1,157 @@ +/* + * Copyright 2024 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.nlportal.openklant.graphql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.module.kotlin.readValue +import kotlinx.coroutines.test.runTest +import nl.nlportal.commonground.authentication.WithBurgerUser +import nl.nlportal.core.util.Mapper +import nl.nlportal.openklant.service.OpenKlant2Service +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.mock.mockito.SpyBean +import org.springframework.core.io.ClassPathResource +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.web.reactive.function.BodyInserters +import java.nio.charset.Charset + +@SpringBootTest +@Tag("integration") +@AutoConfigureWebTestClient(timeout = "36000") +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +class OpenKlant2DigitaleAdresQueryIT( + @Autowired private val webTestClient: WebTestClient, +) { + @SpyBean + lateinit var openKlant2Service: OpenKlant2Service + + @Test + fun `should introspect DigitaleAdres type`() = + runTest { + // when + val responseBodyContent = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/digitaleAdresIntrospection.gql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val typeResponse = + objectMapper + .readValue(responseBodyContent!!) + .get("data") + ?.get("__type") + + // then + assertEquals("OBJECT", typeResponse?.get("kind")?.textValue()) + assertEquals("DigitaleAdresResponse", typeResponse?.get("name")?.textValue()) + } + + @Test + @WithBurgerUser("123456788") + fun `should find DigitaleAdressen for authenticated user`() = + runTest { + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserDigitaleAdresen.gql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val response = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("getUserDigitaleAdresen") + + // then + verify(openKlant2Service, times(1)).findDigitaleAdressen(any()) + + assertNotNull(response) + assertEquals("ANDERS", response?.get(0)?.get("type")?.textValue()) + } + + @Test + @WithBurgerUser("111111110") + fun `should return empty list when no DigitaleAdres was found for authenticated user`() = + runTest { + // when + val responseBody = + webTestClient + .post() + .uri { builder -> + builder + .path("/graphql") + .build() + } + .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/getUserDigitaleAdresen.gql"))) + .exchange() + .expectStatus().isOk + .expectBody() + .returnResult() + .responseBodyContent + ?.toString(Charset.defaultCharset()) + + val responsePartij = + objectMapper + .readValue(responseBody!!) + .get("data") + ?.get("getUserDigitaleAdresen") + + // then + verify(openKlant2Service, times(1)).findDigitaleAdressen(any()) + assertTrue(responsePartij!!.isEmpty) + } + + companion object { + private val objectMapper = Mapper.get() + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt index 2bb8f91f..e5500a30 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijMutationIT.kt @@ -26,10 +26,12 @@ import nl.nlportal.openklant.service.OpenKlant2Service import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation import org.junit.jupiter.api.Order import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestMethodOrder import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.kotlin.any @@ -46,8 +48,9 @@ import java.nio.charset.Charset @SpringBootTest @Tag("integration") +@TestMethodOrder(OrderAnnotation::class) @AutoConfigureWebTestClient(timeout = "36000") -@TestInstance(TestInstance.Lifecycle.PER_METHOD) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class OpenKlant2PartijMutationIT( @Autowired private val webTestClient: WebTestClient, ) { diff --git a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt index eeaef6df..21a84578 100644 --- a/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt +++ b/zgw/openklant/src/test/kotlin/nl/nlportal/openklant/graphql/OpenKlant2PartijQueryIT.kt @@ -68,7 +68,7 @@ class OpenKlant2PartijQueryIT( .build() } .header(HttpHeaders.CONTENT_TYPE, MediaType("application", "graphql").toString()) - .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/openKlant2TypeIntrospection.gql"))) + .body(BodyInserters.fromResource(ClassPathResource("/config/graphql/partijIntrospection.gql"))) .exchange() .expectStatus().isOk .expectBody() diff --git a/zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql b/zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql deleted file mode 100644 index 73c84553..00000000 --- a/zgw/openklant/src/test/resources/config/graphql/createDigitaleAdres.gql +++ /dev/null @@ -1,5 +0,0 @@ -mutation { - createDigitaleAdres(digitaleAdresRequest: {waarde: "0611111111", type: TELEFOONNUMMER, omschrijving: "Privè Telefoonnummer" }) { - - } -} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/createUserDigitaleAdres.gql b/zgw/openklant/src/test/resources/config/graphql/createUserDigitaleAdres.gql new file mode 100644 index 00000000..9dc102fd --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/createUserDigitaleAdres.gql @@ -0,0 +1,8 @@ +mutation { + createUserDigitaleAdres(digitaleAdresRequest: {waarde: "0611111111", type: TELEFOONNUMMER, omschrijving: "Privè telefoonnummer"}) { + uuid + waarde + type + omschrijving + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/digitaleAdresIntrospection.gql b/zgw/openklant/src/test/resources/config/graphql/digitaleAdresIntrospection.gql new file mode 100644 index 00000000..78445473 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/digitaleAdresIntrospection.gql @@ -0,0 +1,7 @@ +query { + __type(name: "DigitaleAdresResponse") { + kind + name + description + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/getUserDigitaleAdresen.gql b/zgw/openklant/src/test/resources/config/graphql/getUserDigitaleAdresen.gql new file mode 100644 index 00000000..8e436af6 --- /dev/null +++ b/zgw/openklant/src/test/resources/config/graphql/getUserDigitaleAdresen.gql @@ -0,0 +1,9 @@ + +query { + getUserDigitaleAdresen { + uuid + waarde + type + omschrijving + } +} \ No newline at end of file diff --git a/zgw/openklant/src/test/resources/config/graphql/openKlant2TypeIntrospection.gql b/zgw/openklant/src/test/resources/config/graphql/partijIntrospection.gql similarity index 100% rename from zgw/openklant/src/test/resources/config/graphql/openKlant2TypeIntrospection.gql rename to zgw/openklant/src/test/resources/config/graphql/partijIntrospection.gql