{"id":13634712,"url":"https://github.com/IZIVIA/ocpi-toolkit","last_synced_at":"2025-04-18T23:32:49.944Z","repository":{"id":37408042,"uuid":"497830391","full_name":"IZIVIA/ocpi-toolkit","owner":"IZIVIA","description":"a Kotlin library to perform OCPI operations","archived":false,"fork":false,"pushed_at":"2025-03-05T17:15:48.000Z","size":1306,"stargazers_count":27,"open_issues_count":19,"forks_count":10,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-05T18:29:06.951Z","etag":null,"topics":["cpo","e-mobility","electric-vehicles","emsp","ev-charging","ev-roaming","evse","kotlin","ocpi"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IZIVIA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-30T07:14:12.000Z","updated_at":"2025-03-05T17:15:22.000Z","dependencies_parsed_at":"2022-07-12T12:50:43.763Z","dependency_job_id":"2e54a3d8-1522-4f48-b8b7-c975dd166383","html_url":"https://github.com/IZIVIA/ocpi-toolkit","commit_stats":{"total_commits":379,"total_committers":10,"mean_commits":37.9,"dds":"0.26649076517150394","last_synced_commit":"4642efb20e733eb9c1b133be4fd4399271453d8c"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IZIVIA%2Focpi-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IZIVIA%2Focpi-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IZIVIA%2Focpi-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IZIVIA%2Focpi-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IZIVIA","download_url":"https://codeload.github.com/IZIVIA/ocpi-toolkit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249565249,"owners_count":21292427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpo","e-mobility","electric-vehicles","emsp","ev-charging","ev-roaming","evse","kotlin","ocpi"],"created_at":"2024-08-02T00:00:31.505Z","updated_at":"2025-04-18T23:32:49.562Z","avatar_url":"https://github.com/IZIVIA.png","language":"Kotlin","funding_links":[],"categories":["Tools and Resources"],"sub_categories":["OCPI"],"readme":"# Ocpi Toolkit\n\n![CI](https://img.shields.io/github/actions/workflow/status/izivia/ocpi-toolkit/ci.yml?style=for-the-badge) ![Latest Release](https://img.shields.io/github/v/tag/izivia/ocpi-toolkit?style=for-the-badge\u0026label=latest%20version)\n\nOpen Charge Point Interface (OCPI) kotlin library.\n\n\u003e ⚠️ Currently in active development. Not ready for production yet. See https://github.com/IZIVIA/ocpi-toolkit/issues/33 for details.\n\n## Setup\n\nIn your `build.gradle.kts`, add:\n\n```kts\ndependencies {\n    implementation(\"com.izivia:ocpi-2-2-1:0.0.15\")\n    implementation(\"com.izivia:ocpi-transport:0.0.15\")\n}\n```\n\nTo see all available artifacts, go to: https://central.sonatype.com/search?namespace=com.izivia\u0026q=ocpi\n\n## Usage\n\n**You have the following updated code samples in [ocpi-toolkit-2.2.1/src/test](https://github.com/IZIVIA/ocpi-toolkit/tree/main/ocpi-toolkit-2.2.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples).**\n\n### Server (CPO or eMSP)\n\nExamples:\n- [Http4kTransportServer](ocpi-toolkit-2.1.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/common/Http4kTransportServer.kt): `TransportServer` implementation example\n- [PartnerMongoRepository](ocpi-toolkit-2.1.1/src/test/kotlin/com/izivia/ocpi/toolkit/tests/integration/mock/PartnerMongoRepository.kt): `PartnerRepository` implementation example\n- [VersionsCacheRepository](ocpi-toolkit-2.1.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/common/VersionsCacheRepository.kt): `VersionsRepository` implementation example\n- [VersionDetailsCacheRepository](ocpi-toolkit-2.1.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/common/VersionDetailsCacheRepository.kt): `VersionsDetailsRepository` implementation example\n\n**Common code (CPO / eMSP):**\n\n```kotlin\n// PartnerMongoRepository is an implementation of PartnerRepository using mongo\n// It will be used to store information about partners with whom the server is communicating:\n// A partner has: Tokens (A, serverToken, clientToken), Endpoints, Versions, Roles\n// You can see an  example in the list above\nval partnerRepository = PartnerMongoRepository(\n    collection = mongoDatabase.getCollection\u003cLocation\u003e(config.partnerCollection)\n)\n\n// Http4kTransportServer is an implementation of TransportServer using htt4k. You have to code your own implementation.\n// It defines the HTTP server, and how to handle requests.\n// You can see an  example in the list above\nval server = Http4kTransportServer(\n    baseUrl = config.baseUrl, // Example: http://localhost:8080, only used for pagination\n    port = config.port, // Example: 8080, used to know on which port the server will run\n    secureFilter = senderPartnerRepository::checkToken // The filter called on secured routes\n)\n\n// VersionsCacheRepository is an implementation of VersionsRepository\n// It defines which OCPI version the server support, and the endpoints associated with it\n// You can see an  example in the list above\nval versionsRepository = VersionsCacheRepository()\n\n// VersionDetailsCacheRepository is an implementation of VersionDetailRepository\n// It defines the available modules (and their endpoint) for the given version\n// You can see an  example in the list above\nval versionDetailsRepository = VersionDetailsCacheRepository()\n\n// Required: defines /versions endpoint\nVersionsServer(\n    validationService = VersionsValidationService(\n        repository = versionsRepository\n    )\n).registerOn(server)\n\n// Required: defines /2.1.1, /2.2.1, whatever version endpoint\nVersionDetailsServer(\n    validationService = VersionDetailsValidationService(\n        repository = versionDetailsRepository\n    )\n).registerOn(server)\n\n// Required: defines /{version}/credentials endpoint for any client to register following OCPI protocol\nCredentialsServer(\n    service = CredentialsServerService(\n        partnerRepository = partnerRepository,\n        credentialsRoleRepository = object : CredentialsRoleRepository { ... },\n        transportClientBuilder = Http4kTransportClientBuilder(),\n        serverVersionsUrl = { versionsUrl }\n    )\n).registerOn(server)\n```\n\n**CPO code:**\n\n```kotlin\n// LocationsCpoMongoService is an implementation of LocationsCpoService\n// Used to know how to retrieve locations\nval locationsService = LocationsCpoMongoService()\n\n// Defines /{version}/locations endpoint for any registered client to retrieve locations\nLocationsCpoServer(\n    transportServer = server,\n    service = LocationsCpoValidationService(\n        service = locationsService\n    ),\n    partnerRepository = partnerRepository\n).registerOn(server)\n\n// Once that all the modules are defined, you need to start the server\nserver.start()\n```\n\n**eMSP code:**\n\n```kotlin\n// LocationsEmspMongoService is an implementation of LocationsEmspService\n// Used to know how to read / create / update / delete locations\nval locationsService = LocationsEmspMongoService()\n\n// Defines /{version}/locations endpoint for any registered client to retrieve locations (and also create / update /\n// delete)\nLocationsEmspServer(\n    service = LocationsEmspValidationService(\n        service = LocationsApiClient(\n            channel = chargingInfrastructureChannel\n        )\n    )\n).registerOn(server)\n\n// Once that all the modules are defined, you need to start the server\nserver.start()\n```\n\n**Optional arguments**\n\nIt is possible to change the default path of a module using `basePath` argument:\n\n```kotlin\nLocationsEmspServer(\n    service = service,\n    basePath = \"/2.1.1/cpo/locations\"\n).registerOn(server)\n```\n\nMake sure that `VersionDetailsRepository` points to the right endpoint (in that case `/2.1.1/cpo/locations`)\nfor the `locations` module.\n\n### Client\n\nExamples:\n- [Http4kTransportClient](ocpi-toolkit-2.1.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/common/Http4kTransportClient.kt): `TransportClient` implementation example\n- [Http4kTransportClientBuilder](ocpi-toolkit-2.1.1/src/test/kotlin/com/izivia/ocpi/toolkit/samples/common/Http4kTransportClientBuilder.kt): `TransportClientBuilder` implementation example\n\n\u003e **Note:** Since you need to register to communicate with a server (CPO or eMSP), to use the client, you must have a\n\u003e server defined with version \u0026 versionDetails modules. During registration, the receiver will make requests to these\n\u003e endpoints to retrieve the latest available version between the two servers. Note that if you strictly follow the OCPI\n\u003e protocol, you must also have a credentials module set. We don't enforce that in the lib.\n\n**Common (registration)**\n\n```kotlin\n// sender: the one that wants to register\n// receiver: the one that receives the registration request\n\n// PartnerMongoRepository is an implementation of PartnerRepository using mongo\n// It will be used to store information about partners with whom the client is communicating:\n// A partner has: Tokens (A, B, C), Endpoints, Versions\n// You can see an  example in the list above\nval senderPartnerRepository = PartnerMongoRepository(\n    collection = mongoDatabase.getCollection\u003cLocation\u003e(config.partnerCollection)\n)\n\n// VersionsCacheRepository is an implementation of VersionsRepository\n// It defines which OCPI version the client supports, and the endpoints associated with it\n// You can see an  example in the list above\nval senderVersionsRepository = VersionsCacheRepository()\n\n// Will be sent during registration for the receiver to use to request what versions the sender supports\nval senderVersionsEndpoint = \"https://sender.com/versions\"\n\n// Will be the first endpoint used by the sender to perform the registration process:\n// - First it retrieves the available versions, it picks the latest\n// - Then it retrieves the details of that version\n// - Finally it requests a registration on the credentials module of the receiver\nval receiverVersionsEndpoint = \"https://receiver.com/versions\"\n\n// Http4kTransportClientBuilder is used to build a transport client during runtime to make all the\n// registration process for you. You can do everything manually, but it's recommended to use CredentialsClientService.\n\nval credentialsClientService = CredentialsClientService(\n    clientVersionsEndpointUrl = senderVersionsEndpint,\n    partnerRepository = senderPartnerRepository,\n    clientVersionsRepository = senderVersionsRepository,\n    credentialsRoleRepository = object : CredentialsRoleRepository { ... },\n    serverVersionsUrlProvider = { receiverVersionsEndpoint },\n    transportClientBuilder = Http4kTransportClientBuilder()\n)\n\ncredentialsClientService.register()\n```\n\n**Communicating with an eMSP**\n\n```kotlin\n// Now that the CPO is registered with the eMSP, all the information (tokens \u0026 endpoints) is stored in\n// partnerRepository. It is now possible to access the locations module of the eMSP using LocationsCpoClient.\n\nval locationsCpoClient = LocationsCpoClient(\n    transportClientBuilder = Http4kTransportClientBuilder(),\n    serverVersionsEndpointUrl = \"https://emsp.com/versions\", // Used as ID for the partner (to retrieve information)\n    partnerRepository = partnerRepository\n)\n\n// Example on how to get a specific location\nlocationsCpoClient.getLocation(countryCode = \"fr\", partyId = \"abc\", locationId = \"location1\")\n```\n\n**Communicating with a CPO**\n\n```kotlin\n// Now that the eMSP is registered with the CPO, all the information (tokens \u0026 endpoints) is stored in\n// partnerRepository. It is now possible to access the locations module of the CPO using LocationsEmspClient.\n\nval locationsEmspClient = LocationsEmspClient(\n    transportClientBuilder = Http4kTransportClientBuilder(),\n    serverVersionsEndpointUrl = \"https://cpo.com/versions\",\n    partnerRepository = partnerRepository\n)\n\n// Example on how to get a specific location\nlocationsEmspClient.getLocation(locationId = \"location1\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FIZIVIA%2Focpi-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FIZIVIA%2Focpi-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FIZIVIA%2Focpi-toolkit/lists"}