From 5864cbcbfe2eb8c36ca05c3a39c7e5916aeecaec Mon Sep 17 00:00:00 2001 From: Dante Niewenhuis Date: Tue, 5 Mar 2024 13:23:57 +0100 Subject: Updated package versions, updated web server tests. (#207) * Updated all package versions including kotlin. Updated all web-server tests to run. * Changed the java version of the tests. OpenDC now only supports java 19. * small update * test update * new update * updated docker version to 19 * updated docker version to 19 --- .../org/opendc/web/client/PortfolioResource.kt | 15 ++++- .../org/opendc/web/client/ScenarioResource.kt | 21 +++++-- .../org/opendc/web/client/TopologyResource.kt | 21 +++++-- .../opendc/web/client/auth/OpenIdAuthController.kt | 55 +++++++++-------- .../org/opendc/web/client/internal/ClientUtils.kt | 10 ++- .../web/client/internal/OAuthTokenRequest.kt | 8 +-- .../web/client/internal/OAuthTokenResponse.kt | 2 +- .../web/client/internal/OpenIdConfiguration.kt | 2 +- .../org/opendc/web/client/runner/JobResource.kt | 5 +- .../web/client/transport/HttpTransportClient.kt | 71 ++++++++++++++-------- .../opendc/web/client/transport/TransportClient.kt | 22 +++++-- 11 files changed, 158 insertions(+), 74 deletions(-) (limited to 'opendc-web/opendc-web-client/src') diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/PortfolioResource.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/PortfolioResource.kt index 399804e8..f0e49973 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/PortfolioResource.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/PortfolioResource.kt @@ -40,19 +40,28 @@ public class PortfolioResource internal constructor(private val client: Transpor /** * Obtain the portfolio for [project] with [number]. */ - public fun get(project: Long, number: Int): Portfolio? = client.get("projects/$project/portfolios/$number") + public fun get( + project: Long, + number: Int, + ): Portfolio? = client.get("projects/$project/portfolios/$number") /** * Create a new portfolio for [project] with the specified [request]. */ - public fun create(project: Long, request: Portfolio.Create): Portfolio { + public fun create( + project: Long, + request: Portfolio.Create, + ): Portfolio { return checkNotNull(client.post("projects/$project/portfolios", request)) } /** * Delete the portfolio for [project] with [index]. */ - public fun delete(project: Long, index: Int): Portfolio { + public fun delete( + project: Long, + index: Int, + ): Portfolio { return requireNotNull(client.delete("projects/$project/portfolios/$index")) { "Unknown portfolio $index" } } } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/ScenarioResource.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/ScenarioResource.kt index 7055e752..d43515a9 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/ScenarioResource.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/ScenarioResource.kt @@ -40,24 +40,37 @@ public class ScenarioResource internal constructor(private val client: Transport /** * List all scenarios that belong to the specified [portfolioNumber]. */ - public fun getAll(project: Long, portfolioNumber: Int): List = client.get("projects/$project/portfolios/$portfolioNumber/scenarios") ?: emptyList() + public fun getAll( + project: Long, + portfolioNumber: Int, + ): List = client.get("projects/$project/portfolios/$portfolioNumber/scenarios") ?: emptyList() /** * Obtain the scenario for [project] with [index]. */ - public fun get(project: Long, index: Int): Scenario? = client.get("projects/$project/scenarios/$index") + public fun get( + project: Long, + index: Int, + ): Scenario? = client.get("projects/$project/scenarios/$index") /** * Create a new scenario for [portfolio][portfolioNumber] with the specified [request]. */ - public fun create(project: Long, portfolioNumber: Int, request: Scenario.Create): Scenario { + public fun create( + project: Long, + portfolioNumber: Int, + request: Scenario.Create, + ): Scenario { return checkNotNull(client.post("projects/$project/portfolios/$portfolioNumber", request)) } /** * Delete the scenario for [project] with [index]. */ - public fun delete(project: Long, index: Int): Scenario { + public fun delete( + project: Long, + index: Int, + ): Scenario { return requireNotNull(client.delete("projects/$project/scenarios/$index")) { "Unknown scenario $index" } } } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/TopologyResource.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/TopologyResource.kt index c37ae8da..34f5ea1b 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/TopologyResource.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/TopologyResource.kt @@ -41,26 +41,39 @@ public class TopologyResource internal constructor(private val client: Transport /** * Obtain the topology for [project] with [index]. */ - public fun get(project: Long, index: Int): Topology? = client.get("projects/$project/topologies/$index") + public fun get( + project: Long, + index: Int, + ): Topology? = client.get("projects/$project/topologies/$index") /** * Create a new topology for [project] with [request]. */ - public fun create(project: Long, request: Topology.Create): Topology { + public fun create( + project: Long, + request: Topology.Create, + ): Topology { return checkNotNull(client.post("projects/$project/topologies", request)) } /** * Update the topology with [index] for [project] using the specified [request]. */ - public fun update(project: Long, index: Int, request: Topology.Update): Topology? { + public fun update( + project: Long, + index: Int, + request: Topology.Update, + ): Topology? { return client.put("projects/$project/topologies/$index", request) } /** * Delete the topology for [project] with [index]. */ - public fun delete(project: Long, index: Long): Topology { + public fun delete( + project: Long, + index: Long, + ): Topology { return requireNotNull(client.delete("projects/$project/topologies/$index")) { "Unknown topology $index" } } } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/auth/OpenIdAuthController.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/auth/OpenIdAuthController.kt index 7f9cbacd..707dc138 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/auth/OpenIdAuthController.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/auth/OpenIdAuthController.kt @@ -41,39 +41,40 @@ public class OpenIdAuthController( private val clientId: String, private val clientSecret: String, private val audience: String = "https://api.opendc.org/v2/", - private val client: HttpClient = HttpClient.newHttpClient() + private val client: HttpClient = HttpClient.newHttpClient(), ) : AuthController { /** * The Jackson object mapper to convert messages from/to JSON. */ - private val mapper = jacksonObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + private val mapper = + jacksonObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) /** * The cached [OpenIdConfiguration]. */ private val openidConfig: OpenIdConfiguration get() { - var openidConfig = _openidConfig + var openidConfig = localOpenidConfig if (openidConfig == null) { openidConfig = requestConfig() - _openidConfig = openidConfig + localOpenidConfig = openidConfig } return openidConfig } - private var _openidConfig: OpenIdConfiguration? = null + private var localOpenidConfig: OpenIdConfiguration? = null /** * The cached OAuth token. */ - private var _token: OAuthTokenResponse? = null + private var localToken: OAuthTokenResponse? = null override fun injectToken(request: HttpRequest.Builder) { - var token = _token + var token = localToken if (token == null) { token = requestToken() - _token = token + localToken = token } request.header("Authorization", "Bearer ${token.accessToken}") @@ -83,22 +84,23 @@ public class OpenIdAuthController( * Refresh the current access token. */ override fun refreshToken() { - val refreshToken = _token?.refreshToken + val refreshToken = localToken?.refreshToken if (refreshToken == null) { requestToken() return } - _token = refreshToken(openidConfig, refreshToken) + localToken = refreshToken(openidConfig, refreshToken) } /** * Request the OpenID configuration from the chosen auth domain */ private fun requestConfig(): OpenIdConfiguration { - val request = HttpRequest.newBuilder(URI("https://$domain/.well-known/openid-configuration")) - .GET() - .build() + val request = + HttpRequest.newBuilder(URI("https://$domain/.well-known/openid-configuration")) + .GET() + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return mapper.readValue(response.body()) } @@ -108,10 +110,11 @@ public class OpenIdAuthController( */ private fun requestToken(openidConfig: OpenIdConfiguration): OAuthTokenResponse { val body = OAuthTokenRequest.ClientCredentials(audience, clientId, clientSecret) - val request = HttpRequest.newBuilder(openidConfig.tokenEndpoint) - .header("Content-Type", "application/json") - .POST(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) - .build() + val request = + HttpRequest.newBuilder(openidConfig.tokenEndpoint) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return mapper.readValue(response.body()) } @@ -119,12 +122,16 @@ public class OpenIdAuthController( /** * Helper method to refresh the auth token. */ - private fun refreshToken(openidConfig: OpenIdConfiguration, refreshToken: String): OAuthTokenResponse { + private fun refreshToken( + openidConfig: OpenIdConfiguration, + refreshToken: String, + ): OAuthTokenResponse { val body = OAuthTokenRequest.RefreshToken(refreshToken, clientId, clientSecret) - val request = HttpRequest.newBuilder(openidConfig.tokenEndpoint) - .header("Content-Type", "application/json") - .POST(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) - .build() + val request = + HttpRequest.newBuilder(openidConfig.tokenEndpoint) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return mapper.readValue(response.body()) } @@ -134,7 +141,7 @@ public class OpenIdAuthController( */ private fun requestToken(): OAuthTokenResponse { val token = requestToken(openidConfig) - _token = token + localToken = token return token } } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/ClientUtils.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/ClientUtils.kt index 29cf09dc..1ffaa602 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/ClientUtils.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/ClientUtils.kt @@ -35,14 +35,20 @@ internal inline fun TransportClient.get(path: String): T? { /** * Perform a POST request for resource at [path] and convert to type [T]. */ -internal inline fun TransportClient.post(path: String, body: B): T? { +internal inline fun TransportClient.post( + path: String, + body: B, +): T? { return post(path, body, object : TypeReference() {}) } /** * Perform a PUT request for resource at [path] and convert to type [T]. */ -internal inline fun TransportClient.put(path: String, body: B): T? { +internal inline fun TransportClient.put( + path: String, + body: B, +): T? { return put(path, body, object : TypeReference() {}) } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenRequest.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenRequest.kt index 25341995..1bb06c8f 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenRequest.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenRequest.kt @@ -33,8 +33,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo @JsonSubTypes( value = [ JsonSubTypes.Type(value = OAuthTokenRequest.ClientCredentials::class, name = "client_credentials"), - JsonSubTypes.Type(value = OAuthTokenRequest.RefreshToken::class, name = "refresh_token") - ] + JsonSubTypes.Type(value = OAuthTokenRequest.RefreshToken::class, name = "refresh_token"), + ], ) internal sealed class OAuthTokenRequest { /** @@ -45,7 +45,7 @@ internal sealed class OAuthTokenRequest { @JsonProperty("client_id") val clientId: String, @JsonProperty("client_secret") - val clientSecret: String + val clientSecret: String, ) : OAuthTokenRequest() /** @@ -57,6 +57,6 @@ internal sealed class OAuthTokenRequest { @JsonProperty("client_id") val clientId: String, @JsonProperty("client_secret") - val clientSecret: String + val clientSecret: String, ) : OAuthTokenRequest() } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenResponse.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenResponse.kt index cd5ccab0..76fe007c 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenResponse.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OAuthTokenResponse.kt @@ -36,5 +36,5 @@ internal data class OAuthTokenResponse( val tokenType: String, val scope: String = "", @JsonProperty("expires_in") - val expiresIn: Long + val expiresIn: Long, ) diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OpenIdConfiguration.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OpenIdConfiguration.kt index 23fbf368..eac1607e 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OpenIdConfiguration.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/internal/OpenIdConfiguration.kt @@ -39,5 +39,5 @@ internal data class OpenIdConfiguration( @JsonProperty("jwks_uri") val jwksUri: URI, @JsonProperty("scopes_supported") - val scopesSupported: Set + val scopesSupported: Set, ) diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/runner/JobResource.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/runner/JobResource.kt index ad3f1c9b..e72f703c 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/runner/JobResource.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/runner/JobResource.kt @@ -44,5 +44,8 @@ public class JobResource internal constructor(private val client: TransportClien /** * Update the job with [id]. */ - public fun update(id: Long, update: Job.Update): Job? = client.post("jobs/$id", update) + public fun update( + id: Long, + update: Job.Update, + ): Job? = client.post("jobs/$id", update) } diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/HttpTransportClient.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/HttpTransportClient.kt index e407380b..f6dca4d1 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/HttpTransportClient.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/HttpTransportClient.kt @@ -43,23 +43,28 @@ import java.nio.file.Paths public class HttpTransportClient( private val baseUrl: URI, private val auth: AuthController?, - private val client: HttpClient = HttpClient.newHttpClient() + private val client: HttpClient = HttpClient.newHttpClient(), ) : TransportClient { /** * The Jackson object mapper to convert messages from/to JSON. */ - private val mapper = jacksonObjectMapper() - .registerModule(JavaTimeModule()) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + private val mapper = + jacksonObjectMapper() + .registerModule(JavaTimeModule()) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) /** * Obtain a resource at [path] of [targetType]. */ - override fun get(path: String, targetType: TypeReference): T? { - val request = HttpRequest.newBuilder(buildUri(path)) - .GET() - .also { auth?.injectToken(it) } - .build() + override fun get( + path: String, + targetType: TypeReference, + ): T? { + val request = + HttpRequest.newBuilder(buildUri(path)) + .GET() + .also { auth?.injectToken(it) } + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return when (val code = response.statusCode()) { @@ -81,12 +86,17 @@ public class HttpTransportClient( /** * Update a resource at [path] of [targetType]. */ - override fun post(path: String, body: B, targetType: TypeReference): T? { - val request = HttpRequest.newBuilder(buildUri(path)) - .POST(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) - .header("Content-Type", "application/json") - .also { auth?.injectToken(it) } - .build() + override fun post( + path: String, + body: B, + targetType: TypeReference, + ): T? { + val request = + HttpRequest.newBuilder(buildUri(path)) + .POST(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) + .header("Content-Type", "application/json") + .also { auth?.injectToken(it) } + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return when (val code = response.statusCode()) { @@ -108,12 +118,17 @@ public class HttpTransportClient( /** * Replace a resource at [path] of [targetType]. */ - override fun put(path: String, body: B, targetType: TypeReference): T? { - val request = HttpRequest.newBuilder(buildUri(path)) - .PUT(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) - .header("Content-Type", "application/json") - .also { auth?.injectToken(it) } - .build() + override fun put( + path: String, + body: B, + targetType: TypeReference, + ): T? { + val request = + HttpRequest.newBuilder(buildUri(path)) + .PUT(HttpRequest.BodyPublishers.ofByteArray(mapper.writeValueAsBytes(body))) + .header("Content-Type", "application/json") + .also { auth?.injectToken(it) } + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return when (val code = response.statusCode()) { @@ -135,11 +150,15 @@ public class HttpTransportClient( /** * Delete a resource at [path] of [targetType]. */ - override fun delete(path: String, targetType: TypeReference): T? { - val request = HttpRequest.newBuilder(buildUri(path)) - .DELETE() - .also { auth?.injectToken(it) } - .build() + override fun delete( + path: String, + targetType: TypeReference, + ): T? { + val request = + HttpRequest.newBuilder(buildUri(path)) + .DELETE() + .also { auth?.injectToken(it) } + .build() val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream()) return when (val code = response.statusCode()) { diff --git a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/TransportClient.kt b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/TransportClient.kt index af727ca7..ebf3402f 100644 --- a/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/TransportClient.kt +++ b/opendc-web/opendc-web-client/src/main/kotlin/org/opendc/web/client/transport/TransportClient.kt @@ -31,20 +31,34 @@ public interface TransportClient { /** * Obtain a resource at [path] of [targetType]. */ - public fun get(path: String, targetType: TypeReference): T? + public fun get( + path: String, + targetType: TypeReference, + ): T? /** * Update a resource at [path] of [targetType]. */ - public fun post(path: String, body: B, targetType: TypeReference): T? + public fun post( + path: String, + body: B, + targetType: TypeReference, + ): T? /** * Replace a resource at [path] of [targetType]. */ - public fun put(path: String, body: B, targetType: TypeReference): T? + public fun put( + path: String, + body: B, + targetType: TypeReference, + ): T? /** * Delete a resource at [path] of [targetType]. */ - public fun delete(path: String, targetType: TypeReference): T? + public fun delete( + path: String, + targetType: TypeReference, + ): T? } -- cgit v1.2.3