summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-runner/src
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2022-04-04 17:00:31 +0200
committerGitHub <noreply@github.com>2022-04-04 17:00:31 +0200
commit38769373c7e89783d33849283586bfa0b62e8251 (patch)
tree4fda128ee6b30018c1aa14c584cc53ade80e67f7 /opendc-web/opendc-web-runner/src
parent6021aa4278bebb34bf5603ead4b5daeabcdc4c19 (diff)
parent527ae2230f5c2dd22f496f45d5d8e3bd4acdb854 (diff)
merge: Migrate to Quarkus-based web API
This pull request changes the web API to a Quarkus-based version. Currently, the OpenDC web API is written in Python (using Flask). Although Python is a powerful language to develop web services, having another language next to Kotlin/Java and JavaScript introduces some challenges. For instance, the web API and UI lack integration with our Gradle-based build pipeline and require additional steps from the developer to start working with. Furthermore, deploying OpenDC requires having Python installed in addition to the JVM. By converting the web API into a Quarkus application, we can enjoy further integration with our Gradle-based build pipeline and simplify the development/deployment process of OpenDC, by requiring only the JVM and Node to work with OpenDC. ## Implementation Notes :hammer_and_pick: * Move build dependencies into version catalog * Design unified communication protocol * Add Quarkus API implementation * Add new web client implementation * Update runner to use new web client * Fix compatibility with React.js UI * Remove Python build steps from CI pipeline * Update Docker deployment for new web API * Remove obsolete database configuration ## External Dependencies :four_leaf_clover: * Quarkus ## Breaking API Changes :warning: * The new web API only supports SQL-based databases for storing user-data, as opposed to MongoDB currently. We intend to use H2 for development and Postgres for production.
Diffstat (limited to 'opendc-web/opendc-web-runner/src')
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiClient.kt179
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/ApiResult.kt43
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/AuthConfiguration.kt32
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Job.kt38
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Machine.kt43
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/MemoryUnit.kt37
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/OperationalPhenomena.kt32
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Portfolio.kt38
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/PortfolioTargets.kt28
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ProcessingUnit.kt37
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Rack.kt39
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Room.kt38
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/RoomTile.kt39
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Scenario.kt39
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTopology.kt28
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/ScenarioTrace.kt28
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/SimulationState.kt30
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/client/model/Topology.kt38
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/Main.kt57
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/ScenarioManager.kt66
-rw-r--r--opendc-web/opendc-web-runner/src/test/kotlin/org/opendc/web/client/ApiClientTest.kt264
21 files changed, 62 insertions, 1111 deletions
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)
- }
-}