From f5e5074f6110840854b2a074bb1f9b8655d83deb Mon Sep 17 00:00:00 2001 From: andacata <1506402+andacata@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:10:36 +0100 Subject: [PATCH 1/3] feat: Add validation of required endpoints --- .../services/CredentialsServerService.kt | 48 +++++++++++-- .../credentials/CredentialsReceiver.kt | 11 +-- .../CredentialsIntegrationTests.kt | 71 ++++++++++++++++--- 3 files changed, 112 insertions(+), 18 deletions(-) diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt index 93ece69d..91f4d0ec 100644 --- a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt @@ -5,9 +5,7 @@ import com.izivia.ocpi.toolkit.modules.credentials.CredentialsInterface import com.izivia.ocpi.toolkit.modules.credentials.domain.Credentials import com.izivia.ocpi.toolkit.modules.credentials.repositories.CredentialsRoleRepository import com.izivia.ocpi.toolkit.modules.credentials.repositories.PartnerRepository -import com.izivia.ocpi.toolkit.modules.versions.domain.Version -import com.izivia.ocpi.toolkit.modules.versions.domain.VersionDetails -import com.izivia.ocpi.toolkit.modules.versions.domain.VersionNumber +import com.izivia.ocpi.toolkit.modules.versions.domain.* import com.izivia.ocpi.toolkit.transport.TransportClientBuilder import com.izivia.ocpi.toolkit.transport.domain.HttpMethod import com.izivia.ocpi.toolkit.transport.domain.HttpRequest @@ -17,7 +15,8 @@ class CredentialsServerService( private val partnerRepository: PartnerRepository, private val credentialsRoleRepository: CredentialsRoleRepository, private val transportClientBuilder: TransportClientBuilder, - private val serverVersionsUrlProvider: suspend () -> String + private val serverVersionsUrlProvider: suspend () -> String, + private val requiredClientEndpointsProvider: suspend () -> Map> ) : CredentialsInterface { override suspend fun get( @@ -202,9 +201,50 @@ class CredentialsServerService( ) } + checkRequiredClientEndpoints(versionDetail.endpoints) + partnerRepository.saveEndpoints(partnerUrl = credentials.url, endpoints = versionDetail.endpoints) } + private suspend fun checkRequiredClientEndpoints(endpoints: List) { + val requiredClientEndpoints = requiredClientEndpointsProvider() + + if (requiredClientEndpoints.isEmpty()) { + return + } + + val requiredClientAsReceiverEndpoints = requiredClientEndpoints[InterfaceRole.RECEIVER.name] ?: listOf() + val requiredClientAsSenderEndpoints = requiredClientEndpoints[InterfaceRole.SENDER.name] ?: listOf() + + endpoints + .find { it.identifier == ModuleID.credentials } + .let { + it ?: throw OcpiServerNoMatchingEndpointsException("${ModuleID.credentials} client endpoint missing") + } + + checkRequiredRoleEndpoints(endpoints, requiredClientAsReceiverEndpoints, InterfaceRole.RECEIVER) + checkRequiredRoleEndpoints(endpoints, requiredClientAsSenderEndpoints, InterfaceRole.SENDER) + } + + private suspend fun checkRequiredRoleEndpoints( + endpoints: List, + requiredEndpoints: List, + role: InterfaceRole + ) { + for (requiredEndpoint in requiredEndpoints) { + endpoints + .find { + requiredEndpoint == ModuleID.credentials + || (it.role == role && it.identifier == requiredEndpoint) + } + .let { + it ?: throw OcpiServerNoMatchingEndpointsException( + "${requiredEndpoint.name} as ${role.name} client endpoint missing" + ) + } + } + } + private suspend fun getCredentials(serverToken: String): Credentials = Credentials( token = serverToken, url = serverVersionsUrlProvider(), diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt index 780e8691..7ca7eea5 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt @@ -9,6 +9,8 @@ import com.izivia.ocpi.toolkit.modules.credentials.services.CredentialsServerSer import com.izivia.ocpi.toolkit.modules.locations.domain.BusinessDetails import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsServer import com.izivia.ocpi.toolkit.modules.versions.VersionsServer +import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole +import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.services.VersionDetailsService import com.izivia.ocpi.toolkit.modules.versions.services.VersionsService import com.izivia.ocpi.toolkit.samples.common.* @@ -38,14 +40,15 @@ fun main() { override suspend fun getCredentialsRoles(): List = listOf( CredentialRole( role = Role.EMSP, - businessDetails = BusinessDetails(name = "Receiver", website = null, logo = null), - partyId = "DEF", - countryCode = "FR" + business_details = BusinessDetails(name = "Receiver", website = null, logo = null), + party_id = "DEF", + country_code = "FR" ) ) }, transportClientBuilder = Http4kTransportClientBuilder(), - serverVersionsUrlProvider = { receiverVersionsUrl } + serverVersionsUrlProvider = { receiverVersionsUrl }, + requiredClientEndpointsProvider = { mapOf(InterfaceRole.RECEIVER.name to listOf(ModuleID.credentials)) } ) ).registerOn(receiverServer) VersionsServer( diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt index d2afd8ac..56f2d1ee 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt @@ -11,6 +11,8 @@ import com.izivia.ocpi.toolkit.modules.locations.domain.BusinessDetails import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsServer import com.izivia.ocpi.toolkit.modules.versions.VersionsClient import com.izivia.ocpi.toolkit.modules.versions.VersionsServer +import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole +import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.services.VersionDetailsService import com.izivia.ocpi.toolkit.modules.versions.services.VersionsService import com.izivia.ocpi.toolkit.samples.common.* @@ -23,6 +25,7 @@ import com.mongodb.client.MongoDatabase import kotlinx.coroutines.runBlocking import org.eclipse.jetty.client.HttpResponseException import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.litote.kmongo.eq import org.litote.kmongo.getCollection import strikt.api.expectCatching @@ -42,7 +45,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { private var database: MongoDatabase? = null - private fun setupReceiver(): ServerSetupResult { + private fun setupReceiver(requiredEndpoints: Map> = mapOf()): ServerSetupResult { if (database == null) database = buildDBClient().getDatabase("ocpi-2-2-1-tests") val receiverPartnerCollection = database!! .getCollection("receiver-server-${UUID.randomUUID()}") @@ -65,14 +68,15 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { override suspend fun getCredentialsRoles(): List = listOf( CredentialRole( role = Role.EMSP, - businessDetails = BusinessDetails(name = "Receiver", website = null, logo = null), - partyId = "DEF", - countryCode = "FR" + business_details = BusinessDetails(name = "Receiver", website = null, logo = null), + party_id = "DEF", + country_code = "FR" ) ) }, transportClientBuilder = Http4kTransportClientBuilder(), - serverVersionsUrlProvider = { receiverServerVersionsUrl } + serverVersionsUrlProvider = { receiverServerVersionsUrl }, + requiredClientEndpointsProvider = { requiredEndpoints } ) ).registerOn(receiverServer) VersionsServer( @@ -134,15 +138,15 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { // Setup sender (client) return CredentialsClientService( clientVersionsEndpointUrl = senderServerSetupResult.versionsEndpoint, - clientPartnerRepository = PartnerMongoRepository(collection = senderServerSetupResult.partnerCollection), + clientPlatformRepository = PartnerMongoRepository(collection = senderServerSetupResult.partnerCollection), clientVersionsRepository = VersionsCacheRepository(baseUrl = senderServerSetupResult.transport.baseUrl), clientCredentialsRoleRepository = object : CredentialsRoleRepository { override suspend fun getCredentialsRoles(): List = listOf( CredentialRole( role = Role.CPO, - businessDetails = BusinessDetails(name = "Sender", website = null, logo = null), - partyId = "ABC", - countryCode = "FR" + business_details = BusinessDetails(name = "Sender", website = null, logo = null), + party_id = "ABC", + country_code = "FR" ) ) }, @@ -248,9 +252,56 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { } } + @Test + fun `should not properly run registration process because required endpoints are missing`() { + val receiverServer = setupReceiver( + mapOf( + InterfaceRole.RECEIVER.name to listOf( + ModuleID.credentials, + ModuleID.locations + ), + InterfaceRole.SENDER.name to listOf( + ModuleID.chargingprofiles + ) + ) + ) + val senderServer = setupSender() + + val credentialsClientService = setupCredentialsSenderClient( + senderServerSetupResult = senderServer, + receiverServerSetupResult = receiverServer + ) + + // Store token A on the receiver side, that will be used by the sender to begin registration and store it as + // well in the client so that it knows what token to send + val tokenA = UUID.randomUUID().toString() + receiverServer.partnerCollection.insertOne(Partner(url = senderServer.versionsEndpoint, tokenA = tokenA)) + senderServer.partnerCollection.insertOne(Partner(url = receiverServer.versionsEndpoint, tokenA = tokenA)) + + // Start the servers + receiverServer.transport.start() + senderServer.transport.start() + + expectThat( + assertThrows { + runBlocking { + credentialsClientService.register() + } + } + ) { + get { statusCode } + .isEqualTo(OcpiStatus.SERVER_NO_MATCHING_ENDPOINTS.code) + } + + } + @Test fun `should properly run registration process then correct get credentials from receiver`() { - val receiverServer = setupReceiver() + val receiverServer = setupReceiver(mapOf( + InterfaceRole.RECEIVER.name to listOf( + ModuleID.credentials, + ModuleID.locations) + )) val senderServer = setupSender() val credentialsClientService = setupCredentialsSenderClient( From cb89ba6bb6a5fb90f19d2aa25c27a5a724c5e8a6 Mon Sep 17 00:00:00 2001 From: andacata <1506402+andacata@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:52:42 +0100 Subject: [PATCH 2/3] feat: Add validation of required endpoints --- .../services/CredentialsClientService.kt | 7 ++- .../credentials/services/CredentialsCommon.kt | 52 +++++++++++++++++++ .../services/CredentialsServerService.kt | 43 +-------------- .../credentials/CredentialsReceiver.kt | 10 ++-- .../samples/credentials/CredentialsSender.kt | 5 +- .../CredentialsIntegrationTests.kt | 42 ++++++++------- 6 files changed, 93 insertions(+), 66 deletions(-) create mode 100644 ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt index 1a89c8be..ba85a8f9 100644 --- a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt @@ -8,6 +8,7 @@ import com.izivia.ocpi.toolkit.modules.credentials.repositories.PartnerRepositor import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsClient import com.izivia.ocpi.toolkit.modules.versions.VersionsClient import com.izivia.ocpi.toolkit.modules.versions.domain.Endpoint +import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.domain.parseVersionNumber import com.izivia.ocpi.toolkit.modules.versions.repositories.VersionsRepository @@ -28,6 +29,7 @@ import com.izivia.ocpi.toolkit.transport.TransportClientBuilder * @property clientCredentialsRoleRepository client's repository to retrieve its role * @property serverVersionsEndpointUrl the versions endpoint url of the server (for the client to retrieve endpoints) * @property transportClientBuilder used to build a transport (will be used to create CredentialClient to make calls) + * @property requiredOtherPartEndpointsProvider the endpoints this client expects from the other part to provide */ class CredentialsClientService( private val clientVersionsEndpointUrl: String, @@ -35,7 +37,8 @@ class CredentialsClientService( private val clientVersionsRepository: VersionsRepository, private val clientCredentialsRoleRepository: CredentialsRoleRepository, private val serverVersionsEndpointUrl: String, - private val transportClientBuilder: TransportClientBuilder + private val transportClientBuilder: TransportClientBuilder, + private val requiredOtherPartEndpointsProvider: suspend () -> Map> ) { suspend fun get(): Credentials = clientPartnerRepository .getCredentialsClientToken(partnerUrl = serverVersionsEndpointUrl) @@ -226,6 +229,8 @@ class CredentialsClientService( it.data ?: throw OcpiResponseException(it.status_code, it.status_message ?: "unknown") } + CredentialsCommon.checkRequiredEndpoints(requiredOtherPartEndpointsProvider(), versionDetails.endpoints) + // Store version & endpoint return clientPartnerRepository.saveEndpoints( partnerUrl = serverVersionsEndpointUrl, diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt new file mode 100644 index 00000000..6b3338cf --- /dev/null +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt @@ -0,0 +1,52 @@ +package com.izivia.ocpi.toolkit.modules.credentials.services + +import com.izivia.ocpi.toolkit.common.OcpiServerNoMatchingEndpointsException +import com.izivia.ocpi.toolkit.modules.versions.domain.Endpoint +import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole +import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID + +class CredentialsCommon { + companion object { + fun checkRequiredEndpoints( + requiredEndpoints: Map>, + actualEndpoints: List + ) { + if (requiredEndpoints.isEmpty()) { + return + } + + val requiredOtherPartAsReceiverEndpoints = requiredEndpoints[InterfaceRole.RECEIVER] ?: listOf() + val requiredOtherPartAsSenderEndpoints = requiredEndpoints[InterfaceRole.SENDER] ?: listOf() + + actualEndpoints + .find { it.identifier == ModuleID.credentials } + .let { + it ?: throw OcpiServerNoMatchingEndpointsException( + "${ModuleID.credentials} other part endpoint missing" + ) + } + + checkRequiredRoleEndpoints(actualEndpoints, requiredOtherPartAsReceiverEndpoints, InterfaceRole.RECEIVER) + checkRequiredRoleEndpoints(actualEndpoints, requiredOtherPartAsSenderEndpoints, InterfaceRole.SENDER) + } + + private fun checkRequiredRoleEndpoints( + endpoints: List, + requiredEndpoints: List, + role: InterfaceRole + ) { + for (requiredEndpoint in requiredEndpoints) { + endpoints + .find { + requiredEndpoint == ModuleID.credentials || + (it.role == role && it.identifier == requiredEndpoint) + } + .let { + it ?: throw OcpiServerNoMatchingEndpointsException( + "${requiredEndpoint.name} as ${role.name} other part endpoint missing" + ) + } + } + } + } +} diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt index 91f4d0ec..c5b7218c 100644 --- a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt @@ -16,7 +16,7 @@ class CredentialsServerService( private val credentialsRoleRepository: CredentialsRoleRepository, private val transportClientBuilder: TransportClientBuilder, private val serverVersionsUrlProvider: suspend () -> String, - private val requiredClientEndpointsProvider: suspend () -> Map> + private val requiredOtherPartEndpointsProvider: suspend () -> Map> ) : CredentialsInterface { override suspend fun get( @@ -201,50 +201,11 @@ class CredentialsServerService( ) } - checkRequiredClientEndpoints(versionDetail.endpoints) + CredentialsCommon.checkRequiredEndpoints(requiredOtherPartEndpointsProvider(), versionDetail.endpoints) partnerRepository.saveEndpoints(partnerUrl = credentials.url, endpoints = versionDetail.endpoints) } - private suspend fun checkRequiredClientEndpoints(endpoints: List) { - val requiredClientEndpoints = requiredClientEndpointsProvider() - - if (requiredClientEndpoints.isEmpty()) { - return - } - - val requiredClientAsReceiverEndpoints = requiredClientEndpoints[InterfaceRole.RECEIVER.name] ?: listOf() - val requiredClientAsSenderEndpoints = requiredClientEndpoints[InterfaceRole.SENDER.name] ?: listOf() - - endpoints - .find { it.identifier == ModuleID.credentials } - .let { - it ?: throw OcpiServerNoMatchingEndpointsException("${ModuleID.credentials} client endpoint missing") - } - - checkRequiredRoleEndpoints(endpoints, requiredClientAsReceiverEndpoints, InterfaceRole.RECEIVER) - checkRequiredRoleEndpoints(endpoints, requiredClientAsSenderEndpoints, InterfaceRole.SENDER) - } - - private suspend fun checkRequiredRoleEndpoints( - endpoints: List, - requiredEndpoints: List, - role: InterfaceRole - ) { - for (requiredEndpoint in requiredEndpoints) { - endpoints - .find { - requiredEndpoint == ModuleID.credentials - || (it.role == role && it.identifier == requiredEndpoint) - } - .let { - it ?: throw OcpiServerNoMatchingEndpointsException( - "${requiredEndpoint.name} as ${role.name} client endpoint missing" - ) - } - } - } - private suspend fun getCredentials(serverToken: String): Credentials = Credentials( token = serverToken, url = serverVersionsUrlProvider(), diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt index 7ca7eea5..973684cc 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt @@ -32,6 +32,8 @@ fun main() { secureFilter = receiverPlatformRepository::checkToken ) + val requiredOtherPartEndpoints = mapOf(InterfaceRole.RECEIVER to listOf(ModuleID.credentials)) + runBlocking { CredentialsServer( service = CredentialsServerService( @@ -40,15 +42,15 @@ fun main() { override suspend fun getCredentialsRoles(): List = listOf( CredentialRole( role = Role.EMSP, - business_details = BusinessDetails(name = "Receiver", website = null, logo = null), - party_id = "DEF", - country_code = "FR" + businessDetails = BusinessDetails(name = "Receiver", website = null, logo = null), + partyId = "DEF", + countryCode = "FR" ) ) }, transportClientBuilder = Http4kTransportClientBuilder(), serverVersionsUrlProvider = { receiverVersionsUrl }, - requiredClientEndpointsProvider = { mapOf(InterfaceRole.RECEIVER.name to listOf(ModuleID.credentials)) } + requiredOtherPartEndpointsProvider = { requiredOtherPartEndpoints } ) ).registerOn(receiverServer) VersionsServer( diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt index c450665d..aaefb81f 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt @@ -8,6 +8,8 @@ import com.izivia.ocpi.toolkit.modules.credentials.services.CredentialsClientSer import com.izivia.ocpi.toolkit.modules.locations.domain.BusinessDetails import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsServer import com.izivia.ocpi.toolkit.modules.versions.VersionsServer +import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole +import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.services.VersionDetailsService import com.izivia.ocpi.toolkit.modules.versions.services.VersionsService import com.izivia.ocpi.toolkit.samples.common.* @@ -61,7 +63,8 @@ fun main() { ) }, serverVersionsEndpointUrl = receiverVersionsUrl, - transportClientBuilder = Http4kTransportClientBuilder() + transportClientBuilder = Http4kTransportClientBuilder(), + requiredOtherPartEndpointsProvider = { mapOf(InterfaceRole.RECEIVER to listOf(ModuleID.credentials)) } ) runBlocking { diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt index 56f2d1ee..c48d81bc 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt @@ -45,7 +45,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { private var database: MongoDatabase? = null - private fun setupReceiver(requiredEndpoints: Map> = mapOf()): ServerSetupResult { + private fun setupReceiver(requiredEndpoints: Map> = mapOf()): ServerSetupResult { if (database == null) database = buildDBClient().getDatabase("ocpi-2-2-1-tests") val receiverPartnerCollection = database!! .getCollection("receiver-server-${UUID.randomUUID()}") @@ -68,15 +68,15 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { override suspend fun getCredentialsRoles(): List = listOf( CredentialRole( role = Role.EMSP, - business_details = BusinessDetails(name = "Receiver", website = null, logo = null), - party_id = "DEF", - country_code = "FR" + businessDetails = BusinessDetails(name = "Receiver", website = null, logo = null), + partyId = "DEF", + countryCode = "FR" ) ) }, transportClientBuilder = Http4kTransportClientBuilder(), serverVersionsUrlProvider = { receiverServerVersionsUrl }, - requiredClientEndpointsProvider = { requiredEndpoints } + requiredOtherPartEndpointsProvider = { requiredEndpoints } ) ).registerOn(receiverServer) VersionsServer( @@ -133,25 +133,27 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { private fun setupCredentialsSenderClient( senderServerSetupResult: ServerSetupResult, - receiverServerSetupResult: ServerSetupResult + receiverServerSetupResult: ServerSetupResult, + requiredEndpoints: Map> = mapOf() ): CredentialsClientService { // Setup sender (client) return CredentialsClientService( clientVersionsEndpointUrl = senderServerSetupResult.versionsEndpoint, - clientPlatformRepository = PartnerMongoRepository(collection = senderServerSetupResult.partnerCollection), + clientPartnerRepository = PartnerMongoRepository(collection = senderServerSetupResult.partnerCollection), clientVersionsRepository = VersionsCacheRepository(baseUrl = senderServerSetupResult.transport.baseUrl), clientCredentialsRoleRepository = object : CredentialsRoleRepository { override suspend fun getCredentialsRoles(): List = listOf( CredentialRole( role = Role.CPO, - business_details = BusinessDetails(name = "Sender", website = null, logo = null), - party_id = "ABC", - country_code = "FR" + businessDetails = BusinessDetails(name = "Sender", website = null, logo = null), + partyId = "ABC", + countryCode = "FR" ) ) }, serverVersionsEndpointUrl = receiverServerSetupResult.versionsEndpoint, - transportClientBuilder = Http4kTransportClientBuilder() + transportClientBuilder = Http4kTransportClientBuilder(), + requiredOtherPartEndpointsProvider = { requiredEndpoints } ) } @@ -256,11 +258,11 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { fun `should not properly run registration process because required endpoints are missing`() { val receiverServer = setupReceiver( mapOf( - InterfaceRole.RECEIVER.name to listOf( + InterfaceRole.RECEIVER to listOf( ModuleID.credentials, ModuleID.locations ), - InterfaceRole.SENDER.name to listOf( + InterfaceRole.SENDER to listOf( ModuleID.chargingprofiles ) ) @@ -292,16 +294,18 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { get { statusCode } .isEqualTo(OcpiStatus.SERVER_NO_MATCHING_ENDPOINTS.code) } - } @Test fun `should properly run registration process then correct get credentials from receiver`() { - val receiverServer = setupReceiver(mapOf( - InterfaceRole.RECEIVER.name to listOf( - ModuleID.credentials, - ModuleID.locations) - )) + val receiverServer = setupReceiver( + mapOf( + InterfaceRole.RECEIVER to listOf( + ModuleID.credentials, + ModuleID.locations + ) + ) + ) val senderServer = setupSender() val credentialsClientService = setupCredentialsSenderClient( From 319816e5ab2c1a7fc4d8825bc739378560b0226c Mon Sep 17 00:00:00 2001 From: andacata <1506402+andacata@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:27:35 +0100 Subject: [PATCH 3/3] fix: PR comments --- .../services/CredentialsClientService.kt | 7 ++- .../credentials/services/CredentialsCommon.kt | 52 ------------------- .../services/CredentialsRequiredEndpoints.kt | 42 +++++++++++++++ .../services/CredentialsServerService.kt | 4 +- .../credentials/CredentialsReceiver.kt | 6 +-- .../samples/credentials/CredentialsSender.kt | 4 +- .../CredentialsIntegrationTests.kt | 28 ++++------ 7 files changed, 62 insertions(+), 81 deletions(-) delete mode 100644 ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt create mode 100644 ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsRequiredEndpoints.kt diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt index ba85a8f9..fc89e947 100644 --- a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsClientService.kt @@ -8,7 +8,6 @@ import com.izivia.ocpi.toolkit.modules.credentials.repositories.PartnerRepositor import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsClient import com.izivia.ocpi.toolkit.modules.versions.VersionsClient import com.izivia.ocpi.toolkit.modules.versions.domain.Endpoint -import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.domain.parseVersionNumber import com.izivia.ocpi.toolkit.modules.versions.repositories.VersionsRepository @@ -29,7 +28,7 @@ import com.izivia.ocpi.toolkit.transport.TransportClientBuilder * @property clientCredentialsRoleRepository client's repository to retrieve its role * @property serverVersionsEndpointUrl the versions endpoint url of the server (for the client to retrieve endpoints) * @property transportClientBuilder used to build a transport (will be used to create CredentialClient to make calls) - * @property requiredOtherPartEndpointsProvider the endpoints this client expects from the other part to provide + * @property requiredEndpoints the endpoints this client expects from the other part to provide */ class CredentialsClientService( private val clientVersionsEndpointUrl: String, @@ -38,7 +37,7 @@ class CredentialsClientService( private val clientCredentialsRoleRepository: CredentialsRoleRepository, private val serverVersionsEndpointUrl: String, private val transportClientBuilder: TransportClientBuilder, - private val requiredOtherPartEndpointsProvider: suspend () -> Map> + private val requiredEndpoints: RequiredEndpoints? ) { suspend fun get(): Credentials = clientPartnerRepository .getCredentialsClientToken(partnerUrl = serverVersionsEndpointUrl) @@ -229,7 +228,7 @@ class CredentialsClientService( it.data ?: throw OcpiResponseException(it.status_code, it.status_message ?: "unknown") } - CredentialsCommon.checkRequiredEndpoints(requiredOtherPartEndpointsProvider(), versionDetails.endpoints) + checkRequiredEndpoints(requiredEndpoints, versionDetails.endpoints) // Store version & endpoint return clientPartnerRepository.saveEndpoints( diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt deleted file mode 100644 index 6b3338cf..00000000 --- a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsCommon.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.izivia.ocpi.toolkit.modules.credentials.services - -import com.izivia.ocpi.toolkit.common.OcpiServerNoMatchingEndpointsException -import com.izivia.ocpi.toolkit.modules.versions.domain.Endpoint -import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole -import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID - -class CredentialsCommon { - companion object { - fun checkRequiredEndpoints( - requiredEndpoints: Map>, - actualEndpoints: List - ) { - if (requiredEndpoints.isEmpty()) { - return - } - - val requiredOtherPartAsReceiverEndpoints = requiredEndpoints[InterfaceRole.RECEIVER] ?: listOf() - val requiredOtherPartAsSenderEndpoints = requiredEndpoints[InterfaceRole.SENDER] ?: listOf() - - actualEndpoints - .find { it.identifier == ModuleID.credentials } - .let { - it ?: throw OcpiServerNoMatchingEndpointsException( - "${ModuleID.credentials} other part endpoint missing" - ) - } - - checkRequiredRoleEndpoints(actualEndpoints, requiredOtherPartAsReceiverEndpoints, InterfaceRole.RECEIVER) - checkRequiredRoleEndpoints(actualEndpoints, requiredOtherPartAsSenderEndpoints, InterfaceRole.SENDER) - } - - private fun checkRequiredRoleEndpoints( - endpoints: List, - requiredEndpoints: List, - role: InterfaceRole - ) { - for (requiredEndpoint in requiredEndpoints) { - endpoints - .find { - requiredEndpoint == ModuleID.credentials || - (it.role == role && it.identifier == requiredEndpoint) - } - .let { - it ?: throw OcpiServerNoMatchingEndpointsException( - "${requiredEndpoint.name} as ${role.name} other part endpoint missing" - ) - } - } - } - } -} diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsRequiredEndpoints.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsRequiredEndpoints.kt new file mode 100644 index 00000000..328e4e25 --- /dev/null +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsRequiredEndpoints.kt @@ -0,0 +1,42 @@ +package com.izivia.ocpi.toolkit.modules.credentials.services + +import com.izivia.ocpi.toolkit.common.OcpiServerNoMatchingEndpointsException +import com.izivia.ocpi.toolkit.modules.versions.domain.Endpoint +import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole +import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID + +data class RequiredEndpoints( + val receiver: List = listOf(), + val sender: List = listOf() +) + +fun checkRequiredEndpoints( + requiredEndpoints: RequiredEndpoints?, + actualEndpoints: List +) { + if (requiredEndpoints == null) { + return + } + + actualEndpoints + .find { it.identifier == ModuleID.credentials } + ?: throw OcpiServerNoMatchingEndpointsException("${ModuleID.credentials} endpoint missing") + + checkRequiredRoleEndpoints(actualEndpoints, requiredEndpoints.receiver, InterfaceRole.RECEIVER) + checkRequiredRoleEndpoints(actualEndpoints, requiredEndpoints.sender, InterfaceRole.SENDER) +} + +private fun checkRequiredRoleEndpoints( + endpoints: List, + requiredEndpoints: List, + role: InterfaceRole +) { + for (requiredEndpoint in requiredEndpoints) { + endpoints + .find { + requiredEndpoint == ModuleID.credentials || + (it.role == role && it.identifier == requiredEndpoint) + } + ?: throw OcpiServerNoMatchingEndpointsException("${requiredEndpoint.name} as ${role.name} endpoint missing") + } +} diff --git a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt index c5b7218c..24fd116a 100644 --- a/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt +++ b/ocpi-toolkit-2.2.1/src/main/kotlin/com/izivia/ocpi/toolkit/modules/credentials/services/CredentialsServerService.kt @@ -16,7 +16,7 @@ class CredentialsServerService( private val credentialsRoleRepository: CredentialsRoleRepository, private val transportClientBuilder: TransportClientBuilder, private val serverVersionsUrlProvider: suspend () -> String, - private val requiredOtherPartEndpointsProvider: suspend () -> Map> + private val requiredEndpoints: RequiredEndpoints? ) : CredentialsInterface { override suspend fun get( @@ -201,7 +201,7 @@ class CredentialsServerService( ) } - CredentialsCommon.checkRequiredEndpoints(requiredOtherPartEndpointsProvider(), versionDetail.endpoints) + checkRequiredEndpoints(requiredEndpoints, versionDetail.endpoints) partnerRepository.saveEndpoints(partnerUrl = credentials.url, endpoints = versionDetail.endpoints) } diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt index 973684cc..ca512643 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsReceiver.kt @@ -6,10 +6,10 @@ import com.izivia.ocpi.toolkit.modules.credentials.domain.CredentialRole import com.izivia.ocpi.toolkit.modules.credentials.domain.Role import com.izivia.ocpi.toolkit.modules.credentials.repositories.CredentialsRoleRepository import com.izivia.ocpi.toolkit.modules.credentials.services.CredentialsServerService +import com.izivia.ocpi.toolkit.modules.credentials.services.RequiredEndpoints import com.izivia.ocpi.toolkit.modules.locations.domain.BusinessDetails import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsServer import com.izivia.ocpi.toolkit.modules.versions.VersionsServer -import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.services.VersionDetailsService import com.izivia.ocpi.toolkit.modules.versions.services.VersionsService @@ -32,7 +32,7 @@ fun main() { secureFilter = receiverPlatformRepository::checkToken ) - val requiredOtherPartEndpoints = mapOf(InterfaceRole.RECEIVER to listOf(ModuleID.credentials)) + val requiredOtherPartEndpoints = RequiredEndpoints(receiver = listOf(ModuleID.credentials)) runBlocking { CredentialsServer( @@ -50,7 +50,7 @@ fun main() { }, transportClientBuilder = Http4kTransportClientBuilder(), serverVersionsUrlProvider = { receiverVersionsUrl }, - requiredOtherPartEndpointsProvider = { requiredOtherPartEndpoints } + requiredEndpoints = requiredOtherPartEndpoints ) ).registerOn(receiverServer) VersionsServer( diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt index aaefb81f..99e75135 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/credentials/CredentialsSender.kt @@ -5,10 +5,10 @@ import com.izivia.ocpi.toolkit.modules.credentials.domain.CredentialRole import com.izivia.ocpi.toolkit.modules.credentials.domain.Role import com.izivia.ocpi.toolkit.modules.credentials.repositories.CredentialsRoleRepository import com.izivia.ocpi.toolkit.modules.credentials.services.CredentialsClientService +import com.izivia.ocpi.toolkit.modules.credentials.services.RequiredEndpoints import com.izivia.ocpi.toolkit.modules.locations.domain.BusinessDetails import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsServer import com.izivia.ocpi.toolkit.modules.versions.VersionsServer -import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.services.VersionDetailsService import com.izivia.ocpi.toolkit.modules.versions.services.VersionsService @@ -64,7 +64,7 @@ fun main() { }, serverVersionsEndpointUrl = receiverVersionsUrl, transportClientBuilder = Http4kTransportClientBuilder(), - requiredOtherPartEndpointsProvider = { mapOf(InterfaceRole.RECEIVER to listOf(ModuleID.credentials)) } + requiredEndpoints = RequiredEndpoints(receiver = listOf(ModuleID.credentials)) ) runBlocking { diff --git a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt index c48d81bc..78ffe37f 100644 --- a/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt +++ b/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/CredentialsIntegrationTests.kt @@ -7,11 +7,11 @@ import com.izivia.ocpi.toolkit.modules.credentials.domain.Role import com.izivia.ocpi.toolkit.modules.credentials.repositories.CredentialsRoleRepository import com.izivia.ocpi.toolkit.modules.credentials.services.CredentialsClientService import com.izivia.ocpi.toolkit.modules.credentials.services.CredentialsServerService +import com.izivia.ocpi.toolkit.modules.credentials.services.RequiredEndpoints import com.izivia.ocpi.toolkit.modules.locations.domain.BusinessDetails import com.izivia.ocpi.toolkit.modules.versions.VersionDetailsServer import com.izivia.ocpi.toolkit.modules.versions.VersionsClient import com.izivia.ocpi.toolkit.modules.versions.VersionsServer -import com.izivia.ocpi.toolkit.modules.versions.domain.InterfaceRole import com.izivia.ocpi.toolkit.modules.versions.domain.ModuleID import com.izivia.ocpi.toolkit.modules.versions.services.VersionDetailsService import com.izivia.ocpi.toolkit.modules.versions.services.VersionsService @@ -45,7 +45,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { private var database: MongoDatabase? = null - private fun setupReceiver(requiredEndpoints: Map> = mapOf()): ServerSetupResult { + private fun setupReceiver(requiredEndpoints: RequiredEndpoints? = null): ServerSetupResult { if (database == null) database = buildDBClient().getDatabase("ocpi-2-2-1-tests") val receiverPartnerCollection = database!! .getCollection("receiver-server-${UUID.randomUUID()}") @@ -76,7 +76,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { }, transportClientBuilder = Http4kTransportClientBuilder(), serverVersionsUrlProvider = { receiverServerVersionsUrl }, - requiredOtherPartEndpointsProvider = { requiredEndpoints } + requiredEndpoints = requiredEndpoints ) ).registerOn(receiverServer) VersionsServer( @@ -134,7 +134,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { private fun setupCredentialsSenderClient( senderServerSetupResult: ServerSetupResult, receiverServerSetupResult: ServerSetupResult, - requiredEndpoints: Map> = mapOf() + requiredEndpoints: RequiredEndpoints? = null ): CredentialsClientService { // Setup sender (client) return CredentialsClientService( @@ -153,7 +153,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { }, serverVersionsEndpointUrl = receiverServerSetupResult.versionsEndpoint, transportClientBuilder = Http4kTransportClientBuilder(), - requiredOtherPartEndpointsProvider = { requiredEndpoints } + requiredEndpoints = requiredEndpoints ) } @@ -257,14 +257,9 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { @Test fun `should not properly run registration process because required endpoints are missing`() { val receiverServer = setupReceiver( - mapOf( - InterfaceRole.RECEIVER to listOf( - ModuleID.credentials, - ModuleID.locations - ), - InterfaceRole.SENDER to listOf( - ModuleID.chargingprofiles - ) + RequiredEndpoints( + receiver = listOf(ModuleID.credentials, ModuleID.locations), + sender = listOf(ModuleID.chargingprofiles) ) ) val senderServer = setupSender() @@ -299,11 +294,8 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() { @Test fun `should properly run registration process then correct get credentials from receiver`() { val receiverServer = setupReceiver( - mapOf( - InterfaceRole.RECEIVER to listOf( - ModuleID.credentials, - ModuleID.locations - ) + RequiredEndpoints( + receiver = listOf(ModuleID.credentials, ModuleID.locations) ) ) val senderServer = setupSender()