Skip to content

Commit

Permalink
feat: Add validation of required endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
andacata authored and lilgallon committed Jan 9, 2024
1 parent 16c624f commit 5a3c162
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<String, List<ModuleID>>
) : CredentialsInterface {

override suspend fun get(
Expand Down Expand Up @@ -202,9 +201,50 @@ class CredentialsServerService(
)
}

checkRequiredClientEndpoints(versionDetail.endpoints)

partnerRepository.saveEndpoints(partnerUrl = credentials.url, endpoints = versionDetail.endpoints)
}

private suspend fun checkRequiredClientEndpoints(endpoints: List<Endpoint>) {
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<Endpoint>,
requiredEndpoints: List<ModuleID>,
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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down Expand Up @@ -38,14 +40,15 @@ fun main() {
override suspend fun getCredentialsRoles(): List<CredentialRole> = 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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand All @@ -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
Expand All @@ -42,7 +45,7 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() {

private var database: MongoDatabase? = null

private fun setupReceiver(): ServerSetupResult {
private fun setupReceiver(requiredEndpoints: Map<String, List<ModuleID>> = mapOf()): ServerSetupResult {
if (database == null) database = buildDBClient().getDatabase("ocpi-2-2-1-tests")
val receiverPartnerCollection = database!!
.getCollection<Partner>("receiver-server-${UUID.randomUUID()}")
Expand All @@ -65,14 +68,15 @@ class CredentialsIntegrationTests : BaseServerIntegrationTest() {
override suspend fun getCredentialsRoles(): List<CredentialRole> = 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(
Expand Down Expand Up @@ -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<CredentialRole> = 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"
)
)
},
Expand Down Expand Up @@ -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<OcpiResponseException> {
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(
Expand Down

0 comments on commit 5a3c162

Please sign in to comment.