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(