-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(versions) #61: VersionDetails based on registered OcpiModuleServers #64
Conversation
atschabu
commented
Jan 12, 2024
- Merges Versions and VersionDetails server together and ensures consistency between registered handlers and returned version information
- OCPI servers register themselves with the VersionDetailsRepository, ensuring handlers and endpoint description has consistent path information
I can't see what SonarCloud is complaining about (no access) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job, I will test this new feature in our implementation to make sure I did not miss anything, but it looks good to me
) { req -> | ||
req.httpResponse { | ||
service.getVersionDetails( | ||
versionNumber = req.pathParams["versionNumber"]!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sonarcloud was complaining about that. I marked this issue as won't fix because handle
implementation has the responsability to make sure that specified pathParams
exist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested it against our multi tenant platform, and I found some issues
/** | ||
* The configured baseUrl this server listens to, used to generate NextPageUrl and Endpoint Url | ||
*/ | ||
fun baseUrl(): String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the lib, this field is only used by registerOn
of OcpiSelfRegisteringModuleServer
to specify the path of the endpoint of the module (Endpoint Url
).
According to your TransportServer
implementation, it can, indeed be the baseUrl
used to generate NextPageUrl
(as long as you pass it in the baseUrl
field of the HttpRequest
).
In our case, we have a multi tenant platform. So each platform can have its own baseUrl
to contact us. So we dynamically compute the baseUrl
every time we receive a request. In our case, we will not use baseUrl()
and we will not use automatic endpoint registration because each tenant has its set of endpoints it can access.
Knowing that, I would like to change the documentation to say something like:
The configured baseUrl this server listens to. ONLY used by the lib to generate Endpoint Url. You can use it in
handle
to specify thebaseUrl
ofHttpRequest
. In that case, it will be used to generateNextPageUrl
Then, in the lib, we have to make sure that this baseUrl
is not used anywhere else (the comment implies that it is not). If a baseUrl has to be used, it will be the one in HttpRequest
We can even rename it to staticBaseUrl()
, but I am not sure about that
basePath: String = "/2.2.1/credentials" | ||
) : OcpiModuleServer(basePath) { | ||
override suspend fun registerOn(transportServer: TransportServer) { | ||
versionsRepository: MutableVersionsRepository, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
versionsRepository: MutableVersionsRepository
should be nullable and be null by default everywhere. So if one wants to opt in automatic endpoint registration they can, but it is not a must have.
In our case we will not use it because we have a list of available endpoints for each tenant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to clarify, and mostly out of curiosity, why do you need various endpoints? Is it just so that it is not obvious to connecting parties that is a multi tenant system?
You could still benefit from this approach, by moving responsibility of adjusting endpoint URL's to the VersionServer. That's partly what I tried to achieve here too, move all the HTTP specific stuff as close as possible to the HTTP components, as a repository shouldn't need to know such specifics as our external facing URL (ideally that's just some config you pass in as an env var). In your case, where you pretend to be at a certain URL for certain incoming connections, you could store the external baseUrl within your partner repo, provide a placeholder value in the baseUrl, and then have the VersionsServer replace(placeholder, actualValue).
Once #62 is implemented, you could do it in the VersionsService
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each tenant has its sets of visible endpoints. We hold the tenant information in coroutines context. Moreover, we have separate server for registration and the rest. So the baseUrl of version / credentials is different from locations for instance.
Yes we could benefit from that, but we liked the fact that the way we implemented things was straightforward. We have a configuration that specifies with tenant can see what, and this config is only used at one place, in the VersionsRepository (all this logic is centralized in one place). We may change our minds later on, but as of now it works well that way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to that, we do not have access of versions repository from our other server, so we can not use automatic endpoint registration. Yes we could call endpoints from our other server to our credentials server, but if it's only to perform automatic endpoint registration, it is not worth the cost of development.
But we understand that this feature is really relevant for a lot of other cases ;)
I will review your work asap today (I've been very busy yesterday) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your improvements :)
I have a last request, and we will be good (I tested the lib with this change and it's working properly)
import com.izivia.ocpi.toolkit.modules.versions.repositories.VersionsRepository | ||
|
||
class VersionsService( | ||
private val repository: VersionsRepository | ||
private val repository: VersionsRepository, | ||
private val baseUrl: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should take advantage of coroutines here and use a baseUrlProvider
(that is what is done in CredentialsServerService
)
private val baseUrl: String, | |
private val baseUrlProvider: suspend () -> String, |
It allows anyone to use coroutine context to hold information about baseUrl
. That is what we do in our multi tenant platform
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a feeling I'm missing an exciting feature of kotlin ... do you have any example of how to make use of coroutine context for this particular use case? Or will PR for #62 contain an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR for #62 will contain examples, but we have something that looks like this:
VersionsService(
repository = MyVersionsRepository(),
baseUrlProvider = { config.ofCurrentTenant().baseUrl },
// ...
)
repository.getVersions().map { | ||
Version( | ||
version = it.value, | ||
url = "$baseUrl$versionDetailsBasePath/${it.value}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
url = "$baseUrl$versionDetailsBasePath/${it.value}" | |
url = "${baseUrlProvider()}$versionDetailsBasePath/${it.value}" |
Quality Gate passedKudos, no new issues were introduced! 0 New issues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your work !
glad to improve this great library ... and thanks for considering it, even though you don't benefit from it (yet) |
We are currently developing the Session module in our platform, so we already benefit from your contributions ;) |