From d12efc754a1611a624d170b4d1fa6085e6bb177b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 7 Mar 2022 17:58:08 +0100 Subject: 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. --- opendc-web/opendc-web-runner/build.gradle.kts | 7 +- .../main/kotlin/org/opendc/web/client/ApiClient.kt | 179 -------------- .../main/kotlin/org/opendc/web/client/ApiResult.kt | 43 ---- .../org/opendc/web/client/AuthConfiguration.kt | 32 --- .../main/kotlin/org/opendc/web/client/model/Job.kt | 38 --- .../kotlin/org/opendc/web/client/model/Machine.kt | 43 ---- .../org/opendc/web/client/model/MemoryUnit.kt | 37 --- .../web/client/model/OperationalPhenomena.kt | 32 --- .../org/opendc/web/client/model/Portfolio.kt | 38 --- .../opendc/web/client/model/PortfolioTargets.kt | 28 --- .../org/opendc/web/client/model/ProcessingUnit.kt | 37 --- .../kotlin/org/opendc/web/client/model/Rack.kt | 39 --- .../kotlin/org/opendc/web/client/model/Room.kt | 38 --- .../kotlin/org/opendc/web/client/model/RoomTile.kt | 39 --- .../kotlin/org/opendc/web/client/model/Scenario.kt | 39 --- .../opendc/web/client/model/ScenarioTopology.kt | 28 --- .../org/opendc/web/client/model/ScenarioTrace.kt | 28 --- .../org/opendc/web/client/model/SimulationState.kt | 30 --- .../kotlin/org/opendc/web/client/model/Topology.kt | 38 --- .../src/main/kotlin/org/opendc/web/runner/Main.kt | 57 +++-- .../org/opendc/web/runner/ScenarioManager.kt | 66 +++--- .../kotlin/org/opendc/web/client/ApiClientTest.kt | 264 --------------------- 22 files changed, 63 insertions(+), 1117 deletions(-) delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiClient.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiResult.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/AuthConfiguration.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Job.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/MemoryUnit.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/OperationalPhenomena.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Portfolio.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/PortfolioTargets.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ProcessingUnit.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Rack.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Scenario.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTopology.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTrace.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/SimulationState.kt delete mode 100644 opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Topology.kt delete mode 100644 opendc-web/opendc-web-runner/src/test/kotlin/org/opendc/web/client/ApiClientTest.kt (limited to 'opendc-web') 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>(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>(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>(url)) { - is ApiResult.Success -> result.data - else -> null - } - } - - /** - * Retrieve the available jobs. - */ - public suspend fun getJobs(): List { - val url = URLBuilder(Url(baseUrl)) - .path("jobs") - .build() - return when (val result = client.get>>(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 = emptyMap()): Boolean { - val url = URLBuilder(Url(baseUrl)) - .path("jobs", id) - .build() - - data class Request( - val state: SimulationState, - val results: Map - ) - - val res = client.post { - 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 { - 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 { - /** - * A response indicating everything is okay. - */ - public data class Success(val data: T) : ApiResult() - - /** - * A response indicating a failure. - */ - public data class Failure(val message: String, val errors: List = emptyList()) : ApiResult() -} 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 -) 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 = emptyList(), - val gpus: List = emptyList(), - @JsonProperty("memories") - val memory: List = emptyList(), - @JsonProperty("storages") - val storage: List = 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, - 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, 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 -) 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, - 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, -) 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 { - val id = scenario.id + private suspend fun runJob(job: Job, topology: Topology): List { + 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) { - 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) { + 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) - } -} -- cgit v1.2.3