diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2022-03-07 17:58:08 +0100 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2022-04-04 12:48:05 +0200 |
| commit | d12efc754a1611a624d170b4d1fa6085e6bb177b (patch) | |
| tree | 13f70f3c2db7fa82f89a400a9001666bee81ec87 | |
| parent | abac46fe742484c6e0b90bebe3c86d88231540b2 (diff) | |
refactor(web/runner): Update runner to use new web client
This change updates the web runner implementation to use the new API
client introduced in the previous commit.
23 files changed, 63 insertions, 1124 deletions
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4411bd87..fbed7e7b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,6 @@ kotlin = "1.6.10" kotlin-logging = "2.1.21" kotlinx-coroutines = "1.6.0" ktlint-gradle = "10.2.1" -ktor = "1.6.7" log4j = "2.17.1" microprofile-openapi = "3.0" mockk = "1.12.2" @@ -94,12 +93,6 @@ quarkus-test-security = { module = "io.quarkus:quarkus-test-security" } restassured-core = { module = "io.rest-assured:rest-assured" } restassured-kotlin = { module = "io.rest-assured:kotlin-extensions" } -# HTTP client -ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } -ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } -ktor-client-jackson = { module = "io.ktor:ktor-client-jackson", version.ref = "ktor" } -ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } - # Other classgraph = { module = "io.github.classgraph:classgraph", version.ref = "classgraph" } jakarta-validation = { module = "jakarta.validation:jakarta.validation-api", version.ref = "jakarta-validation" } diff --git a/opendc-web/opendc-web-runner/build.gradle.kts b/opendc-web/opendc-web-runner/build.gradle.kts index a73ca6b3..3c80f605 100644 --- a/opendc-web/opendc-web-runner/build.gradle.kts +++ b/opendc-web/opendc-web-runner/build.gradle.kts @@ -40,18 +40,13 @@ dependencies { implementation(projects.opendcTelemetry.opendcTelemetrySdk) implementation(projects.opendcTelemetry.opendcTelemetryCompute) implementation(projects.opendcTrace.opendcTraceApi) + implementation(projects.opendcWeb.opendcWebClient) implementation(libs.kotlin.logging) implementation(libs.clikt) implementation(libs.sentry.log4j2) - implementation(libs.ktor.client.cio) - implementation(libs.ktor.client.auth) - implementation(libs.ktor.client.jackson) - implementation(libs.jackson.datatype.jsr310) implementation(kotlin("reflect")) runtimeOnly(projects.opendcTrace.opendcTraceOpendc) runtimeOnly(libs.log4j.slf4j) - - testImplementation(libs.ktor.client.mock) } diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiClient.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiClient.kt deleted file mode 100644 index 9f2656c4..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiClient.kt +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import io.ktor.client.* -import io.ktor.client.features.auth.* -import io.ktor.client.features.auth.providers.* -import io.ktor.client.features.json.* -import io.ktor.client.request.* -import io.ktor.client.statement.* -import io.ktor.http.* -import org.opendc.web.client.model.* -import java.net.URI - -/** - * Client implementation for the OpenDC REST API (version 2). - * - * @param baseUrl The base url of the API. - * @param auth The authentication configuration for the client. - * @param client The HTTP client to use. - */ -public class ApiClient( - private val baseUrl: URI, - private val auth: AuthConfiguration, - private val audience: String = "https://api.opendc.org/v2/", - client: HttpClient = HttpClient {} -) : AutoCloseable { - /** - * The Ktor [HttpClient] that is used to communicate with the REST API. - */ - private val client = client.config { - install(JsonFeature) { - serializer = JacksonSerializer { - registerModule(JavaTimeModule()) - } - } - install(Auth) { - bearer { - loadTokens { requestToken() } - refreshTokens { requestToken() } - } - } - expectSuccess = false - } - - /** - * Retrieve the topology with the specified [id]. - */ - public suspend fun getPortfolio(id: String): Portfolio? { - val url = URLBuilder(Url(baseUrl)) - .path("portfolios", id) - .build() - return when (val result = client.get<ApiResult<Portfolio>>(url)) { - is ApiResult.Success -> result.data - else -> null - } - } - - /** - * Retrieve the scenario with the specified [id]. - */ - public suspend fun getScenario(id: String): Scenario? { - val url = URLBuilder(Url(baseUrl)) - .path("scenarios", id) - .build() - return when (val result = client.get<ApiResult<Scenario>>(url)) { - is ApiResult.Success -> result.data - else -> null - } - } - - /** - * Retrieve the topology with the specified [id]. - */ - public suspend fun getTopology(id: String): Topology? { - val url = URLBuilder(Url(baseUrl)) - .path("topologies", id) - .build() - return when (val result = client.get<ApiResult<Topology>>(url)) { - is ApiResult.Success -> result.data - else -> null - } - } - - /** - * Retrieve the available jobs. - */ - public suspend fun getJobs(): List<Job> { - val url = URLBuilder(Url(baseUrl)) - .path("jobs") - .build() - return when (val result = client.get<ApiResult<List<Job>>>(url)) { - is ApiResult.Success -> result.data - else -> emptyList() - } - } - - /** - * Update the specified job. - * - * @param id The identifier of the job. - * @param state The new state of the job. - * @param results The results of the job. - */ - public suspend fun updateJob(id: String, state: SimulationState, results: Map<String, Any> = emptyMap()): Boolean { - val url = URLBuilder(Url(baseUrl)) - .path("jobs", id) - .build() - - data class Request( - val state: SimulationState, - val results: Map<String, Any> - ) - - val res = client.post<HttpResponse> { - url(url) - contentType(ContentType.Application.Json) - body = Request(state, results) - } - return res.status.isSuccess() - } - - /** - * Request the auth token for the API. - */ - private suspend fun requestToken(): BearerTokens { - data class Request( - val audience: String, - @JsonProperty("grant_type") - val grantType: String, - @JsonProperty("client_id") - val clientId: String, - @JsonProperty("client_secret") - val clientSecret: String - ) - - data class Response( - @JsonProperty("access_token") - val accessToken: String, - @JsonProperty("token_type") - val tokenType: String, - val scope: String = "", - @JsonProperty("expires_in") - val expiresIn: Long - ) - - val result = client.post<Response> { - url(Url("https://${auth.domain}/oauth/token")) - contentType(ContentType.Application.Json) - body = Request(audience, "client_credentials", auth.clientId, auth.clientSecret) - } - - return BearerTokens(result.accessToken, "") - } - - override fun close() = client.close() -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiResult.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiResult.kt deleted file mode 100644 index a3df01c5..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiResult.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client - -import com.fasterxml.jackson.annotation.JsonSubTypes -import com.fasterxml.jackson.annotation.JsonTypeInfo - -/** - * Generic response model for the OpenDC API. - */ -@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION) -@JsonSubTypes(JsonSubTypes.Type(ApiResult.Success::class), JsonSubTypes.Type(ApiResult.Failure::class)) -public sealed class ApiResult<out T> { - /** - * A response indicating everything is okay. - */ - public data class Success<out T>(val data: T) : ApiResult<T>() - - /** - * A response indicating a failure. - */ - public data class Failure<out T>(val message: String, val errors: List<String> = emptyList()) : ApiResult<T>() -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/AuthConfiguration.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/AuthConfiguration.kt deleted file mode 100644 index 5dbf2f59..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/AuthConfiguration.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client - -/** - * The authentication configuration for the API client. - */ -public data class AuthConfiguration( - val domain: String, - val clientId: String, - val clientSecret: String -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Job.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Job.kt deleted file mode 100644 index eeb65e49..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Job.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonProperty -import java.time.LocalDateTime - -/** - * A description of a simulation job. - */ -public data class Job( - @JsonProperty("_id") - val id: String, - val scenarioId: String, - val state: SimulationState, - val heartbeat: LocalDateTime, - val results: Map<String, Any> -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt deleted file mode 100644 index 86d2d46f..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A machine in a rack. - */ -@JsonIgnoreProperties("id_legacy") -public data class Machine( - @JsonProperty("_id") - val id: String, - val position: Int, - val cpus: List<ProcessingUnit> = emptyList(), - val gpus: List<ProcessingUnit> = emptyList(), - @JsonProperty("memories") - val memory: List<MemoryUnit> = emptyList(), - @JsonProperty("storages") - val storage: List<MemoryUnit> = emptyList(), - val rackId: String? = null -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/MemoryUnit.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/MemoryUnit.kt deleted file mode 100644 index 11e794e8..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/MemoryUnit.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A memory unit in a system. - */ -public data class MemoryUnit( - @JsonProperty("_id") - val id: String, - val name: String, - val speedMbPerS: Double, - val sizeMb: Double, - val energyConsumptionW: Double -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/OperationalPhenomena.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/OperationalPhenomena.kt deleted file mode 100644 index ef5b4902..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/OperationalPhenomena.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -/** - * Object describing the enabled operational phenomena for a scenario. - */ -public data class OperationalPhenomena( - val failuresEnabled: Boolean, - val performanceInterferenceEnabled: Boolean, - val schedulerName: String -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Portfolio.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Portfolio.kt deleted file mode 100644 index 6904920b..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Portfolio.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A portfolio in OpenDC. - */ -public data class Portfolio( - @JsonProperty("_id") - val id: String, - val projectId: String, - val name: String, - @JsonProperty("scenarioIds") - val scenarios: Set<String>, - val targets: PortfolioTargets -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/PortfolioTargets.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/PortfolioTargets.kt deleted file mode 100644 index 07c11c19..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/PortfolioTargets.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -/** - * The targets of a portfolio. - */ -public data class PortfolioTargets(val enabledMetrics: Set<String>, val repeatsPerScenario: Int) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ProcessingUnit.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ProcessingUnit.kt deleted file mode 100644 index 449b5c43..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ProcessingUnit.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A CPU model. - */ -public data class ProcessingUnit( - @JsonProperty("_id") - val id: String, - val name: String, - val clockRateMhz: Double, - val numberOfCores: Int, - val energyConsumptionW: Double -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Rack.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Rack.kt deleted file mode 100644 index a0464388..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Rack.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A rack in a datacenter. - */ -@JsonIgnoreProperties("id_legacy") -public class Rack( - @JsonProperty("_id") - val id: String, - val name: String, - val capacity: Int, - val powerCapacityW: Double, - val machines: List<Machine> -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt deleted file mode 100644 index f1b8f946..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A room in a datacenter. - */ -@JsonIgnoreProperties("id_legacy") -public data class Room( - @JsonProperty("_id") - val id: String, - val name: String, - val tiles: Set<RoomTile>, - val topologyId: String? = null, -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt deleted file mode 100644 index 0b956262..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A room tile. - */ -@JsonIgnoreProperties("id_legacy") -public data class RoomTile( - @JsonProperty("_id") - val id: String, - val positionX: Double, - val positionY: Double, - val rack: Rack? = null, - val roomId: String? = null, -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Scenario.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Scenario.kt deleted file mode 100644 index 851ff980..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Scenario.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * A simulation scenario. - */ -public data class Scenario( - @JsonProperty("_id") - val id: String, - val portfolioId: String, - val name: String, - val trace: ScenarioTrace, - val topology: ScenarioTopology, - @JsonProperty("operational") - val operationalPhenomena: OperationalPhenomena -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTopology.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTopology.kt deleted file mode 100644 index 2b90f7ef..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTopology.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -/** - * The topology details for a scenario. - */ -public data class ScenarioTopology(val topologyId: String) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTrace.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTrace.kt deleted file mode 100644 index adff6d97..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTrace.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -/** - * The trace details of a scenario. - */ -public data class ScenarioTrace(val traceId: String, val loadSamplingFraction: Double) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/SimulationState.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/SimulationState.kt deleted file mode 100644 index 2eadd747..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/SimulationState.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -/** - * The state of a simulation job. - */ -public enum class SimulationState { - QUEUED, CLAIMED, RUNNING, FINISHED, FAILED -} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Topology.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Topology.kt deleted file mode 100644 index b59aba42..00000000 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Topology.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client.model - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * Model for an OpenDC topology. - */ -@JsonIgnoreProperties("id_legacy", "datacenter_id_legacy", "datetimeLastUpdated", "datetimeLastEdited") -public data class Topology( - @JsonProperty("_id") - val id: String, - val projectId: String, - val name: String, - val rooms: Set<Room>, -) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt index 94ef8f8e..561dcd59 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt @@ -44,15 +44,15 @@ import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.compute.collectServiceMetrics import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader -import org.opendc.web.client.ApiClient -import org.opendc.web.client.AuthConfiguration -import org.opendc.web.client.model.Scenario +import org.opendc.web.client.auth.OpenIdAuthController +import org.opendc.web.client.runner.OpenDCRunnerClient +import org.opendc.web.proto.runner.Job +import org.opendc.web.proto.runner.Scenario import java.io.File import java.net.URI import java.time.Duration import java.util.* -import org.opendc.web.client.model.Portfolio as ClientPortfolio -import org.opendc.web.client.model.Topology as ClientTopology +import org.opendc.web.proto.runner.Topology as ClientTopology private val logger = KotlinLogging.logger {} @@ -134,18 +134,18 @@ class RunnerCli : CliktCommand(name = "runner") { .default(60L * 3) // Experiment may run for a maximum of three minutes /** - * Converge a single scenario. + * Run a simulation job. */ - private suspend fun runScenario(portfolio: ClientPortfolio, scenario: Scenario, topology: Topology): List<WebComputeMetricExporter.Result> { - val id = scenario.id + private suspend fun runJob(job: Job, topology: Topology): List<WebComputeMetricExporter.Result> { + val id = job.id + val scenario = job.scenario logger.info { "Constructing performance interference model" } val workloadLoader = ComputeWorkloadLoader(tracePath) val interferenceModel = let { - val path = tracePath.resolve(scenario.trace.traceId).resolve("performance-interference-model.json") - val operational = scenario.operationalPhenomena - val enabled = operational.performanceInterferenceEnabled + val path = tracePath.resolve(scenario.workload.trace.id).resolve("performance-interference-model.json") + val enabled = scenario.phenomena.interference if (!enabled || !path.exists()) { return@let null @@ -154,8 +154,7 @@ class RunnerCli : CliktCommand(name = "runner") { VmInterferenceModelReader().read(path.inputStream()) } - val targets = portfolio.targets - val results = (0 until targets.repeatsPerScenario).map { repeat -> + val results = (0 until scenario.portfolio.targets.repeats).map { repeat -> logger.info { "Starting repeat $repeat" } withTimeout(runTimeout * 1000) { runRepeat(scenario, repeat, topology, workloadLoader, interferenceModel?.withSeed(repeat.toLong())) @@ -168,7 +167,7 @@ class RunnerCli : CliktCommand(name = "runner") { } /** - * Converge a single repeat. + * Run a single repeat. */ private suspend fun runRepeat( scenario: Scenario, @@ -181,17 +180,17 @@ class RunnerCli : CliktCommand(name = "runner") { try { runBlockingSimulation { - val workloadName = scenario.trace.traceId - val workloadFraction = scenario.trace.loadSamplingFraction + val workloadName = scenario.workload.trace.id + val workloadFraction = scenario.workload.samplingFraction val seeder = Random(repeat.toLong()) - val operational = scenario.operationalPhenomena - val computeScheduler = createComputeScheduler(operational.schedulerName, seeder) + val phenomena = scenario.phenomena + val computeScheduler = createComputeScheduler(scenario.schedulerName, seeder) val workload = trace(workloadName).sampleByLoad(workloadFraction) val failureModel = - if (operational.failuresEnabled) + if (phenomena.failures) grid5000(Duration.ofDays(7)) else null @@ -203,7 +202,7 @@ class RunnerCli : CliktCommand(name = "runner") { telemetry, computeScheduler, failureModel, - interferenceModel.takeIf { operational.performanceInterferenceEnabled } + interferenceModel ) telemetry.registerMetricReader(CoroutineMetricReader(this, exporter, exportInterval = Duration.ofHours(1))) @@ -241,20 +240,19 @@ class RunnerCli : CliktCommand(name = "runner") { override fun run(): Unit = runBlocking(Dispatchers.Default) { logger.info { "Starting OpenDC web runner" } - val client = ApiClient(baseUrl = apiUrl, AuthConfiguration(authDomain, authClientId, authClientSecret), authAudience) + val client = OpenDCRunnerClient(baseUrl = apiUrl, OpenIdAuthController(authDomain, authClientId, authClientSecret, authAudience)) val manager = ScenarioManager(client) logger.info { "Watching for queued scenarios" } while (true) { - val scenario = manager.findNext() - - if (scenario == null) { + val job = manager.findNext() + if (job == null) { delay(POLL_INTERVAL) continue } - val id = scenario.id + val id = job.id logger.info { "Found queued scenario $id: attempting to claim" } @@ -273,10 +271,8 @@ class RunnerCli : CliktCommand(name = "runner") { } try { - val scenarioModel = client.getScenario(id)!! - val portfolio = client.getPortfolio(scenarioModel.portfolioId)!! - val environment = convert(client.getTopology(scenarioModel.topology.topologyId)!!) - val results = runScenario(portfolio, scenarioModel, environment) + val environment = convert(job.scenario.topology) + val results = runJob(job, environment) logger.info { "Writing results to database" } @@ -306,7 +302,8 @@ class RunnerCli : CliktCommand(name = "runner") { val machines = topology.rooms.asSequence() .flatMap { room -> room.tiles.flatMap { tile -> - tile.rack?.machines?.map { machine -> tile.rack to machine } ?: emptyList() + val rack = tile.rack + rack?.machines?.map { machine -> rack to machine } ?: emptyList() } } for ((rack, machine) in machines) { diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt index 1ee835a6..7374f0c9 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt @@ -22,64 +22,68 @@ package org.opendc.web.runner -import org.opendc.web.client.ApiClient -import org.opendc.web.client.model.Job -import org.opendc.web.client.model.SimulationState +import org.opendc.web.client.runner.OpenDCRunnerClient +import org.opendc.web.proto.JobState +import org.opendc.web.proto.runner.Job /** * Manages the queue of scenarios that need to be processed. */ -public class ScenarioManager(private val client: ApiClient) { +class ScenarioManager(private val client: OpenDCRunnerClient) { /** * Find the next job that the simulator needs to process. */ - public suspend fun findNext(): Job? { - return client.getJobs().firstOrNull() + fun findNext(): Job? { + return client.jobs.queryPending().firstOrNull() } /** * Claim the simulation job with the specified id. */ - public suspend fun claim(id: String): Boolean { - return client.updateJob(id, SimulationState.CLAIMED) + fun claim(id: Long): Boolean { + client.jobs.update(id, Job.Update(JobState.CLAIMED)) // TODO Handle conflict + return true } /** * Update the heartbeat of the specified scenario. */ - public suspend fun heartbeat(id: String) { - client.updateJob(id, SimulationState.RUNNING) + fun heartbeat(id: Long) { + client.jobs.update(id, Job.Update(JobState.RUNNING)) } /** * Mark the scenario as failed. */ - public suspend fun fail(id: String) { - client.updateJob(id, SimulationState.FAILED) + fun fail(id: Long) { + client.jobs.update(id, Job.Update(JobState.FAILED)) } /** * Persist the specified results. */ - public suspend fun finish(id: String, results: List<WebComputeMetricExporter.Result>) { - client.updateJob( - id, SimulationState.FINISHED, - mapOf( - "total_requested_burst" to results.map { it.totalActiveTime + it.totalIdleTime }, - "total_granted_burst" to results.map { it.totalActiveTime }, - "total_overcommitted_burst" to results.map { it.totalStealTime }, - "total_interfered_burst" to results.map { it.totalLostTime }, - "mean_cpu_usage" to results.map { it.meanCpuUsage }, - "mean_cpu_demand" to results.map { it.meanCpuDemand }, - "mean_num_deployed_images" to results.map { it.meanNumDeployedImages }, - "max_num_deployed_images" to results.map { it.maxNumDeployedImages }, - "total_power_draw" to results.map { it.totalPowerDraw }, - "total_failure_slices" to results.map { it.totalFailureSlices }, - "total_failure_vm_slices" to results.map { it.totalFailureVmSlices }, - "total_vms_submitted" to results.map { it.totalVmsSubmitted }, - "total_vms_queued" to results.map { it.totalVmsQueued }, - "total_vms_finished" to results.map { it.totalVmsFinished }, - "total_vms_failed" to results.map { it.totalVmsFailed } + public fun finish(id: Long, results: List<WebComputeMetricExporter.Result>) { + client.jobs.update( + id, + Job.Update( + JobState.FINISHED, + mapOf( + "total_requested_burst" to results.map { it.totalActiveTime + it.totalIdleTime }, + "total_granted_burst" to results.map { it.totalActiveTime }, + "total_overcommitted_burst" to results.map { it.totalStealTime }, + "total_interfered_burst" to results.map { it.totalLostTime }, + "mean_cpu_usage" to results.map { it.meanCpuUsage }, + "mean_cpu_demand" to results.map { it.meanCpuDemand }, + "mean_num_deployed_images" to results.map { it.meanNumDeployedImages }, + "max_num_deployed_images" to results.map { it.maxNumDeployedImages }, + "total_power_draw" to results.map { it.totalPowerDraw }, + "total_failure_slices" to results.map { it.totalFailureSlices }, + "total_failure_vm_slices" to results.map { it.totalFailureVmSlices }, + "total_vms_submitted" to results.map { it.totalVmsSubmitted }, + "total_vms_queued" to results.map { it.totalVmsQueued }, + "total_vms_finished" to results.map { it.totalVmsFinished }, + "total_vms_failed" to results.map { it.totalVmsFailed } + ) ) ) } diff --git a/opendc-web/opendc-web-runner/src/test/kotlin/org/opendc/web/client/ApiClientTest.kt b/opendc-web/opendc-web-runner/src/test/kotlin/org/opendc/web/client/ApiClientTest.kt deleted file mode 100644 index 3a0730a6..00000000 --- a/opendc-web/opendc-web-runner/src/test/kotlin/org/opendc/web/client/ApiClientTest.kt +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.client - -import io.ktor.client.* -import io.ktor.client.engine.mock.* -import io.ktor.http.* -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Assertions.assertNull -import org.junit.jupiter.api.Test -import java.net.URI - -/** - * Test suite for the [ApiClient] class. - */ -class ApiClientTest { - /** - * The Ktor [HttpClient] instance. - */ - private val ktor = HttpClient(MockEngine) { - engine { - addHandler { request -> - when (request.url.fullPath) { - "/oauth/token" -> { - val responseHeaders = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "access_token": "eyJz93a...k4laUWw", - "token_type": "Bearer", - "expires_in": 86400 - } - """.trimIndent(), - headers = responseHeaders - ) - } - "/portfolios/5fda5daa97dca438e7cb0a4c" -> { - val responseHeaders = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "data": { - "_id": "string", - "projectId": "string", - "name": "string", - "scenarioIds": [ - "string" - ], - "targets": { - "enabledMetrics": [ - "string" - ], - "repeatsPerScenario": 0 - } - } - } - """.trimIndent(), - headers = responseHeaders - ) - } - "/portfolios/x" -> { - val responseHeaders = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "message": "Not Found" - } - """.trimIndent(), - headers = responseHeaders, status = HttpStatusCode.NotFound - ) - } - "/scenarios/5fda5db297dca438e7cb0a4d" -> { - val responseHeaders = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "data": { - "_id": "string", - "portfolioId": "string", - "name": "string", - "trace": { - "traceId": "string", - "loadSamplingFraction": 0 - }, - "topology": { - "topologyId": "string" - }, - "operational": { - "failuresEnabled": true, - "performanceInterferenceEnabled": true, - "schedulerName": "string" - } - } - } - """.trimIndent(), - headers = responseHeaders - ) - } - "/scenarios/x" -> { - val responseHeaders = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "message": "Not Found" - } - """.trimIndent(), - headers = responseHeaders, status = HttpStatusCode.NotFound - ) - } - "/topologies/5f9825a6cf6e4c24e380b86f" -> { - val responseHeaders = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "data": { - "_id": "string", - "projectId": "string", - "name": "string", - "rooms": [ - { - "_id": "string", - "name": "string", - "tiles": [ - { - "_id": "string", - "positionX": 0, - "positionY": 0, - "rack": { - "_id": "string", - "name": "string", - "capacity": 0, - "powerCapacityW": 0, - "machines": [ - { - "_id": "string", - "position": 0, - "cpus": [ - { - "_id": "string", - "name": "string", - "clockRateMhz": 0, - "numberOfCores": 0 - } - ], - "gpus": [ - { - "_id": "string", - "name": "string", - "clockRateMhz": 0, - "numberOfCores": 0 - } - ], - "memories": [ - { - "_id": "string", - "name": "string", - "speedMbPerS": 0, - "sizeMb": 0 - } - ], - "storages": [ - { - "_id": "string", - "name": "string", - "speedMbPerS": 0, - "sizeMb": 0 - } - ] - } - ] - } - } - ] - } - ] - } - } - """.trimIndent(), - headers = responseHeaders - ) - } - "/topologies/x" -> { - val responseHeaders = - headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) - respond( - """ - { - "message": "Not Found" - } - """.trimIndent(), - headers = responseHeaders, status = HttpStatusCode.NotFound - ) - } - else -> error("Unhandled ${request.url}") - } - } - } - } - - private val auth = AuthConfiguration("auth.opendc.org", "a", "b") - - @Test - fun testPortfolioExists(): Unit = runBlocking { - val client = ApiClient(URI("http://localhost:8081"), auth, client = ktor) - val portfolio = client.getPortfolio("5fda5daa97dca438e7cb0a4c") - assertNotNull(portfolio) - } - - @Test - fun testPortfolioDoesNotExists(): Unit = runBlocking { - val client = ApiClient(URI("http://localhost:8081"), auth, client = ktor) - val portfolio = client.getPortfolio("x") - assertNull(portfolio) - } - - @Test - fun testScenarioExists(): Unit = runBlocking { - val client = ApiClient(URI("http://localhost:8081"), auth, client = ktor) - val scenario = client.getScenario("5fda5db297dca438e7cb0a4d") - assertNotNull(scenario) - } - - @Test - fun testScenarioDoesNotExists(): Unit = runBlocking { - val client = ApiClient(URI("http://localhost:8081"), auth, client = ktor) - val scenario = client.getScenario("x") - assertNull(scenario) - } - - @Test - fun testTopologyExists(): Unit = runBlocking { - val client = ApiClient(URI("http://localhost:8081"), auth, client = ktor) - val topology = client.getTopology("5f9825a6cf6e4c24e380b86f") - assertNotNull(topology) - } - - @Test - fun testTopologyDoesNotExists(): Unit = runBlocking { - val client = ApiClient(URI("http://localhost:8081"), auth, client = ktor) - val topology = client.getTopology("x") - assertNull(topology) - } -} |
