summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-api/src
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2022-07-30 12:15:10 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2022-08-03 11:54:44 +0200
commita01f964b531f12fd89cbdb0f2132aecbfaebf546 (patch)
tree4a2c3795d3d1ae394e9ab785b9229ab6e14ccbdf /opendc-web/opendc-web-api/src
parent41b0ed59421b301bac652e47d1a2909145aa5936 (diff)
refactor(web/server): Create standalone OpenDC distribution
This change updates the Quarkus configuration of the OpenDC web server to serve as a fully standalone distribution that is capable of serving the web UI, web API, and experiment runner. Such an approach vastly simplifies local deployments. For Docker deployments, we create a custom Quarkus profile that uses PostgreSQL and disables the web UI.
Diffstat (limited to 'opendc-web/opendc-web-api/src')
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/OpenDCApplication.kt30
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Job.kt95
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Portfolio.kt89
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Project.kt134
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorization.kt58
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorizationKey.kt38
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Scenario.kt107
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Topology.kt92
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Trace.kt58
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Workload.kt39
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/JobRepository.kt93
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/PortfolioRepository.kt76
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ProjectRepository.kt157
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ScenarioRepository.kt90
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TopologyRepository.kt86
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TraceRepository.kt53
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/SchedulerResource.kt48
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/TraceResource.kt51
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/GenericExceptionMapper.kt45
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/MissingKotlinParameterExceptionMapper.kt43
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/runner/JobResource.kt72
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioResource.kt77
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResource.kt59
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ProjectResource.kt82
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ScenarioResource.kt60
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/TopologyResource.kt88
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/JobService.kt81
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/PortfolioService.kt104
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ProjectService.kt86
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/RunnerConversions.kt69
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ScenarioService.kt128
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TopologyService.kt127
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TraceService.kt48
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/UserConversions.kt120
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/Utils.kt40
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/DevSecurityOverrideFilter.kt51
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/KotlinModuleCustomizer.kt38
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/AbstractJsonSqlTypeDescriptor.kt74
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBinarySqlTypeDescriptor.kt26
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBytesSqlTypeDescriptor.kt83
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonSqlTypeDescriptor.kt107
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonStringSqlTypeDescriptor.kt38
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonType.kt48
-rw-r--r--opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonTypeDescriptor.kt149
-rw-r--r--opendc-web/opendc-web-api/src/main/resources/META-INF/branding/logo.pngbin2825 -> 0 bytes
-rw-r--r--opendc-web/opendc-web-api/src/main/resources/application-dev.properties40
-rw-r--r--opendc-web/opendc-web-api/src/main/resources/application-prod.properties33
-rw-r--r--opendc-web/opendc-web-api/src/main/resources/application-test.properties40
-rw-r--r--opendc-web/opendc-web-api/src/main/resources/application.properties53
-rw-r--r--opendc-web/opendc-web-api/src/main/resources/init-dev.sql3
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/SchedulerResourceTest.kt48
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/TraceResourceTest.kt100
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/runner/JobResourceTest.kt200
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioResourceTest.kt265
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResourceTest.kt213
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ProjectResourceTest.kt240
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ScenarioResourceTest.kt178
-rw-r--r--opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/TopologyResourceTest.kt304
58 files changed, 0 insertions, 5054 deletions
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/OpenDCApplication.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/OpenDCApplication.kt
deleted file mode 100644
index ddbd5390..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/OpenDCApplication.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.api
-
-import javax.ws.rs.core.Application
-
-/**
- * [Application] definition for the OpenDC web API.
- */
-class OpenDCApplication : Application()
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Job.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Job.kt
deleted file mode 100644
index b09b46a1..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Job.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import org.hibernate.annotations.Type
-import org.hibernate.annotations.TypeDef
-import org.opendc.web.api.util.hibernate.json.JsonType
-import org.opendc.web.proto.JobState
-import java.time.Instant
-import javax.persistence.*
-
-/**
- * A simulation job to be run by the simulator.
- */
-@TypeDef(name = "json", typeClass = JsonType::class)
-@Entity
-@Table(name = "jobs")
-@NamedQueries(
- value = [
- NamedQuery(
- name = "Job.findAll",
- query = "SELECT j FROM Job j WHERE j.state = :state"
- ),
- NamedQuery(
- name = "Job.updateOne",
- query = """
- UPDATE Job j
- SET j.state = :newState, j.updatedAt = :updatedAt, j.results = :results
- WHERE j.id = :id AND j.state = :oldState
- """
- )
- ]
-)
-class Job(
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- val id: Long,
-
- @OneToOne(optional = false, mappedBy = "job", fetch = FetchType.EAGER)
- @JoinColumn(name = "scenario_id", nullable = false)
- val scenario: Scenario,
-
- @Column(name = "created_at", nullable = false, updatable = false)
- val createdAt: Instant,
-
- /**
- * The number of simulation runs to perform.
- */
- @Column(nullable = false, updatable = false)
- val repeats: Int
-) {
- /**
- * The instant at which the job was updated.
- */
- @Column(name = "updated_at", nullable = false)
- var updatedAt: Instant = createdAt
-
- /**
- * The state of the job.
- */
- @Column(nullable = false)
- var state: JobState = JobState.PENDING
-
- /**
- * Experiment results in JSON
- */
- @Type(type = "json")
- @Column(columnDefinition = "jsonb")
- var results: Map<String, Any>? = null
-
- /**
- * Return a string representation of this job.
- */
- override fun toString(): String = "Job[id=$id,scenario=${scenario.id},state=$state]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Portfolio.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Portfolio.kt
deleted file mode 100644
index c8b94daf..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Portfolio.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import org.hibernate.annotations.Type
-import org.hibernate.annotations.TypeDef
-import org.opendc.web.api.util.hibernate.json.JsonType
-import org.opendc.web.proto.Targets
-import javax.persistence.*
-
-/**
- * A portfolio is the composition of multiple scenarios.
- */
-@TypeDef(name = "json", typeClass = JsonType::class)
-@Entity
-@Table(
- name = "portfolios",
- uniqueConstraints = [UniqueConstraint(columnNames = ["project_id", "number"])],
- indexes = [Index(name = "fn_portfolios_number", columnList = "project_id, number")]
-)
-@NamedQueries(
- value = [
- NamedQuery(
- name = "Portfolio.findAll",
- query = "SELECT p FROM Portfolio p WHERE p.project.id = :projectId"
- ),
- NamedQuery(
- name = "Portfolio.findOne",
- query = "SELECT p FROM Portfolio p WHERE p.project.id = :projectId AND p.number = :number"
- )
- ]
-)
-class Portfolio(
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- val id: Long,
-
- /**
- * Unique number of the portfolio for the project.
- */
- @Column(nullable = false)
- val number: Int,
-
- @Column(nullable = false)
- val name: String,
-
- @ManyToOne(optional = false)
- @JoinColumn(name = "project_id", nullable = false)
- val project: Project,
-
- /**
- * The portfolio targets (metrics, repetitions).
- */
- @Type(type = "json")
- @Column(columnDefinition = "jsonb", nullable = false, updatable = false)
- val targets: Targets,
-) {
- /**
- * The scenarios in this portfolio.
- */
- @OneToMany(cascade = [CascadeType.ALL], mappedBy = "portfolio", orphanRemoval = true)
- @OrderBy("id ASC")
- val scenarios: MutableSet<Scenario> = mutableSetOf()
-
- /**
- * Return a string representation of this portfolio.
- */
- override fun toString(): String = "Job[id=$id,name=$name,project=${project.id},targets=$targets]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Project.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Project.kt
deleted file mode 100644
index e0440bf4..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Project.kt
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import java.time.Instant
-import javax.persistence.*
-
-/**
- * A project in OpenDC encapsulates all the datacenter designs and simulation runs for a set of users.
- */
-@Entity
-@Table(name = "projects")
-@NamedQueries(
- value = [
- NamedQuery(
- name = "Project.findAll",
- query = """
- SELECT a
- FROM ProjectAuthorization a
- WHERE a.key.userId = :userId
- """
- ),
- NamedQuery(
- name = "Project.allocatePortfolio",
- query = """
- UPDATE Project p
- SET p.portfoliosCreated = :oldState + 1, p.updatedAt = :now
- WHERE p.id = :id AND p.portfoliosCreated = :oldState
- """
- ),
- NamedQuery(
- name = "Project.allocateTopology",
- query = """
- UPDATE Project p
- SET p.topologiesCreated = :oldState + 1, p.updatedAt = :now
- WHERE p.id = :id AND p.topologiesCreated = :oldState
- """
- ),
- NamedQuery(
- name = "Project.allocateScenario",
- query = """
- UPDATE Project p
- SET p.scenariosCreated = :oldState + 1, p.updatedAt = :now
- WHERE p.id = :id AND p.scenariosCreated = :oldState
- """
- )
- ]
-)
-class Project(
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- val id: Long,
-
- @Column(nullable = false)
- var name: String,
-
- @Column(name = "created_at", nullable = false, updatable = false)
- val createdAt: Instant,
-) {
- /**
- * The instant at which the project was updated.
- */
- @Column(name = "updated_at", nullable = false)
- var updatedAt: Instant = createdAt
-
- /**
- * The portfolios belonging to this project.
- */
- @OneToMany(cascade = [CascadeType.ALL], mappedBy = "project", orphanRemoval = true)
- @OrderBy("id ASC")
- val portfolios: MutableSet<Portfolio> = mutableSetOf()
-
- /**
- * The number of portfolios created for this project (including deleted portfolios).
- */
- @Column(name = "portfolios_created", nullable = false)
- var portfoliosCreated: Int = 0
-
- /**
- * The topologies belonging to this project.
- */
- @OneToMany(cascade = [CascadeType.ALL], mappedBy = "project", orphanRemoval = true)
- @OrderBy("id ASC")
- val topologies: MutableSet<Topology> = mutableSetOf()
-
- /**
- * The number of topologies created for this project (including deleted topologies).
- */
- @Column(name = "topologies_created", nullable = false)
- var topologiesCreated: Int = 0
-
- /**
- * The scenarios belonging to this project.
- */
- @OneToMany(mappedBy = "project", orphanRemoval = true)
- val scenarios: MutableSet<Scenario> = mutableSetOf()
-
- /**
- * The number of scenarios created for this project (including deleted scenarios).
- */
- @Column(name = "scenarios_created", nullable = false)
- var scenariosCreated: Int = 0
-
- /**
- * The users authorized to access the project.
- */
- @OneToMany(cascade = [CascadeType.ALL], mappedBy = "project", orphanRemoval = true)
- val authorizations: MutableSet<ProjectAuthorization> = mutableSetOf()
-
- /**
- * Return a string representation of this project.
- */
- override fun toString(): String = "Project[id=$id,name=$name]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorization.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorization.kt
deleted file mode 100644
index a72ff06a..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorization.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import org.opendc.web.proto.user.ProjectRole
-import javax.persistence.*
-
-/**
- * An authorization for some user to participate in a project.
- */
-@Entity
-@Table(name = "project_authorizations")
-class ProjectAuthorization(
- /**
- * The user identifier of the authorization.
- */
- @EmbeddedId
- val key: ProjectAuthorizationKey,
-
- /**
- * The project that the user is authorized to participate in.
- */
- @ManyToOne(optional = false)
- @MapsId("projectId")
- @JoinColumn(name = "project_id", updatable = false, insertable = false, nullable = false)
- val project: Project,
-
- /**
- * The role of the user in the project.
- */
- @Column(nullable = false)
- val role: ProjectRole
-) {
- /**
- * Return a string representation of this project authorization.
- */
- override fun toString(): String = "ProjectAuthorization[project=${key.projectId},user=${key.userId},role=$role]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorizationKey.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorizationKey.kt
deleted file mode 100644
index b5f66e70..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/ProjectAuthorizationKey.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import javax.persistence.Column
-import javax.persistence.Embeddable
-
-/**
- * Key for representing a [ProjectAuthorization] object.
- */
-@Embeddable
-data class ProjectAuthorizationKey(
- @Column(name = "user_id", nullable = false)
- val userId: String,
-
- @Column(name = "project_id", nullable = false)
- val projectId: Long
-) : java.io.Serializable
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Scenario.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Scenario.kt
deleted file mode 100644
index 5c9cb259..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Scenario.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import org.hibernate.annotations.Type
-import org.hibernate.annotations.TypeDef
-import org.opendc.web.api.util.hibernate.json.JsonType
-import org.opendc.web.proto.OperationalPhenomena
-import javax.persistence.*
-
-/**
- * A single scenario to be explored by the simulator.
- */
-@TypeDef(name = "json", typeClass = JsonType::class)
-@Entity
-@Table(
- name = "scenarios",
- uniqueConstraints = [UniqueConstraint(columnNames = ["project_id", "number"])],
- indexes = [Index(name = "fn_scenarios_number", columnList = "project_id, number")]
-)
-@NamedQueries(
- value = [
- NamedQuery(
- name = "Scenario.findAll",
- query = "SELECT s FROM Scenario s WHERE s.project.id = :projectId"
- ),
- NamedQuery(
- name = "Scenario.findAllForPortfolio",
- query = """
- SELECT s
- FROM Scenario s
- JOIN Portfolio p ON p.id = s.portfolio.id AND p.number = :number
- WHERE s.project.id = :projectId
- """
- ),
- NamedQuery(
- name = "Scenario.findOne",
- query = "SELECT s FROM Scenario s WHERE s.project.id = :projectId AND s.number = :number"
- )
- ]
-)
-class Scenario(
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- val id: Long,
-
- /**
- * Unique number of the scenario for the project.
- */
- @Column(nullable = false)
- val number: Int,
-
- @Column(nullable = false, updatable = false)
- val name: String,
-
- @ManyToOne(optional = false)
- @JoinColumn(name = "project_id", nullable = false)
- val project: Project,
-
- @ManyToOne(optional = false)
- @JoinColumn(name = "portfolio_id", nullable = false)
- val portfolio: Portfolio,
-
- @Embedded
- val workload: Workload,
-
- @ManyToOne(optional = false)
- val topology: Topology,
-
- @Type(type = "json")
- @Column(columnDefinition = "jsonb", nullable = false, updatable = false)
- val phenomena: OperationalPhenomena,
-
- @Column(name = "scheduler_name", nullable = false, updatable = false)
- val schedulerName: String,
-) {
- /**
- * The [Job] associated with the scenario.
- */
- @OneToOne(cascade = [CascadeType.ALL])
- lateinit var job: Job
-
- /**
- * Return a string representation of this scenario.
- */
- override fun toString(): String = "Scenario[id=$id,name=$name,project=${project.id},portfolio=${portfolio.id}]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Topology.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Topology.kt
deleted file mode 100644
index 9b64e382..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Topology.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import org.hibernate.annotations.Type
-import org.hibernate.annotations.TypeDef
-import org.opendc.web.api.util.hibernate.json.JsonType
-import org.opendc.web.proto.Room
-import java.time.Instant
-import javax.persistence.*
-
-/**
- * A datacenter design in OpenDC.
- */
-@TypeDef(name = "json", typeClass = JsonType::class)
-@Entity
-@Table(
- name = "topologies",
- uniqueConstraints = [UniqueConstraint(columnNames = ["project_id", "number"])],
- indexes = [Index(name = "fn_topologies_number", columnList = "project_id, number")]
-)
-@NamedQueries(
- value = [
- NamedQuery(
- name = "Topology.findAll",
- query = "SELECT t FROM Topology t WHERE t.project.id = :projectId"
- ),
- NamedQuery(
- name = "Topology.findOne",
- query = "SELECT t FROM Topology t WHERE t.project.id = :projectId AND t.number = :number"
- )
- ]
-)
-class Topology(
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- val id: Long,
-
- /**
- * Unique number of the topology for the project.
- */
- @Column(nullable = false)
- val number: Int,
-
- @Column(nullable = false)
- val name: String,
-
- @ManyToOne(optional = false)
- @JoinColumn(name = "project_id", nullable = false)
- val project: Project,
-
- @Column(name = "created_at", nullable = false, updatable = false)
- val createdAt: Instant,
-
- /**
- * Datacenter design in JSON
- */
- @Type(type = "json")
- @Column(columnDefinition = "jsonb", nullable = false)
- var rooms: List<Room> = emptyList()
-) {
- /**
- * The instant at which the topology was updated.
- */
- @Column(name = "updated_at", nullable = false)
- var updatedAt: Instant = createdAt
-
- /**
- * Return a string representation of this topology.
- */
- override fun toString(): String = "Topology[id=$id,name=$name,project=${project.id}]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Trace.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Trace.kt
deleted file mode 100644
index 2e2d71f8..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Trace.kt
+++ /dev/null
@@ -1,58 +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.api.model
-
-import javax.persistence.*
-
-/**
- * A workload trace available for simulation.
- *
- * @param id The unique identifier of the trace.
- * @param name The name of the trace.
- * @param type The type of trace.
- */
-@Entity
-@Table(name = "traces")
-@NamedQueries(
- value = [
- NamedQuery(
- name = "Trace.findAll",
- query = "SELECT t FROM Trace t"
- ),
- ]
-)
-class Trace(
- @Id
- val id: String,
-
- @Column(nullable = false, updatable = false)
- val name: String,
-
- @Column(nullable = false, updatable = false)
- val type: String,
-) {
- /**
- * Return a string representation of this trace.
- */
- override fun toString(): String = "Trace[id=$id,name=$name,type=$type]"
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Workload.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Workload.kt
deleted file mode 100644
index 07fc096b..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/model/Workload.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.model
-
-import javax.persistence.Column
-import javax.persistence.Embeddable
-import javax.persistence.ManyToOne
-
-/**
- * Specification of the workload for a [Scenario].
- */
-@Embeddable
-class Workload(
- @ManyToOne(optional = false)
- val trace: Trace,
-
- @Column(name = "sampling_fraction", nullable = false, updatable = false)
- val samplingFraction: Double
-)
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/JobRepository.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/JobRepository.kt
deleted file mode 100644
index 558d7c38..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/JobRepository.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.repository
-
-import org.opendc.web.api.model.Job
-import org.opendc.web.proto.JobState
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import javax.persistence.EntityManager
-
-/**
- * A repository to manage [Job] entities.
- */
-@ApplicationScoped
-class JobRepository @Inject constructor(private val em: EntityManager) {
- /**
- * Find all jobs currently residing in [state].
- *
- * @param state The state in which the jobs should be.
- * @return The list of jobs in state [state].
- */
- fun findAll(state: JobState): List<Job> {
- return em.createNamedQuery("Job.findAll", Job::class.java)
- .setParameter("state", state)
- .resultList
- }
-
- /**
- * Find the [Job] with the specified [id].
- *
- * @param id The unique identifier of the job.
- * @return The trace or `null` if it does not exist.
- */
- fun findOne(id: Long): Job? {
- return em.find(Job::class.java, id)
- }
-
- /**
- * Delete the specified [job].
- */
- fun delete(job: Job) {
- em.remove(job)
- }
-
- /**
- * Save the specified [job] to the database.
- */
- fun save(job: Job) {
- em.persist(job)
- }
-
- /**
- * Atomically update the specified [job].
- *
- * @param job The job to update atomically.
- * @param newState The new state to enter into.
- * @param time The time at which the update occurs.
- * @param results The results to possible set.
- * @return `true` when the update succeeded`, `false` when there was a conflict.
- */
- fun updateOne(job: Job, newState: JobState, time: Instant, results: Map<String, Any>?): Boolean {
- val count = em.createNamedQuery("Job.updateOne")
- .setParameter("id", job.id)
- .setParameter("oldState", job.state)
- .setParameter("newState", newState)
- .setParameter("updatedAt", Instant.now())
- .setParameter("results", results)
- .executeUpdate()
- em.refresh(job)
- return count > 0
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/PortfolioRepository.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/PortfolioRepository.kt
deleted file mode 100644
index 34b3598c..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/PortfolioRepository.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.repository
-
-import org.opendc.web.api.model.Portfolio
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import javax.persistence.EntityManager
-
-/**
- * A repository to manage [Portfolio] entities.
- */
-@ApplicationScoped
-class PortfolioRepository @Inject constructor(private val em: EntityManager) {
- /**
- * Find all [Portfolio]s that belong to [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @return The list of portfolios that belong to the specified project.
- */
- fun findAll(projectId: Long): List<Portfolio> {
- return em.createNamedQuery("Portfolio.findAll", Portfolio::class.java)
- .setParameter("projectId", projectId)
- .resultList
- }
-
- /**
- * Find the [Portfolio] with the specified [number] belonging to [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @param number The number of the portfolio.
- * @return The portfolio or `null` if it does not exist.
- */
- fun findOne(projectId: Long, number: Int): Portfolio? {
- return em.createNamedQuery("Portfolio.findOne", Portfolio::class.java)
- .setParameter("projectId", projectId)
- .setParameter("number", number)
- .setMaxResults(1)
- .resultList
- .firstOrNull()
- }
-
- /**
- * Delete the specified [portfolio].
- */
- fun delete(portfolio: Portfolio) {
- em.remove(portfolio)
- }
-
- /**
- * Save the specified [portfolio] to the database.
- */
- fun save(portfolio: Portfolio) {
- em.persist(portfolio)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ProjectRepository.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ProjectRepository.kt
deleted file mode 100644
index 6529f778..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ProjectRepository.kt
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.repository
-
-import org.opendc.web.api.model.Project
-import org.opendc.web.api.model.ProjectAuthorization
-import org.opendc.web.api.model.ProjectAuthorizationKey
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import javax.persistence.EntityManager
-
-/**
- * A repository to manage [Project] entities.
- */
-@ApplicationScoped
-class ProjectRepository @Inject constructor(private val em: EntityManager) {
- /**
- * List all projects for the user with the specified [userId].
- *
- * @param userId The identifier of the user that is requesting the list of projects.
- * @return A list of projects that the user has received authorization for.
- */
- fun findAll(userId: String): List<ProjectAuthorization> {
- return em.createNamedQuery("Project.findAll", ProjectAuthorization::class.java)
- .setParameter("userId", userId)
- .resultList
- }
-
- /**
- * Find the project with [id] for the user with the specified [userId].
- *
- * @param userId The identifier of the user that is requesting the list of projects.
- * @param id The unique identifier of the project.
- * @return The project with the specified identifier or `null` if it does not exist or is not accessible to the
- * user with the specified identifier.
- */
- fun findOne(userId: String, id: Long): ProjectAuthorization? {
- return em.find(ProjectAuthorization::class.java, ProjectAuthorizationKey(userId, id))
- }
-
- /**
- * Delete the specified [project].
- */
- fun delete(project: Project) {
- em.remove(project)
- }
-
- /**
- * Save the specified [project] to the database.
- */
- fun save(project: Project) {
- em.persist(project)
- }
-
- /**
- * Save the specified [auth] to the database.
- */
- fun save(auth: ProjectAuthorization) {
- em.persist(auth)
- }
-
- /**
- * Allocate the next portfolio number for the specified [project].
- *
- * @param project The project to allocate the portfolio number for.
- * @param time The time at which the new portfolio is created.
- * @param tries The number of times to try to allocate the number before failing.
- */
- fun allocatePortfolio(project: Project, time: Instant, tries: Int = 4): Int {
- repeat(tries) {
- val count = em.createNamedQuery("Project.allocatePortfolio")
- .setParameter("id", project.id)
- .setParameter("oldState", project.portfoliosCreated)
- .setParameter("now", time)
- .executeUpdate()
-
- if (count > 0) {
- return project.portfoliosCreated + 1
- } else {
- em.refresh(project)
- }
- }
-
- throw IllegalStateException("Failed to allocate next portfolio")
- }
-
- /**
- * Allocate the next topology number for the specified [project].
- *
- * @param project The project to allocate the topology number for.
- * @param time The time at which the new topology is created.
- * @param tries The number of times to try to allocate the number before failing.
- */
- fun allocateTopology(project: Project, time: Instant, tries: Int = 4): Int {
- repeat(tries) {
- val count = em.createNamedQuery("Project.allocateTopology")
- .setParameter("id", project.id)
- .setParameter("oldState", project.topologiesCreated)
- .setParameter("now", time)
- .executeUpdate()
-
- if (count > 0) {
- return project.topologiesCreated + 1
- } else {
- em.refresh(project)
- }
- }
-
- throw IllegalStateException("Failed to allocate next topology")
- }
-
- /**
- * Allocate the next scenario number for the specified [project].
- *
- * @param project The project to allocate the scenario number for.
- * @param time The time at which the new scenario is created.
- * @param tries The number of times to try to allocate the number before failing.
- */
- fun allocateScenario(project: Project, time: Instant, tries: Int = 4): Int {
- repeat(tries) {
- val count = em.createNamedQuery("Project.allocateScenario")
- .setParameter("id", project.id)
- .setParameter("oldState", project.scenariosCreated)
- .setParameter("now", time)
- .executeUpdate()
-
- if (count > 0) {
- return project.scenariosCreated + 1
- } else {
- em.refresh(project)
- }
- }
-
- throw IllegalStateException("Failed to allocate next scenario")
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ScenarioRepository.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ScenarioRepository.kt
deleted file mode 100644
index de116ad6..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/ScenarioRepository.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.repository
-
-import org.opendc.web.api.model.Scenario
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import javax.persistence.EntityManager
-
-/**
- * A repository to manage [Scenario] entities.
- */
-@ApplicationScoped
-class ScenarioRepository @Inject constructor(private val em: EntityManager) {
- /**
- * Find all [Scenario]s that belong to [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @return The list of scenarios that belong to the specified project.
- */
- fun findAll(projectId: Long): List<Scenario> {
- return em.createNamedQuery("Scenario.findAll", Scenario::class.java)
- .setParameter("projectId", projectId)
- .resultList
- }
-
- /**
- * Find all [Scenario]s that belong to [portfolio][number] of [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @param number The number of the portfolio to which the scenarios should belong.
- * @return The list of scenarios that belong to the specified portfolio.
- */
- fun findAll(projectId: Long, number: Int): List<Scenario> {
- return em.createNamedQuery("Scenario.findAllForPortfolio", Scenario::class.java)
- .setParameter("projectId", projectId)
- .setParameter("number", number)
- .resultList
- }
-
- /**
- * Find the [Scenario] with the specified [number] belonging to [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @param number The number of the scenario.
- * @return The scenario or `null` if it does not exist.
- */
- fun findOne(projectId: Long, number: Int): Scenario? {
- return em.createNamedQuery("Scenario.findOne", Scenario::class.java)
- .setParameter("projectId", projectId)
- .setParameter("number", number)
- .setMaxResults(1)
- .resultList
- .firstOrNull()
- }
-
- /**
- * Delete the specified [scenario].
- */
- fun delete(scenario: Scenario) {
- em.remove(scenario)
- }
-
- /**
- * Save the specified [scenario] to the database.
- */
- fun save(scenario: Scenario) {
- em.persist(scenario)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TopologyRepository.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TopologyRepository.kt
deleted file mode 100644
index cd8f666e..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TopologyRepository.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.repository
-
-import org.opendc.web.api.model.Topology
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import javax.persistence.EntityManager
-
-/**
- * A repository to manage [Topology] entities.
- */
-@ApplicationScoped
-class TopologyRepository @Inject constructor(private val em: EntityManager) {
- /**
- * Find all [Topology]s that belong to [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @return The list of topologies that belong to the specified project.
- */
- fun findAll(projectId: Long): List<Topology> {
- return em.createNamedQuery("Topology.findAll", Topology::class.java)
- .setParameter("projectId", projectId)
- .resultList
- }
-
- /**
- * Find the [Topology] with the specified [number] belonging to [project][projectId].
- *
- * @param projectId The unique identifier of the project.
- * @param number The number of the topology.
- * @return The topology or `null` if it does not exist.
- */
- fun findOne(projectId: Long, number: Int): Topology? {
- return em.createNamedQuery("Topology.findOne", Topology::class.java)
- .setParameter("projectId", projectId)
- .setParameter("number", number)
- .setMaxResults(1)
- .resultList
- .firstOrNull()
- }
-
- /**
- * Find the [Topology] with the specified [id].
- *
- * @param id Unique identifier of the topology.
- * @return The topology or `null` if it does not exist.
- */
- fun findOne(id: Long): Topology? {
- return em.find(Topology::class.java, id)
- }
-
- /**
- * Delete the specified [topology].
- */
- fun delete(topology: Topology) {
- em.remove(topology)
- }
-
- /**
- * Save the specified [topology] to the database.
- */
- fun save(topology: Topology) {
- em.persist(topology)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TraceRepository.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TraceRepository.kt
deleted file mode 100644
index 6652fc80..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/repository/TraceRepository.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.repository
-
-import org.opendc.web.api.model.Trace
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import javax.persistence.EntityManager
-
-/**
- * A repository to manage [Trace] entities.
- */
-@ApplicationScoped
-class TraceRepository @Inject constructor(private val em: EntityManager) {
- /**
- * Find all workload traces in the database.
- *
- * @return The list of available workload traces.
- */
- fun findAll(): List<Trace> {
- return em.createNamedQuery("Trace.findAll", Trace::class.java).resultList
- }
-
- /**
- * Find the [Trace] with the specified [id].
- *
- * @param id The unique identifier of the trace.
- * @return The trace or `null` if it does not exist.
- */
- fun findOne(id: String): Trace? {
- return em.find(Trace::class.java, id)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/SchedulerResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/SchedulerResource.kt
deleted file mode 100644
index 735fdd9b..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/SchedulerResource.kt
+++ /dev/null
@@ -1,48 +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.api.rest
-
-import javax.ws.rs.GET
-import javax.ws.rs.Path
-
-/**
- * A resource representing the available schedulers that can be used during experiments.
- */
-@Path("/schedulers")
-class SchedulerResource {
- /**
- * Obtain all available schedulers.
- */
- @GET
- fun getAll() = listOf(
- "mem",
- "mem-inv",
- "core-mem",
- "core-mem-inv",
- "active-servers",
- "active-servers-inv",
- "provisioned-cores",
- "provisioned-cores-inv",
- "random"
- )
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/TraceResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/TraceResource.kt
deleted file mode 100644
index e87fe602..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/TraceResource.kt
+++ /dev/null
@@ -1,51 +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.api.rest
-
-import org.opendc.web.api.service.TraceService
-import org.opendc.web.proto.Trace
-import javax.inject.Inject
-import javax.ws.rs.*
-
-/**
- * A resource representing the workload traces available in the OpenDC instance.
- */
-@Path("/traces")
-class TraceResource @Inject constructor(private val traceService: TraceService) {
- /**
- * Obtain all available traces.
- */
- @GET
- fun getAll(): List<Trace> {
- return traceService.findAll()
- }
-
- /**
- * Obtain trace information by identifier.
- */
- @GET
- @Path("{id}")
- fun get(@PathParam("id") id: String): Trace {
- return traceService.findById(id) ?: throw WebApplicationException("Trace not found", 404)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/GenericExceptionMapper.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/GenericExceptionMapper.kt
deleted file mode 100644
index fb253758..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/GenericExceptionMapper.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.error
-
-import org.opendc.web.proto.ProtocolError
-import javax.ws.rs.WebApplicationException
-import javax.ws.rs.core.MediaType
-import javax.ws.rs.core.Response
-import javax.ws.rs.ext.ExceptionMapper
-import javax.ws.rs.ext.Provider
-
-/**
- * Helper class to transform an exception into an JSON error response.
- */
-@Provider
-class GenericExceptionMapper : ExceptionMapper<Exception> {
- override fun toResponse(exception: Exception): Response {
- val code = if (exception is WebApplicationException) exception.response.status else 500
-
- return Response.status(code)
- .entity(ProtocolError(code, exception.message ?: "Unknown error"))
- .type(MediaType.APPLICATION_JSON)
- .build()
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/MissingKotlinParameterExceptionMapper.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/MissingKotlinParameterExceptionMapper.kt
deleted file mode 100644
index 57cd35d1..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/error/MissingKotlinParameterExceptionMapper.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.error
-
-import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
-import org.opendc.web.proto.ProtocolError
-import javax.ws.rs.core.MediaType
-import javax.ws.rs.core.Response
-import javax.ws.rs.ext.ExceptionMapper
-import javax.ws.rs.ext.Provider
-
-/**
- * An [ExceptionMapper] for [MissingKotlinParameterException] thrown by Jackson.
- */
-@Provider
-class MissingKotlinParameterExceptionMapper : ExceptionMapper<MissingKotlinParameterException> {
- override fun toResponse(exception: MissingKotlinParameterException): Response {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(ProtocolError(Response.Status.BAD_REQUEST.statusCode, "Field '${exception.parameter.name}' is missing from body."))
- .type(MediaType.APPLICATION_JSON)
- .build()
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/runner/JobResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/runner/JobResource.kt
deleted file mode 100644
index d9923505..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/runner/JobResource.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.runner
-
-import org.opendc.web.api.service.JobService
-import org.opendc.web.proto.runner.Job
-import javax.annotation.security.RolesAllowed
-import javax.inject.Inject
-import javax.transaction.Transactional
-import javax.validation.Valid
-import javax.ws.rs.*
-
-/**
- * A resource representing the available simulation jobs.
- */
-@Path("/jobs")
-@RolesAllowed("runner")
-class JobResource @Inject constructor(private val jobService: JobService) {
- /**
- * Obtain all pending simulation jobs.
- */
- @GET
- fun queryPending(): List<Job> {
- return jobService.queryPending()
- }
-
- /**
- * Get a job by identifier.
- */
- @GET
- @Path("{job}")
- fun get(@PathParam("job") id: Long): Job {
- return jobService.findById(id) ?: throw WebApplicationException("Job not found", 404)
- }
-
- /**
- * Atomically update the state of a job.
- */
- @POST
- @Path("{job}")
- @Transactional
- fun update(@PathParam("job") id: Long, @Valid update: Job.Update): Job {
- return try {
- jobService.updateState(id, update.state, update.results)
- ?: throw WebApplicationException("Job not found", 404)
- } catch (e: IllegalArgumentException) {
- throw WebApplicationException(e, 400)
- } catch (e: IllegalStateException) {
- throw WebApplicationException(e, 409)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioResource.kt
deleted file mode 100644
index e720de75..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioResource.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.quarkus.security.identity.SecurityIdentity
-import org.opendc.web.api.service.PortfolioService
-import org.opendc.web.proto.user.Portfolio
-import javax.annotation.security.RolesAllowed
-import javax.inject.Inject
-import javax.transaction.Transactional
-import javax.validation.Valid
-import javax.ws.rs.*
-
-/**
- * A resource representing the portfolios of a project.
- */
-@Path("/projects/{project}/portfolios")
-@RolesAllowed("openid")
-class PortfolioResource @Inject constructor(
- private val portfolioService: PortfolioService,
- private val identity: SecurityIdentity,
-) {
- /**
- * Get all portfolios that belong to the specified project.
- */
- @GET
- fun getAll(@PathParam("project") projectId: Long): List<Portfolio> {
- return portfolioService.findAll(identity.principal.name, projectId)
- }
-
- /**
- * Create a portfolio for this project.
- */
- @POST
- @Transactional
- fun create(@PathParam("project") projectId: Long, @Valid request: Portfolio.Create): Portfolio {
- return portfolioService.create(identity.principal.name, projectId, request) ?: throw WebApplicationException("Project not found", 404)
- }
-
- /**
- * Obtain a portfolio by its identifier.
- */
- @GET
- @Path("{portfolio}")
- fun get(@PathParam("project") projectId: Long, @PathParam("portfolio") number: Int): Portfolio {
- return portfolioService.findOne(identity.principal.name, projectId, number) ?: throw WebApplicationException("Portfolio not found", 404)
- }
-
- /**
- * Delete a portfolio.
- */
- @DELETE
- @Path("{portfolio}")
- fun delete(@PathParam("project") projectId: Long, @PathParam("portfolio") number: Int): Portfolio {
- return portfolioService.delete(identity.principal.name, projectId, number) ?: throw WebApplicationException("Portfolio not found", 404)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResource.kt
deleted file mode 100644
index 8d24b2eb..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResource.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.quarkus.security.identity.SecurityIdentity
-import org.opendc.web.api.service.ScenarioService
-import org.opendc.web.proto.user.Scenario
-import javax.annotation.security.RolesAllowed
-import javax.inject.Inject
-import javax.transaction.Transactional
-import javax.validation.Valid
-import javax.ws.rs.*
-
-/**
- * A resource representing the scenarios of a portfolio.
- */
-@Path("/projects/{project}/portfolios/{portfolio}/scenarios")
-@RolesAllowed("openid")
-class PortfolioScenarioResource @Inject constructor(
- private val scenarioService: ScenarioService,
- private val identity: SecurityIdentity,
-) {
- /**
- * Get all scenarios that belong to the specified portfolio.
- */
- @GET
- fun get(@PathParam("project") projectId: Long, @PathParam("portfolio") portfolioNumber: Int): List<Scenario> {
- return scenarioService.findAll(identity.principal.name, projectId, portfolioNumber)
- }
-
- /**
- * Create a scenario for this portfolio.
- */
- @POST
- @Transactional
- fun create(@PathParam("project") projectId: Long, @PathParam("portfolio") portfolioNumber: Int, @Valid request: Scenario.Create): Scenario {
- return scenarioService.create(identity.principal.name, projectId, portfolioNumber, request) ?: throw WebApplicationException("Portfolio not found", 404)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ProjectResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ProjectResource.kt
deleted file mode 100644
index a27d50e7..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ProjectResource.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.quarkus.security.identity.SecurityIdentity
-import org.opendc.web.api.service.ProjectService
-import org.opendc.web.proto.user.Project
-import javax.annotation.security.RolesAllowed
-import javax.inject.Inject
-import javax.transaction.Transactional
-import javax.validation.Valid
-import javax.ws.rs.*
-
-/**
- * A resource representing the created projects.
- */
-@Path("/projects")
-@RolesAllowed("openid")
-class ProjectResource @Inject constructor(
- private val projectService: ProjectService,
- private val identity: SecurityIdentity
-) {
- /**
- * Obtain all the projects of the current user.
- */
- @GET
- fun getAll(): List<Project> {
- return projectService.findWithUser(identity.principal.name)
- }
-
- /**
- * Create a new project for the current user.
- */
- @POST
- @Transactional
- fun create(@Valid request: Project.Create): Project {
- return projectService.createForUser(identity.principal.name, request.name)
- }
-
- /**
- * Obtain a single project by its identifier.
- */
- @GET
- @Path("{project}")
- fun get(@PathParam("project") id: Long): Project {
- return projectService.findWithUser(identity.principal.name, id) ?: throw WebApplicationException("Project not found", 404)
- }
-
- /**
- * Delete a project.
- */
- @DELETE
- @Path("{project}")
- @Transactional
- fun delete(@PathParam("project") id: Long): Project {
- try {
- return projectService.deleteWithUser(identity.principal.name, id) ?: throw WebApplicationException("Project not found", 404)
- } catch (e: IllegalArgumentException) {
- throw WebApplicationException(e.message, 403)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ScenarioResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ScenarioResource.kt
deleted file mode 100644
index 3690f987..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/ScenarioResource.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.quarkus.security.identity.SecurityIdentity
-import org.opendc.web.api.service.ScenarioService
-import org.opendc.web.proto.user.Scenario
-import javax.annotation.security.RolesAllowed
-import javax.inject.Inject
-import javax.transaction.Transactional
-import javax.ws.rs.*
-
-/**
- * A resource representing the scenarios of a portfolio.
- */
-@Path("/projects/{project}/scenarios")
-@RolesAllowed("openid")
-class ScenarioResource @Inject constructor(
- private val scenarioService: ScenarioService,
- private val identity: SecurityIdentity
-) {
- /**
- * Obtain a scenario by its identifier.
- */
- @GET
- @Path("{scenario}")
- fun get(@PathParam("project") projectId: Long, @PathParam("scenario") number: Int): Scenario {
- return scenarioService.findOne(identity.principal.name, projectId, number) ?: throw WebApplicationException("Scenario not found", 404)
- }
-
- /**
- * Delete a scenario.
- */
- @DELETE
- @Path("{scenario}")
- @Transactional
- fun delete(@PathParam("project") projectId: Long, @PathParam("scenario") number: Int): Scenario {
- return scenarioService.delete(identity.principal.name, projectId, number) ?: throw WebApplicationException("Scenario not found", 404)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/TopologyResource.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/TopologyResource.kt
deleted file mode 100644
index 52c5eaaa..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/rest/user/TopologyResource.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.quarkus.security.identity.SecurityIdentity
-import org.opendc.web.api.service.TopologyService
-import org.opendc.web.proto.user.Topology
-import javax.annotation.security.RolesAllowed
-import javax.inject.Inject
-import javax.transaction.Transactional
-import javax.validation.Valid
-import javax.ws.rs.*
-
-/**
- * A resource representing the constructed datacenter topologies.
- */
-@Path("/projects/{project}/topologies")
-@RolesAllowed("openid")
-class TopologyResource @Inject constructor(
- private val topologyService: TopologyService,
- private val identity: SecurityIdentity
-) {
- /**
- * Get all topologies that belong to the specified project.
- */
- @GET
- fun getAll(@PathParam("project") projectId: Long): List<Topology> {
- return topologyService.findAll(identity.principal.name, projectId)
- }
-
- /**
- * Create a topology for this project.
- */
- @POST
- @Transactional
- fun create(@PathParam("project") projectId: Long, @Valid request: Topology.Create): Topology {
- return topologyService.create(identity.principal.name, projectId, request) ?: throw WebApplicationException("Topology not found", 404)
- }
-
- /**
- * Obtain a topology by its number.
- */
- @GET
- @Path("{topology}")
- fun get(@PathParam("project") projectId: Long, @PathParam("topology") number: Int): Topology {
- return topologyService.findOne(identity.principal.name, projectId, number) ?: throw WebApplicationException("Topology not found", 404)
- }
-
- /**
- * Update the specified topology by its number.
- */
- @PUT
- @Path("{topology}")
- @Transactional
- fun update(@PathParam("project") projectId: Long, @PathParam("topology") number: Int, @Valid request: Topology.Update): Topology {
- return topologyService.update(identity.principal.name, projectId, number, request) ?: throw WebApplicationException("Topology not found", 404)
- }
-
- /**
- * Delete the specified topology.
- */
- @Path("{topology}")
- @DELETE
- @Transactional
- fun delete(@PathParam("project") projectId: Long, @PathParam("topology") number: Int): Topology {
- return topologyService.delete(identity.principal.name, projectId, number) ?: throw WebApplicationException("Topology not found", 404)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/JobService.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/JobService.kt
deleted file mode 100644
index 1b33248d..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/JobService.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.repository.JobRepository
-import org.opendc.web.proto.JobState
-import org.opendc.web.proto.runner.Job
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-
-/**
- * Service for managing [Job]s.
- */
-@ApplicationScoped
-class JobService @Inject constructor(private val repository: JobRepository) {
- /**
- * Query the pending simulation jobs.
- */
- fun queryPending(): List<Job> {
- return repository.findAll(JobState.PENDING).map { it.toRunnerDto() }
- }
-
- /**
- * Find a job by its identifier.
- */
- fun findById(id: Long): Job? {
- return repository.findOne(id)?.toRunnerDto()
- }
-
- /**
- * Atomically update the state of a [Job].
- */
- fun updateState(id: Long, newState: JobState, results: Map<String, Any>?): Job? {
- val entity = repository.findOne(id) ?: return null
- val state = entity.state
- if (!state.isTransitionLegal(newState)) {
- throw IllegalArgumentException("Invalid transition from $state to $newState")
- }
-
- val now = Instant.now()
- if (!repository.updateOne(entity, newState, now, results)) {
- throw IllegalStateException("Conflicting update")
- }
-
- return entity.toRunnerDto()
- }
-
- /**
- * Determine whether the transition from [this] to [newState] is legal.
- */
- private fun JobState.isTransitionLegal(newState: JobState): Boolean {
- // Note that we always allow transitions from the state
- return newState == this || when (this) {
- JobState.PENDING -> newState == JobState.CLAIMED
- JobState.CLAIMED -> newState == JobState.RUNNING || newState == JobState.FAILED
- JobState.RUNNING -> newState == JobState.FINISHED || newState == JobState.FAILED
- JobState.FINISHED, JobState.FAILED -> false
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/PortfolioService.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/PortfolioService.kt
deleted file mode 100644
index 1f41c2d7..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/PortfolioService.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.model.*
-import org.opendc.web.api.repository.PortfolioRepository
-import org.opendc.web.api.repository.ProjectRepository
-import org.opendc.web.proto.user.Portfolio
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import org.opendc.web.api.model.Portfolio as PortfolioEntity
-
-/**
- * Service for managing [Portfolio]s.
- */
-@ApplicationScoped
-class PortfolioService @Inject constructor(
- private val projectRepository: ProjectRepository,
- private val portfolioRepository: PortfolioRepository
-) {
- /**
- * List all [Portfolio]s that belong a certain project.
- */
- fun findAll(userId: String, projectId: Long): List<Portfolio> {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId) ?: return emptyList()
- val project = auth.toUserDto()
- return portfolioRepository.findAll(projectId).map { it.toUserDto(project) }
- }
-
- /**
- * Find a [Portfolio] with the specified [number] belonging to [project][projectId].
- */
- fun findOne(userId: String, projectId: Long, number: Int): Portfolio? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId) ?: return null
- return portfolioRepository.findOne(projectId, number)?.toUserDto(auth.toUserDto())
- }
-
- /**
- * Delete the portfolio with the specified [number] belonging to [project][projectId].
- */
- fun delete(userId: String, projectId: Long, number: Int): Portfolio? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val entity = portfolioRepository.findOne(projectId, number) ?: return null
- val portfolio = entity.toUserDto(auth.toUserDto())
- portfolioRepository.delete(entity)
- return portfolio
- }
-
- /**
- * Construct a new [Portfolio] with the specified name.
- */
- fun create(userId: String, projectId: Long, request: Portfolio.Create): Portfolio? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val now = Instant.now()
- val project = auth.project
- val number = projectRepository.allocatePortfolio(auth.project, now)
-
- val portfolio = PortfolioEntity(0, number, request.name, project, request.targets)
-
- project.portfolios.add(portfolio)
- portfolioRepository.save(portfolio)
-
- return portfolio.toUserDto(auth.toUserDto())
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ProjectService.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ProjectService.kt
deleted file mode 100644
index c3e43395..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ProjectService.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.model.*
-import org.opendc.web.api.repository.ProjectRepository
-import org.opendc.web.proto.user.Project
-import org.opendc.web.proto.user.ProjectRole
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-
-/**
- * Service for managing [Project]s.
- */
-@ApplicationScoped
-class ProjectService @Inject constructor(private val repository: ProjectRepository) {
- /**
- * List all projects for the user with the specified [userId].
- */
- fun findWithUser(userId: String): List<Project> {
- return repository.findAll(userId).map { it.toUserDto() }
- }
-
- /**
- * Obtain the project with the specified [id] for the user with the specified [userId].
- */
- fun findWithUser(userId: String, id: Long): Project? {
- return repository.findOne(userId, id)?.toUserDto()
- }
-
- /**
- * Create a new [Project] for the user with the specified [userId].
- */
- fun createForUser(userId: String, name: String): Project {
- val now = Instant.now()
- val entity = Project(0, name, now)
- repository.save(entity)
-
- val authorization = ProjectAuthorization(ProjectAuthorizationKey(userId, entity.id), entity, ProjectRole.OWNER)
-
- entity.authorizations.add(authorization)
- repository.save(authorization)
-
- return authorization.toUserDto()
- }
-
- /**
- * Delete a project by its identifier.
- *
- * @param userId The user that invokes the action.
- * @param id The identifier of the project.
- */
- fun deleteWithUser(userId: String, id: Long): Project? {
- val auth = repository.findOne(userId, id) ?: return null
-
- if (!auth.role.canDelete) {
- throw IllegalArgumentException("Not allowed to delete project")
- }
-
- val now = Instant.now()
- val project = auth.toUserDto().copy(updatedAt = now)
- repository.delete(auth.project)
- return project
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/RunnerConversions.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/RunnerConversions.kt
deleted file mode 100644
index 3722a641..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/RunnerConversions.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.model.Job
-import org.opendc.web.api.model.Portfolio
-import org.opendc.web.api.model.Scenario
-import org.opendc.web.api.model.Topology
-
-/**
- * Conversions into DTOs provided to OpenDC runners.
- */
-
-/**
- * Convert a [Topology] into a runner-facing DTO.
- */
-internal fun Topology.toRunnerDto(): org.opendc.web.proto.runner.Topology {
- return org.opendc.web.proto.runner.Topology(id, number, name, rooms, createdAt, updatedAt)
-}
-
-/**
- * Convert a [Portfolio] into a runner-facing DTO.
- */
-internal fun Portfolio.toRunnerDto(): org.opendc.web.proto.runner.Portfolio {
- return org.opendc.web.proto.runner.Portfolio(id, number, name, targets)
-}
-
-/**
- * Convert a [Job] into a runner-facing DTO.
- */
-internal fun Job.toRunnerDto(): org.opendc.web.proto.runner.Job {
- return org.opendc.web.proto.runner.Job(id, scenario.toRunnerDto(), state, createdAt, updatedAt, results)
-}
-
-/**
- * Convert a [Job] into a runner-facing DTO.
- */
-internal fun Scenario.toRunnerDto(): org.opendc.web.proto.runner.Scenario {
- return org.opendc.web.proto.runner.Scenario(
- id,
- number,
- portfolio.toRunnerDto(),
- name,
- workload.toDto(),
- topology.toRunnerDto(),
- phenomena,
- schedulerName
- )
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ScenarioService.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ScenarioService.kt
deleted file mode 100644
index dd51a929..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/ScenarioService.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.model.*
-import org.opendc.web.api.repository.*
-import org.opendc.web.proto.user.Scenario
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-
-/**
- * Service for managing [Scenario]s.
- */
-@ApplicationScoped
-class ScenarioService @Inject constructor(
- private val projectRepository: ProjectRepository,
- private val portfolioRepository: PortfolioRepository,
- private val topologyRepository: TopologyRepository,
- private val traceRepository: TraceRepository,
- private val scenarioRepository: ScenarioRepository,
-) {
- /**
- * List all [Scenario]s that belong a certain portfolio.
- */
- fun findAll(userId: String, projectId: Long, number: Int): List<Scenario> {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId) ?: return emptyList()
- val project = auth.toUserDto()
- return scenarioRepository.findAll(projectId).map { it.toUserDto(project) }
- }
-
- /**
- * Obtain a [Scenario] by identifier.
- */
- fun findOne(userId: String, projectId: Long, number: Int): Scenario? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId) ?: return null
- val project = auth.toUserDto()
- return scenarioRepository.findOne(projectId, number)?.toUserDto(project)
- }
-
- /**
- * Delete the specified scenario.
- */
- fun delete(userId: String, projectId: Long, number: Int): Scenario? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val entity = scenarioRepository.findOne(projectId, number) ?: return null
- val scenario = entity.toUserDto(auth.toUserDto())
- scenarioRepository.delete(entity)
- return scenario
- }
-
- /**
- * Construct a new [Scenario] with the specified data.
- */
- fun create(userId: String, projectId: Long, portfolioNumber: Int, request: Scenario.Create): Scenario? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val portfolio = portfolioRepository.findOne(projectId, portfolioNumber) ?: return null
- val topology = requireNotNull(
- topologyRepository.findOne(
- projectId,
- request.topology.toInt()
- )
- ) { "Referred topology does not exist" }
- val trace =
- requireNotNull(traceRepository.findOne(request.workload.trace)) { "Referred trace does not exist" }
-
- val now = Instant.now()
- val project = auth.project
- val number = projectRepository.allocateScenario(auth.project, now)
-
- val scenario = Scenario(
- 0,
- number,
- request.name,
- project,
- portfolio,
- Workload(trace, request.workload.samplingFraction),
- topology,
- request.phenomena,
- request.schedulerName
- )
- val job = Job(0, scenario, now, portfolio.targets.repeats)
-
- scenario.job = job
- portfolio.scenarios.add(scenario)
- scenarioRepository.save(scenario)
-
- return scenario.toUserDto(auth.toUserDto())
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TopologyService.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TopologyService.kt
deleted file mode 100644
index f3460496..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TopologyService.kt
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.repository.ProjectRepository
-import org.opendc.web.api.repository.TopologyRepository
-import org.opendc.web.proto.user.Topology
-import java.time.Instant
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-import org.opendc.web.api.model.Topology as TopologyEntity
-
-/**
- * Service for managing [Topology]s.
- */
-@ApplicationScoped
-class TopologyService @Inject constructor(
- private val projectRepository: ProjectRepository,
- private val topologyRepository: TopologyRepository
-) {
- /**
- * List all [Topology]s that belong a certain project.
- */
- fun findAll(userId: String, projectId: Long): List<Topology> {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId) ?: return emptyList()
- val project = auth.toUserDto()
- return topologyRepository.findAll(projectId).map { it.toUserDto(project) }
- }
-
- /**
- * Find the [Topology] with the specified [number] belonging to [project][projectId].
- */
- fun findOne(userId: String, projectId: Long, number: Int): Topology? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId) ?: return null
- return topologyRepository.findOne(projectId, number)?.toUserDto(auth.toUserDto())
- }
-
- /**
- * Delete the [Topology] with the specified [number] belonging to [project][projectId].
- */
- fun delete(userId: String, projectId: Long, number: Int): Topology? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val entity = topologyRepository.findOne(projectId, number) ?: return null
- val now = Instant.now()
- val topology = entity.toUserDto(auth.toUserDto()).copy(updatedAt = now)
- topologyRepository.delete(entity)
-
- return topology
- }
-
- /**
- * Update a [Topology] with the specified [number] belonging to [project][projectId].
- */
- fun update(userId: String, projectId: Long, number: Int, request: Topology.Update): Topology? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val entity = topologyRepository.findOne(projectId, number) ?: return null
- val now = Instant.now()
-
- entity.updatedAt = now
- entity.rooms = request.rooms
-
- return entity.toUserDto(auth.toUserDto())
- }
-
- /**
- * Construct a new [Topology] with the specified name.
- */
- fun create(userId: String, projectId: Long, request: Topology.Create): Topology? {
- // User must have access to project
- val auth = projectRepository.findOne(userId, projectId)
-
- if (auth == null) {
- return null
- } else if (!auth.role.canEdit) {
- throw IllegalStateException("Not permitted to edit project")
- }
-
- val now = Instant.now()
- val project = auth.project
- val number = projectRepository.allocateTopology(auth.project, now)
-
- val topology = TopologyEntity(0, number, request.name, project, now, request.rooms)
-
- project.topologies.add(topology)
- topologyRepository.save(topology)
-
- return topology.toUserDto(auth.toUserDto())
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TraceService.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TraceService.kt
deleted file mode 100644
index a942696e..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/TraceService.kt
+++ /dev/null
@@ -1,48 +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.api.service
-
-import org.opendc.web.api.repository.TraceRepository
-import org.opendc.web.proto.Trace
-import javax.enterprise.context.ApplicationScoped
-import javax.inject.Inject
-
-/**
- * Service for managing [Trace]s.
- */
-@ApplicationScoped
-class TraceService @Inject constructor(private val repository: TraceRepository) {
- /**
- * Obtain all available workload traces.
- */
- fun findAll(): List<Trace> {
- return repository.findAll().map { it.toUserDto() }
- }
-
- /**
- * Obtain a workload trace by identifier.
- */
- fun findById(id: String): Trace? {
- return repository.findOne(id)?.toUserDto()
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/UserConversions.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/UserConversions.kt
deleted file mode 100644
index 8612ee8c..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/UserConversions.kt
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.api.model.*
-import org.opendc.web.proto.user.Project
-
-/**
- * Conversions into DTOs provided to users.
- */
-
-/**
- * Convert a [Trace] entity into a [org.opendc.web.proto.Trace] DTO.
- */
-internal fun Trace.toUserDto(): org.opendc.web.proto.Trace {
- return org.opendc.web.proto.Trace(id, name, type)
-}
-
-/**
- * Convert a [ProjectAuthorization] entity into a [Project] DTO.
- */
-internal fun ProjectAuthorization.toUserDto(): Project {
- return Project(project.id, project.name, project.createdAt, project.updatedAt, role)
-}
-
-/**
- * Convert a [Topology] entity into a [org.opendc.web.proto.user.Topology] DTO.
- */
-internal fun Topology.toUserDto(project: Project): org.opendc.web.proto.user.Topology {
- return org.opendc.web.proto.user.Topology(id, number, project, name, rooms, createdAt, updatedAt)
-}
-
-/**
- * Convert a [Topology] entity into a [org.opendc.web.proto.user.Topology.Summary] DTO.
- */
-private fun Topology.toSummaryDto(): org.opendc.web.proto.user.Topology.Summary {
- return org.opendc.web.proto.user.Topology.Summary(id, number, name, createdAt, updatedAt)
-}
-
-/**
- * Convert a [Portfolio] entity into a [org.opendc.web.proto.user.Portfolio] DTO.
- */
-internal fun Portfolio.toUserDto(project: Project): org.opendc.web.proto.user.Portfolio {
- return org.opendc.web.proto.user.Portfolio(id, number, project, name, targets, scenarios.map { it.toSummaryDto() })
-}
-
-/**
- * Convert a [Portfolio] entity into a [org.opendc.web.proto.user.Portfolio.Summary] DTO.
- */
-private fun Portfolio.toSummaryDto(): org.opendc.web.proto.user.Portfolio.Summary {
- return org.opendc.web.proto.user.Portfolio.Summary(id, number, name, targets)
-}
-
-/**
- * Convert a [Scenario] entity into a [org.opendc.web.proto.user.Scenario] DTO.
- */
-internal fun Scenario.toUserDto(project: Project): org.opendc.web.proto.user.Scenario {
- return org.opendc.web.proto.user.Scenario(
- id,
- number,
- project,
- portfolio.toSummaryDto(),
- name,
- workload.toDto(),
- topology.toSummaryDto(),
- phenomena,
- schedulerName,
- job.toUserDto()
- )
-}
-
-/**
- * Convert a [Scenario] entity into a [org.opendc.web.proto.user.Scenario.Summary] DTO.
- */
-private fun Scenario.toSummaryDto(): org.opendc.web.proto.user.Scenario.Summary {
- return org.opendc.web.proto.user.Scenario.Summary(
- id,
- number,
- name,
- workload.toDto(),
- topology.toSummaryDto(),
- phenomena,
- schedulerName,
- job.toUserDto()
- )
-}
-
-/**
- * Convert a [Job] entity into a [org.opendc.web.proto.user.Job] DTO.
- */
-internal fun Job.toUserDto(): org.opendc.web.proto.user.Job {
- return org.opendc.web.proto.user.Job(id, state, createdAt, updatedAt, results)
-}
-
-/**
- * Convert a [Workload] entity into a DTO.
- */
-internal fun Workload.toDto(): org.opendc.web.proto.Workload {
- return org.opendc.web.proto.Workload(trace.toUserDto(), samplingFraction)
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/Utils.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/Utils.kt
deleted file mode 100644
index 254be8b7..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/service/Utils.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.service
-
-import org.opendc.web.proto.user.ProjectRole
-
-/**
- * Flag to indicate that the user can edit a project.
- */
-internal val ProjectRole.canEdit: Boolean
- get() = when (this) {
- ProjectRole.OWNER, ProjectRole.EDITOR -> true
- ProjectRole.VIEWER -> false
- }
-
-/**
- * Flag to indicate that the user can delete a project.
- */
-internal val ProjectRole.canDelete: Boolean
- get() = this == ProjectRole.OWNER
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/DevSecurityOverrideFilter.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/DevSecurityOverrideFilter.kt
deleted file mode 100644
index ba2cf2ae..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/DevSecurityOverrideFilter.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util
-
-import io.quarkus.arc.properties.IfBuildProperty
-import java.security.Principal
-import javax.ws.rs.container.ContainerRequestContext
-import javax.ws.rs.container.ContainerRequestFilter
-import javax.ws.rs.container.PreMatching
-import javax.ws.rs.core.SecurityContext
-import javax.ws.rs.ext.Provider
-
-/**
- * Helper class to disable security for the OpenDC web API when in development mode.
- */
-@Provider
-@PreMatching
-@IfBuildProperty(name = "opendc.security.enabled", stringValue = "false")
-class DevSecurityOverrideFilter : ContainerRequestFilter {
- override fun filter(requestContext: ContainerRequestContext) {
- requestContext.securityContext = object : SecurityContext {
- override fun getUserPrincipal(): Principal = Principal { "anon" }
-
- override fun isSecure(): Boolean = false
-
- override fun isUserInRole(role: String): Boolean = true
-
- override fun getAuthenticationScheme(): String = "basic"
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/KotlinModuleCustomizer.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/KotlinModuleCustomizer.kt
deleted file mode 100644
index 8d91a00c..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/KotlinModuleCustomizer.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.module.kotlin.KotlinModule
-import io.quarkus.jackson.ObjectMapperCustomizer
-import javax.inject.Singleton
-
-/**
- * Helper class to register the Kotlin Jackson module.
- */
-@Singleton
-class KotlinModuleCustomizer : ObjectMapperCustomizer {
- override fun customize(objectMapper: ObjectMapper) {
- objectMapper.registerModule(KotlinModule.Builder().build())
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/AbstractJsonSqlTypeDescriptor.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/AbstractJsonSqlTypeDescriptor.kt
deleted file mode 100644
index 134739c9..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/AbstractJsonSqlTypeDescriptor.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util.hibernate.json
-
-import org.hibernate.type.descriptor.ValueExtractor
-import org.hibernate.type.descriptor.WrapperOptions
-import org.hibernate.type.descriptor.java.JavaTypeDescriptor
-import org.hibernate.type.descriptor.sql.BasicExtractor
-import org.hibernate.type.descriptor.sql.SqlTypeDescriptor
-import java.sql.CallableStatement
-import java.sql.ResultSet
-import java.sql.Types
-
-/**
- * Abstract implementation of a [SqlTypeDescriptor] for Hibernate JSON type.
- */
-internal abstract class AbstractJsonSqlTypeDescriptor : SqlTypeDescriptor {
-
- override fun getSqlType(): Int {
- return Types.OTHER
- }
-
- override fun canBeRemapped(): Boolean {
- return true
- }
-
- override fun <X> getExtractor(typeDescriptor: JavaTypeDescriptor<X>): ValueExtractor<X> {
- return object : BasicExtractor<X>(typeDescriptor, this) {
- override fun doExtract(rs: ResultSet, name: String, options: WrapperOptions): X {
- return typeDescriptor.wrap(extractJson(rs, name), options)
- }
-
- override fun doExtract(statement: CallableStatement, index: Int, options: WrapperOptions): X {
- return typeDescriptor.wrap(extractJson(statement, index), options)
- }
-
- override fun doExtract(statement: CallableStatement, name: String, options: WrapperOptions): X {
- return typeDescriptor.wrap(extractJson(statement, name), options)
- }
- }
- }
-
- open fun extractJson(rs: ResultSet, name: String): Any? {
- return rs.getObject(name)
- }
-
- open fun extractJson(statement: CallableStatement, index: Int): Any? {
- return statement.getObject(index)
- }
-
- open fun extractJson(statement: CallableStatement, name: String): Any? {
- return statement.getObject(name)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBinarySqlTypeDescriptor.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBinarySqlTypeDescriptor.kt
deleted file mode 100644
index 32f69928..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBinarySqlTypeDescriptor.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.opendc.web.api.util.hibernate.json
-
-import com.fasterxml.jackson.databind.JsonNode
-import org.hibernate.type.descriptor.ValueBinder
-import org.hibernate.type.descriptor.WrapperOptions
-import org.hibernate.type.descriptor.java.JavaTypeDescriptor
-import org.hibernate.type.descriptor.sql.BasicBinder
-import java.sql.CallableStatement
-import java.sql.PreparedStatement
-
-/**
- * A [AbstractJsonSqlTypeDescriptor] that stores the JSON as binary (JSONB).
- */
-internal object JsonBinarySqlTypeDescriptor : AbstractJsonSqlTypeDescriptor() {
- override fun <X> getBinder(typeDescriptor: JavaTypeDescriptor<X>): ValueBinder<X> {
- return object : BasicBinder<X>(typeDescriptor, this) {
- override fun doBind(st: PreparedStatement, value: X, index: Int, options: WrapperOptions) {
- st.setObject(index, typeDescriptor.unwrap(value, JsonNode::class.java, options), sqlType)
- }
-
- override fun doBind(st: CallableStatement, value: X, name: String, options: WrapperOptions) {
- st.setObject(name, typeDescriptor.unwrap(value, JsonNode::class.java, options), sqlType)
- }
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBytesSqlTypeDescriptor.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBytesSqlTypeDescriptor.kt
deleted file mode 100644
index eaecc5b0..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonBytesSqlTypeDescriptor.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util.hibernate.json
-
-import org.hibernate.type.descriptor.ValueBinder
-import org.hibernate.type.descriptor.WrapperOptions
-import org.hibernate.type.descriptor.java.JavaTypeDescriptor
-import org.hibernate.type.descriptor.sql.BasicBinder
-import java.io.UnsupportedEncodingException
-import java.sql.*
-
-/**
- * A [AbstractJsonSqlTypeDescriptor] that stores the JSON as UTF-8 encoded bytes.
- */
-internal object JsonBytesSqlTypeDescriptor : AbstractJsonSqlTypeDescriptor() {
- private val CHARSET = Charsets.UTF_8
-
- override fun getSqlType(): Int {
- return Types.BINARY
- }
-
- override fun <X> getBinder(javaTypeDescriptor: JavaTypeDescriptor<X>): ValueBinder<X> {
- return object : BasicBinder<X>(javaTypeDescriptor, this) {
- override fun doBind(st: PreparedStatement, value: X, index: Int, options: WrapperOptions) {
- st.setBytes(index, toJsonBytes(javaTypeDescriptor.unwrap(value, String::class.java, options)))
- }
-
- override fun doBind(st: CallableStatement, value: X, name: String, options: WrapperOptions) {
- st.setBytes(name, toJsonBytes(javaTypeDescriptor.unwrap(value, String::class.java, options)))
- }
- }
- }
-
- override fun extractJson(rs: ResultSet, name: String): Any? {
- return fromJsonBytes(rs.getBytes(name))
- }
-
- override fun extractJson(statement: CallableStatement, index: Int): Any? {
- return fromJsonBytes(statement.getBytes(index))
- }
-
- override fun extractJson(statement: CallableStatement, name: String): Any? {
- return fromJsonBytes(statement.getBytes(name))
- }
-
- private fun toJsonBytes(jsonValue: String): ByteArray? {
- return try {
- jsonValue.toByteArray(CHARSET)
- } catch (e: UnsupportedEncodingException) {
- throw IllegalStateException(e)
- }
- }
-
- private fun fromJsonBytes(jsonBytes: ByteArray?): String? {
- return if (jsonBytes == null) {
- null
- } else try {
- String(jsonBytes, CHARSET)
- } catch (e: UnsupportedEncodingException) {
- throw IllegalStateException(e)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonSqlTypeDescriptor.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonSqlTypeDescriptor.kt
deleted file mode 100644
index e005f368..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonSqlTypeDescriptor.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util.hibernate.json
-
-import org.hibernate.dialect.H2Dialect
-import org.hibernate.dialect.PostgreSQL81Dialect
-import org.hibernate.internal.SessionImpl
-import org.hibernate.type.descriptor.ValueBinder
-import org.hibernate.type.descriptor.ValueExtractor
-import org.hibernate.type.descriptor.WrapperOptions
-import org.hibernate.type.descriptor.java.JavaTypeDescriptor
-import org.hibernate.type.descriptor.sql.BasicBinder
-import org.hibernate.type.descriptor.sql.BasicExtractor
-import org.hibernate.type.descriptor.sql.SqlTypeDescriptor
-import java.sql.*
-
-/**
- * A [SqlTypeDescriptor] that automatically selects the correct implementation for the database dialect.
- */
-internal object JsonSqlTypeDescriptor : SqlTypeDescriptor {
-
- override fun getSqlType(): Int = Types.OTHER
-
- override fun canBeRemapped(): Boolean = true
-
- override fun <X> getExtractor(javaTypeDescriptor: JavaTypeDescriptor<X>): ValueExtractor<X> {
- return object : BasicExtractor<X>(javaTypeDescriptor, this) {
- private var delegate: AbstractJsonSqlTypeDescriptor? = null
-
- override fun doExtract(rs: ResultSet, name: String, options: WrapperOptions): X {
- return javaTypeDescriptor.wrap(delegate(options).extractJson(rs, name), options)
- }
-
- override fun doExtract(statement: CallableStatement, index: Int, options: WrapperOptions): X {
- return javaTypeDescriptor.wrap(delegate(options).extractJson(statement, index), options)
- }
-
- override fun doExtract(statement: CallableStatement, name: String, options: WrapperOptions): X {
- return javaTypeDescriptor.wrap(delegate(options).extractJson(statement, name), options)
- }
-
- private fun delegate(options: WrapperOptions): AbstractJsonSqlTypeDescriptor {
- var delegate = delegate
- if (delegate == null) {
- delegate = resolveSqlTypeDescriptor(options)
- this.delegate = delegate
- }
- return delegate
- }
- }
- }
-
- override fun <X> getBinder(javaTypeDescriptor: JavaTypeDescriptor<X>): ValueBinder<X> {
- return object : BasicBinder<X>(javaTypeDescriptor, this) {
- private var delegate: ValueBinder<X>? = null
-
- override fun doBind(st: PreparedStatement, value: X, index: Int, options: WrapperOptions) {
- delegate(options).bind(st, value, index, options)
- }
-
- override fun doBind(st: CallableStatement, value: X, name: String, options: WrapperOptions) {
- delegate(options).bind(st, value, name, options)
- }
-
- private fun delegate(options: WrapperOptions): ValueBinder<X> {
- var delegate = delegate
- if (delegate == null) {
- delegate = checkNotNull(resolveSqlTypeDescriptor(options).getBinder(javaTypeDescriptor))
- this.delegate = delegate
- }
- return delegate
- }
- }
- }
-
- /**
- * Helper method to resolve the appropriate [SqlTypeDescriptor] based on the [WrapperOptions].
- */
- private fun resolveSqlTypeDescriptor(options: WrapperOptions): AbstractJsonSqlTypeDescriptor {
- val session = options as? SessionImpl
- return when (session?.jdbcServices?.dialect) {
- is PostgreSQL81Dialect -> JsonBinarySqlTypeDescriptor
- is H2Dialect -> JsonBytesSqlTypeDescriptor
- else -> JsonStringSqlTypeDescriptor
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonStringSqlTypeDescriptor.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonStringSqlTypeDescriptor.kt
deleted file mode 100644
index cf400c95..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonStringSqlTypeDescriptor.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.opendc.web.api.util.hibernate.json
-
-import org.hibernate.type.descriptor.ValueBinder
-import org.hibernate.type.descriptor.WrapperOptions
-import org.hibernate.type.descriptor.java.JavaTypeDescriptor
-import org.hibernate.type.descriptor.sql.BasicBinder
-import java.sql.*
-
-/**
- * A [AbstractJsonSqlTypeDescriptor] that stores the JSON as string (VARCHAR).
- */
-internal object JsonStringSqlTypeDescriptor : AbstractJsonSqlTypeDescriptor() {
- override fun getSqlType(): Int = Types.VARCHAR
-
- override fun <X> getBinder(typeDescriptor: JavaTypeDescriptor<X>): ValueBinder<X> {
- return object : BasicBinder<X>(typeDescriptor, this) {
- override fun doBind(st: PreparedStatement, value: X, index: Int, options: WrapperOptions) {
- st.setString(index, typeDescriptor.unwrap(value, String::class.java, options))
- }
-
- override fun doBind(st: CallableStatement, value: X, name: String, options: WrapperOptions) {
- st.setString(name, typeDescriptor.unwrap(value, String::class.java, options))
- }
- }
- }
-
- override fun extractJson(rs: ResultSet, name: String): Any? {
- return rs.getString(name)
- }
-
- override fun extractJson(statement: CallableStatement, index: Int): Any? {
- return statement.getString(index)
- }
-
- override fun extractJson(statement: CallableStatement, name: String): Any? {
- return statement.getString(name)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonType.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonType.kt
deleted file mode 100644
index 2206e82f..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonType.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util.hibernate.json
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import org.hibernate.type.AbstractSingleColumnStandardBasicType
-import org.hibernate.type.BasicType
-import org.hibernate.usertype.DynamicParameterizedType
-import java.util.*
-import javax.enterprise.inject.spi.CDI
-
-/**
- * A [BasicType] that contains JSON.
- */
-class JsonType(objectMapper: ObjectMapper) : AbstractSingleColumnStandardBasicType<Any>(JsonSqlTypeDescriptor, JsonTypeDescriptor(objectMapper)), DynamicParameterizedType {
- /**
- * No-arg constructor for Hibernate to instantiate.
- */
- constructor() : this(CDI.current().select(ObjectMapper::class.java).get())
-
- override fun getName(): String = "json"
-
- override fun registerUnderJavaType(): Boolean = true
-
- override fun setParameterValues(parameters: Properties) {
- (javaTypeDescriptor as JsonTypeDescriptor).setParameterValues(parameters)
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonTypeDescriptor.kt b/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonTypeDescriptor.kt
deleted file mode 100644
index 3386582e..00000000
--- a/opendc-web/opendc-web-api/src/main/kotlin/org/opendc/web/api/util/hibernate/json/JsonTypeDescriptor.kt
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.util.hibernate.json
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import org.hibernate.HibernateException
-import org.hibernate.annotations.common.reflection.XProperty
-import org.hibernate.annotations.common.reflection.java.JavaXMember
-import org.hibernate.engine.jdbc.BinaryStream
-import org.hibernate.engine.jdbc.internal.BinaryStreamImpl
-import org.hibernate.type.descriptor.WrapperOptions
-import org.hibernate.type.descriptor.java.AbstractTypeDescriptor
-import org.hibernate.type.descriptor.java.BlobTypeDescriptor
-import org.hibernate.type.descriptor.java.DataHelper
-import org.hibernate.type.descriptor.java.MutableMutabilityPlan
-import org.hibernate.usertype.DynamicParameterizedType
-import java.io.ByteArrayInputStream
-import java.io.IOException
-import java.io.InputStream
-import java.lang.reflect.Type
-import java.sql.Blob
-import java.sql.SQLException
-import java.util.*
-
-/**
- * An [AbstractTypeDescriptor] implementation for Hibernate JSON type.
- */
-internal class JsonTypeDescriptor(private val objectMapper: ObjectMapper) : AbstractTypeDescriptor<Any>(Any::class.java, JsonMutabilityPlan(objectMapper)), DynamicParameterizedType {
- private var type: Type? = null
-
- override fun setParameterValues(parameters: Properties) {
- val xProperty = parameters[DynamicParameterizedType.XPROPERTY] as XProperty
- type = if (xProperty is JavaXMember) {
- val x = xProperty as JavaXMember
- x.javaType
- } else {
- (parameters[DynamicParameterizedType.PARAMETER_TYPE] as DynamicParameterizedType.ParameterType).returnedClass
- }
- }
-
- override fun areEqual(one: Any?, another: Any?): Boolean {
- return when {
- one === another -> true
- one == null || another == null -> false
- one is String && another is String -> one == another
- one is Collection<*> && another is Collection<*> -> Objects.equals(one, another)
- else -> areJsonEqual(one, another)
- }
- }
-
- override fun toString(value: Any?): String {
- return objectMapper.writeValueAsString(value)
- }
-
- override fun fromString(string: String): Any? {
- return objectMapper.readValue(string, objectMapper.typeFactory.constructType(type))
- }
-
- override fun <X> unwrap(value: Any?, type: Class<X>, options: WrapperOptions): X? {
- if (value == null) {
- return null
- }
-
- @Suppress("UNCHECKED_CAST")
- return when {
- String::class.java.isAssignableFrom(type) -> toString(value)
- BinaryStream::class.java.isAssignableFrom(type) || ByteArray::class.java.isAssignableFrom(type) -> {
- val stringValue = if (value is String) value else toString(value)
- BinaryStreamImpl(DataHelper.extractBytes(ByteArrayInputStream(stringValue.toByteArray())))
- }
- Blob::class.java.isAssignableFrom(type) -> {
- val stringValue = if (value is String) value else toString(value)
- BlobTypeDescriptor.INSTANCE.fromString(stringValue)
- }
- Any::class.java.isAssignableFrom(type) -> toJsonType(value)
- else -> throw unknownUnwrap(type)
- } as X
- }
-
- override fun <X> wrap(value: X?, options: WrapperOptions): Any? {
- if (value == null) {
- return null
- }
-
- var blob: Blob? = null
- if (Blob::class.java.isAssignableFrom(value.javaClass)) {
- blob = options.lobCreator.wrap(value as Blob?)
- } else if (ByteArray::class.java.isAssignableFrom(value.javaClass)) {
- blob = options.lobCreator.createBlob(value as ByteArray?)
- } else if (InputStream::class.java.isAssignableFrom(value.javaClass)) {
- val inputStream = value as InputStream
- blob = try {
- options.lobCreator.createBlob(inputStream, inputStream.available().toLong())
- } catch (e: IOException) {
- throw unknownWrap(value.javaClass)
- }
- }
-
- val stringValue: String = try {
- if (blob != null) String(DataHelper.extractBytes(blob.binaryStream)) else value.toString()
- } catch (e: SQLException) {
- throw HibernateException("Unable to extract binary stream from Blob", e)
- }
-
- return fromString(stringValue)
- }
-
- private class JsonMutabilityPlan(private val objectMapper: ObjectMapper) : MutableMutabilityPlan<Any>() {
- override fun deepCopyNotNull(value: Any): Any {
- return objectMapper.treeToValue(objectMapper.valueToTree(value), value.javaClass)
- }
- }
-
- private fun readObject(value: String): Any {
- return objectMapper.readTree(value)
- }
-
- private fun areJsonEqual(one: Any, another: Any): Boolean {
- return readObject(objectMapper.writeValueAsString(one)) == readObject(objectMapper.writeValueAsString(another))
- }
-
- private fun toJsonType(value: Any?): Any {
- return try {
- readObject(objectMapper.writeValueAsString(value))
- } catch (e: Exception) {
- throw IllegalArgumentException(e)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/main/resources/META-INF/branding/logo.png b/opendc-web/opendc-web-api/src/main/resources/META-INF/branding/logo.png
deleted file mode 100644
index d743038b..00000000
--- a/opendc-web/opendc-web-api/src/main/resources/META-INF/branding/logo.png
+++ /dev/null
Binary files differ
diff --git a/opendc-web/opendc-web-api/src/main/resources/application-dev.properties b/opendc-web/opendc-web-api/src/main/resources/application-dev.properties
deleted file mode 100644
index 98e53ee7..00000000
--- a/opendc-web/opendc-web-api/src/main/resources/application-dev.properties
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (c) 2022 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.
-
-# Datasource (H2)
-quarkus.datasource.db-kind = h2
-quarkus.datasource.jdbc.url=jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;INIT=CREATE TYPE IF NOT EXISTS "JSONB" AS blob;
-
-# Hibernate
-quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect
-quarkus.hibernate-orm.database.generation=drop-and-create
-quarkus.hibernate-orm.sql-load-script=init-dev.sql
-
-# OpenID
-quarkus.oidc.enabled=false
-quarkus.oidc.auth-server-url=
-quarkus.oidc.client-id=
-
-# OpenDC web UI
-quarkus.opendc-ui.path=/
-quarkus.resteasy.path=/api
-
-opendc.security.enabled=false
-quarkus.opendc-runner.auth.enabled=false
diff --git a/opendc-web/opendc-web-api/src/main/resources/application-prod.properties b/opendc-web/opendc-web-api/src/main/resources/application-prod.properties
deleted file mode 100644
index cebcdaab..00000000
--- a/opendc-web/opendc-web-api/src/main/resources/application-prod.properties
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) 2022 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.
-
-# Datasource
-quarkus.datasource.db-kind=postgresql
-quarkus.datasource.username=${OPENDC_DB_USERNAME}
-quarkus.datasource.password=${OPENDC_DB_PASSWORD}
-quarkus.datasource.jdbc.url=${OPENDC_DB_URL}
-
-# Hibernate
-quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQL95Dialect
-quarkus.hibernate-orm.database.generation=validate
-
-# Disable OpenDC web UI and runner
-quarkus.opendc-ui.include=false
-quarkus.opendc-runner.include=false
diff --git a/opendc-web/opendc-web-api/src/main/resources/application-test.properties b/opendc-web/opendc-web-api/src/main/resources/application-test.properties
deleted file mode 100644
index 10197119..00000000
--- a/opendc-web/opendc-web-api/src/main/resources/application-test.properties
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (c) 2022 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.
-
-# Datasource configuration
-quarkus.datasource.db-kind = h2
-quarkus.datasource.jdbc.url=jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;INIT=CREATE TYPE "JSONB" AS blob;
-
-quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect
-quarkus.hibernate-orm.database.generation=drop-and-create
-
-# No OIDC for tests
-quarkus.oidc.enabled=false
-quarkus.oidc.auth-server-url=
-quarkus.oidc.client-id=
-
-# Disable OpenAPI/Swagger
-quarkus.smallrye-openapi.enable=false
-quarkus.swagger-ui.enable=false
-quarkus.smallrye-openapi.oidc-open-id-connect-url=
-
-# Disable OpenDC web UI and runner
-quarkus.opendc-ui.include=false
-quarkus.opendc-runner.include=false
diff --git a/opendc-web/opendc-web-api/src/main/resources/application.properties b/opendc-web/opendc-web-api/src/main/resources/application.properties
deleted file mode 100644
index e9285401..00000000
--- a/opendc-web/opendc-web-api/src/main/resources/application.properties
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) 2022 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.
-
-quarkus.http.cors=true
-
-# OpenID
-quarkus.oidc.auth-server-url=https://${OPENDC_AUTH0_DOMAIN}
-quarkus.oidc.client-id=${OPENDC_AUTH0_AUDIENCE}
-quarkus.oidc.token.audience=${quarkus.oidc.client-id}
-quarkus.oidc.roles.role-claim-path=scope
-
-# Runner logging
-quarkus.log.category."org.opendc".level=ERROR
-quarkus.log.category."org.opendc.web".level=INFO
-quarkus.log.category."org.apache".level=WARN
-
-# OpenAPI and Swagger
-quarkus.smallrye-openapi.info-title=OpenDC REST API
-%dev.quarkus.smallrye-openapi.info-title=OpenDC REST API (development)
-quarkus.smallrye-openapi.info-version=2.1-rc1
-quarkus.smallrye-openapi.info-description=OpenDC is an open-source datacenter simulator for education, featuring real-time online collaboration, diverse simulation models, and detailed performance feedback statistics.
-quarkus.smallrye-openapi.info-contact-email=opendc@atlarge-research.com
-quarkus.smallrye-openapi.info-contact-name=OpenDC Support
-quarkus.smallrye-openapi.info-contact-url=https://opendc.org
-quarkus.smallrye-openapi.info-license-name=MIT
-quarkus.smallrye-openapi.info-license-url=https://github.com/atlarge-research/opendc/blob/master/LICENSE.txt
-
-quarkus.swagger-ui.path=docs
-quarkus.swagger-ui.always-include=true
-quarkus.swagger-ui.oauth-client-id=${OPENDC_AUTH0_DOCS_CLIENT_ID:}
-quarkus.swagger-ui.oauth-additional-query-string-params={"audience":"${OPENDC_AUTH0_AUDIENCE:https://api.opendc.org/}"}
-
-quarkus.smallrye-openapi.security-scheme=oidc
-quarkus.smallrye-openapi.security-scheme-name=Auth0
-quarkus.smallrye-openapi.oidc-open-id-connect-url=https://${OPENDC_AUTH0_DOMAIN:opendc.eu.auth0.com}/.well-known/openid-configuration
-quarkus.smallrye-openapi.servers=http://localhost:8080
diff --git a/opendc-web/opendc-web-api/src/main/resources/init-dev.sql b/opendc-web/opendc-web-api/src/main/resources/init-dev.sql
deleted file mode 100644
index 756eff46..00000000
--- a/opendc-web/opendc-web-api/src/main/resources/init-dev.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-
--- Add example traces
-INSERT INTO traces (id, name, type) VALUES ('bitbrains-small', 'Bitbrains Small', 'vm');
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/SchedulerResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/SchedulerResourceTest.kt
deleted file mode 100644
index e88e1c1c..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/SchedulerResourceTest.kt
+++ /dev/null
@@ -1,48 +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.api.rest
-
-import io.quarkus.test.junit.QuarkusTest
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.junit.jupiter.api.Test
-
-/**
- * Test suite for [SchedulerResource]
- */
-@QuarkusTest
-class SchedulerResourceTest {
- /**
- * Test to verify whether we can obtain all schedulers.
- */
- @Test
- fun testGetSchedulers() {
- When {
- get("/schedulers")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/TraceResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/TraceResourceTest.kt
deleted file mode 100644
index 6fab9953..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/TraceResourceTest.kt
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers
-import org.hamcrest.Matchers.equalTo
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.TraceService
-import org.opendc.web.proto.Trace
-
-/**
- * Test suite for [TraceResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(TraceResource::class)
-class TraceResourceTest {
- @InjectMock
- private lateinit var traceService: TraceService
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(traceService, TraceService::class.java)
- }
-
- /**
- * Test that tries to obtain all traces (empty response).
- */
- @Test
- fun testGetAllEmpy() {
- every { traceService.findAll() } returns emptyList()
-
- When {
- get()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("", Matchers.empty<String>())
- }
- }
-
- /**
- * Test that tries to obtain a non-existent trace.
- */
- @Test
- fun testGetNonExisting() {
- every { traceService.findById("bitbrains") } returns null
-
- When {
- get("/bitbrains")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain an existing trace.
- */
- @Test
- fun testGetExisting() {
- every { traceService.findById("bitbrains") } returns Trace("bitbrains", "Bitbrains", "VM")
-
- When {
- get("/bitbrains")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("name", equalTo("Bitbrains"))
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/runner/JobResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/runner/JobResourceTest.kt
deleted file mode 100644
index b82c60e8..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/runner/JobResourceTest.kt
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.runner
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.quarkus.test.security.TestSecurity
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Given
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers.equalTo
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.JobService
-import org.opendc.web.proto.*
-import org.opendc.web.proto.Targets
-import org.opendc.web.proto.runner.Job
-import org.opendc.web.proto.runner.Portfolio
-import org.opendc.web.proto.runner.Scenario
-import org.opendc.web.proto.runner.Topology
-import java.time.Instant
-
-/**
- * Test suite for [JobResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(JobResource::class)
-class JobResourceTest {
- @InjectMock
- private lateinit var jobService: JobService
-
- /**
- * Dummy values
- */
- private val dummyPortfolio = Portfolio(1, 1, "test", Targets(emptySet()))
- private val dummyTopology = Topology(1, 1, "test", emptyList(), Instant.now(), Instant.now())
- private val dummyTrace = Trace("bitbrains", "Bitbrains", "vm")
- private val dummyScenario = Scenario(1, 1, dummyPortfolio, "test", Workload(dummyTrace, 1.0), dummyTopology, OperationalPhenomena(false, false), "test",)
- private val dummyJob = Job(1, dummyScenario, JobState.PENDING, Instant.now(), Instant.now())
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(jobService, JobService::class.java)
- }
-
- /**
- * Test that tries to query the pending jobs without token.
- */
- @Test
- fun testQueryWithoutToken() {
- When {
- get()
- } Then {
- statusCode(401)
- }
- }
-
- /**
- * Test that tries to query the pending jobs for a user.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testQueryInvalidScope() {
- When {
- get()
- } Then {
- statusCode(403)
- }
- }
-
- /**
- * Test that tries to query the pending jobs for a runner.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testQuery() {
- every { jobService.queryPending() } returns listOf(dummyJob)
-
- When {
- get()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("get(0).id", equalTo(1))
- }
- }
-
- /**
- * Test that tries to obtain a non-existent job.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetNonExisting() {
- every { jobService.findById(1) } returns null
-
- When {
- get("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a job.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetExisting() {
- every { jobService.findById(1) } returns dummyJob
-
- When {
- get("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", equalTo(1))
- }
- }
-
- /**
- * Test that tries to update a non-existent job.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testUpdateNonExistent() {
- every { jobService.updateState(1, any(), any()) } returns null
-
- Given {
- body(Job.Update(JobState.PENDING))
- contentType(ContentType.JSON)
- } When {
- post("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to update a job.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testUpdateState() {
- every { jobService.updateState(1, any(), any()) } returns dummyJob.copy(state = JobState.CLAIMED)
-
- Given {
- body(Job.Update(JobState.CLAIMED))
- contentType(ContentType.JSON)
- } When {
- post("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("state", equalTo(JobState.CLAIMED.toString()))
- }
- }
-
- /**
- * Test that tries to update a job with invalid input.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testUpdateInvalidInput() {
- Given {
- body("""{ "test": "test" }""")
- contentType(ContentType.JSON)
- } When {
- post("/1")
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioResourceTest.kt
deleted file mode 100644
index f74efbca..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioResourceTest.kt
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.quarkus.test.security.TestSecurity
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Given
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.PortfolioService
-import org.opendc.web.proto.Targets
-import org.opendc.web.proto.user.Portfolio
-import org.opendc.web.proto.user.Project
-import org.opendc.web.proto.user.ProjectRole
-import java.time.Instant
-
-/**
- * Test suite for [PortfolioResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(PortfolioResource::class)
-class PortfolioResourceTest {
- @InjectMock
- private lateinit var portfolioService: PortfolioService
-
- /**
- * Dummy project and portfolio
- */
- private val dummyProject = Project(1, "test", Instant.now(), Instant.now(), ProjectRole.OWNER)
- private val dummyPortfolio = Portfolio(1, 1, dummyProject, "test", Targets(emptySet(), 1), emptyList())
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(portfolioService, PortfolioService::class.java)
- }
-
- /**
- * Test that tries to obtain the list of portfolios belonging to a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetForProject() {
- every { portfolioService.findAll("testUser", 1) } returns emptyList()
-
- Given {
- pathParam("project", "1")
- } When {
- get()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to create a topology for a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateNonExistent() {
- every { portfolioService.create("testUser", 1, any()) } returns null
-
- Given {
- pathParam("project", "1")
-
- body(Portfolio.Create("test", Targets(emptySet(), 1)))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to create a portfolio for a scenario.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreate() {
- every { portfolioService.create("testUser", 1, any()) } returns dummyPortfolio
-
- Given {
- pathParam("project", "1")
-
- body(Portfolio.Create("test", Targets(emptySet(), 1)))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", Matchers.equalTo(1))
- body("name", Matchers.equalTo("test"))
- }
- }
-
- /**
- * Test to create a portfolio with an empty body.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateEmpty() {
- Given {
- pathParam("project", "1")
-
- body("{}")
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to create a portfolio with a blank name.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateBlankName() {
- Given {
- pathParam("project", "1")
-
- body(Portfolio.Create("", Targets(emptySet(), 1)))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a portfolio without token.
- */
- @Test
- fun testGetWithoutToken() {
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(401)
- }
- }
-
- /**
- * Test that tries to obtain a portfolio with an invalid scope.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetInvalidToken() {
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(403)
- }
- }
-
- /**
- * Test that tries to obtain a non-existent portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetNonExisting() {
- every { portfolioService.findOne("testUser", 1, 1) } returns null
-
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetExisting() {
- every { portfolioService.findOne("testUser", 1, 1) } returns dummyPortfolio
-
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", Matchers.equalTo(1))
- }
- }
-
- /**
- * Test to delete a non-existent portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDeleteNonExistent() {
- every { portfolioService.delete("testUser", 1, 1) } returns null
-
- Given {
- pathParam("project", "1")
- } When {
- delete("/1")
- } Then {
- statusCode(404)
- }
- }
-
- /**
- * Test to delete a portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDelete() {
- every { portfolioService.delete("testUser", 1, 1) } returns dummyPortfolio
-
- Given {
- pathParam("project", "1")
- } When {
- delete("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResourceTest.kt
deleted file mode 100644
index dbafa8c0..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/PortfolioScenarioResourceTest.kt
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.quarkus.test.security.TestSecurity
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Given
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.ScenarioService
-import org.opendc.web.proto.*
-import org.opendc.web.proto.user.*
-import java.time.Instant
-
-/**
- * Test suite for [PortfolioScenarioResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(PortfolioScenarioResource::class)
-class PortfolioScenarioResourceTest {
- @InjectMock
- private lateinit var scenarioService: ScenarioService
-
- /**
- * Dummy values
- */
- private val dummyProject = Project(0, "test", Instant.now(), Instant.now(), ProjectRole.OWNER)
- private val dummyPortfolio = Portfolio.Summary(1, 1, "test", Targets(emptySet()))
- private val dummyJob = Job(1, JobState.PENDING, Instant.now(), Instant.now(), null)
- private val dummyTrace = Trace("bitbrains", "Bitbrains", "vm")
- private val dummyTopology = Topology.Summary(1, 1, "test", Instant.now(), Instant.now())
- private val dummyScenario = Scenario(
- 1,
- 1,
- dummyProject,
- dummyPortfolio,
- "test",
- Workload(dummyTrace, 1.0),
- dummyTopology,
- OperationalPhenomena(false, false),
- "test",
- dummyJob
- )
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(scenarioService, ScenarioService::class.java)
- }
-
- /**
- * Test that tries to obtain a portfolio without token.
- */
- @Test
- fun testGetWithoutToken() {
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
- } When {
- get()
- } Then {
- statusCode(401)
- }
- }
-
- /**
- * Test that tries to obtain a portfolio with an invalid scope.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetInvalidToken() {
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
- } When {
- get()
- } Then {
- statusCode(403)
- }
- }
-
- /**
- * Test that tries to obtain a non-existent portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGet() {
- every { scenarioService.findAll("testUser", 1, 1) } returns emptyList()
-
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
- } When {
- get()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to create a scenario for a portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateNonExistent() {
- every { scenarioService.create("testUser", 1, any(), any()) } returns null
-
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
-
- body(Scenario.Create("test", Workload.Spec("test", 1.0), 1, OperationalPhenomena(false, false), "test"))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to create a scenario for a portfolio.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreate() {
- every { scenarioService.create("testUser", 1, 1, any()) } returns dummyScenario
-
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
-
- body(Scenario.Create("test", Workload.Spec("test", 1.0), 1, OperationalPhenomena(false, false), "test"))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", Matchers.equalTo(1))
- body("name", Matchers.equalTo("test"))
- }
- }
-
- /**
- * Test to create a project with an empty body.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateEmpty() {
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
-
- body("{}")
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to create a project with a blank name.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateBlankName() {
- Given {
- pathParam("project", "1")
- pathParam("portfolio", "1")
-
- body(Scenario.Create("", Workload.Spec("test", 1.0), 1, OperationalPhenomena(false, false), "test"))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ProjectResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ProjectResourceTest.kt
deleted file mode 100644
index bcbcbab1..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ProjectResourceTest.kt
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.quarkus.test.security.TestSecurity
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Given
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers.equalTo
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.ProjectService
-import org.opendc.web.proto.user.Project
-import org.opendc.web.proto.user.ProjectRole
-import java.time.Instant
-
-/**
- * Test suite for [ProjectResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(ProjectResource::class)
-class ProjectResourceTest {
- @InjectMock
- private lateinit var projectService: ProjectService
-
- /**
- * Dummy values.
- */
- private val dummyProject = Project(0, "test", Instant.now(), Instant.now(), ProjectRole.OWNER)
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(projectService, ProjectService::class.java)
- }
-
- /**
- * Test that tries to obtain all projects without token.
- */
- @Test
- fun testGetAllWithoutToken() {
- When {
- get()
- } Then {
- statusCode(401)
- }
- }
-
- /**
- * Test that tries to obtain all projects with an invalid scope.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetAllWithInvalidScope() {
- When {
- get()
- } Then {
- statusCode(403)
- }
- }
-
- /**
- * Test that tries to obtain all project for a user.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetAll() {
- val projects = listOf(dummyProject)
- every { projectService.findWithUser("testUser") } returns projects
-
- When {
- get()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("get(0).name", equalTo("test"))
- }
- }
-
- /**
- * Test that tries to obtain a non-existent project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetNonExisting() {
- every { projectService.findWithUser("testUser", 1) } returns null
-
- When {
- get("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a job.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetExisting() {
- every { projectService.findWithUser("testUser", 1) } returns dummyProject
-
- When {
- get("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", equalTo(0))
- }
- }
-
- /**
- * Test that tries to create a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreate() {
- every { projectService.createForUser("testUser", "test") } returns dummyProject
-
- Given {
- body(Project.Create("test"))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", equalTo(0))
- body("name", equalTo("test"))
- }
- }
-
- /**
- * Test to create a project with an empty body.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateEmpty() {
- Given {
- body("{}")
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to create a project with a blank name.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateBlankName() {
- Given {
- body(Project.Create(""))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to delete a non-existent project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDeleteNonExistent() {
- every { projectService.deleteWithUser("testUser", 1) } returns null
-
- When {
- delete("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to delete a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDelete() {
- every { projectService.deleteWithUser("testUser", 1) } returns dummyProject
-
- When {
- delete("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to delete a project which the user does not own.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDeleteNonOwner() {
- every { projectService.deleteWithUser("testUser", 1) } throws IllegalArgumentException("User does not own project")
-
- When {
- delete("/1")
- } Then {
- statusCode(403)
- contentType(ContentType.JSON)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ScenarioResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ScenarioResourceTest.kt
deleted file mode 100644
index 65e6e9a1..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/ScenarioResourceTest.kt
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.quarkus.test.security.TestSecurity
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Given
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.ScenarioService
-import org.opendc.web.proto.*
-import org.opendc.web.proto.user.*
-import java.time.Instant
-
-/**
- * Test suite for [ScenarioResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(ScenarioResource::class)
-class ScenarioResourceTest {
- @InjectMock
- private lateinit var scenarioService: ScenarioService
-
- /**
- * Dummy values
- */
- private val dummyProject = Project(0, "test", Instant.now(), Instant.now(), ProjectRole.OWNER)
- private val dummyPortfolio = Portfolio.Summary(1, 1, "test", Targets(emptySet()))
- private val dummyJob = Job(1, JobState.PENDING, Instant.now(), Instant.now(), null)
- private val dummyTrace = Trace("bitbrains", "Bitbrains", "vm")
- private val dummyTopology = Topology.Summary(1, 1, "test", Instant.now(), Instant.now())
- private val dummyScenario = Scenario(
- 1,
- 1,
- dummyProject,
- dummyPortfolio,
- "test",
- Workload(dummyTrace, 1.0),
- dummyTopology,
- OperationalPhenomena(false, false),
- "test",
- dummyJob
- )
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(scenarioService, ScenarioService::class.java)
- }
-
- /**
- * Test that tries to obtain a scenario without token.
- */
- @Test
- fun testGetWithoutToken() {
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(401)
- }
- }
-
- /**
- * Test that tries to obtain a scenario with an invalid scope.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetInvalidToken() {
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(403)
- }
- }
-
- /**
- * Test that tries to obtain a non-existent scenario.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetNonExisting() {
- every { scenarioService.findOne("testUser", 1, 1) } returns null
-
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a scenario.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetExisting() {
- every { scenarioService.findOne("testUser", 1, 1) } returns dummyScenario
-
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", Matchers.equalTo(1))
- }
- }
-
- /**
- * Test to delete a non-existent scenario.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDeleteNonExistent() {
- every { scenarioService.delete("testUser", 1, 1) } returns null
-
- Given {
- pathParam("project", "1")
- } When {
- delete("/1")
- } Then {
- statusCode(404)
- }
- }
-
- /**
- * Test to delete a scenario.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDelete() {
- every { scenarioService.delete("testUser", 1, 1) } returns dummyScenario
-
- Given {
- pathParam("project", "1")
- } When {
- delete("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-}
diff --git a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/TopologyResourceTest.kt b/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/TopologyResourceTest.kt
deleted file mode 100644
index ececeaca..00000000
--- a/opendc-web/opendc-web-api/src/test/kotlin/org/opendc/web/api/rest/user/TopologyResourceTest.kt
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 2022 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.api.rest.user
-
-import io.mockk.every
-import io.quarkiverse.test.junit.mockk.InjectMock
-import io.quarkus.test.common.http.TestHTTPEndpoint
-import io.quarkus.test.junit.QuarkusMock
-import io.quarkus.test.junit.QuarkusTest
-import io.quarkus.test.security.TestSecurity
-import io.restassured.http.ContentType
-import io.restassured.module.kotlin.extensions.Given
-import io.restassured.module.kotlin.extensions.Then
-import io.restassured.module.kotlin.extensions.When
-import org.hamcrest.Matchers
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.opendc.web.api.service.TopologyService
-import org.opendc.web.proto.user.Project
-import org.opendc.web.proto.user.ProjectRole
-import org.opendc.web.proto.user.Topology
-import java.time.Instant
-
-/**
- * Test suite for [TopologyResource].
- */
-@QuarkusTest
-@TestHTTPEndpoint(TopologyResource::class)
-class TopologyResourceTest {
- @InjectMock
- private lateinit var topologyService: TopologyService
-
- /**
- * Dummy project and topology.
- */
- private val dummyProject = Project(1, "test", Instant.now(), Instant.now(), ProjectRole.OWNER)
- private val dummyTopology = Topology(1, 1, dummyProject, "test", emptyList(), Instant.now(), Instant.now())
-
- @BeforeEach
- fun setUp() {
- QuarkusMock.installMockForType(topologyService, TopologyService::class.java)
- }
-
- /**
- * Test that tries to obtain the list of topologies belonging to a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetForProject() {
- every { topologyService.findAll("testUser", 1) } returns emptyList()
-
- Given {
- pathParam("project", "1")
- } When {
- get()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to create a topology for a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateNonExistent() {
- every { topologyService.create("testUser", 1, any()) } returns null
-
- Given {
- pathParam("project", "1")
-
- body(Topology.Create("test", emptyList()))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to create a topology for a project.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreate() {
- every { topologyService.create("testUser", 1, any()) } returns dummyTopology
-
- Given {
- pathParam("project", "1")
-
- body(Topology.Create("test", emptyList()))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", Matchers.equalTo(1))
- body("name", Matchers.equalTo("test"))
- }
- }
-
- /**
- * Test to create a topology with an empty body.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateEmpty() {
- Given {
- pathParam("project", "1")
-
- body("{}")
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to create a topology with a blank name.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testCreateBlankName() {
- Given {
- pathParam("project", "1")
-
- body(Topology.Create("", emptyList()))
- contentType(ContentType.JSON)
- } When {
- post()
- } Then {
- statusCode(400)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a topology without token.
- */
- @Test
- fun testGetWithoutToken() {
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(401)
- }
- }
-
- /**
- * Test that tries to obtain a topology with an invalid scope.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["runner"])
- fun testGetInvalidToken() {
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(403)
- }
- }
-
- /**
- * Test that tries to obtain a non-existent topology.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetNonExisting() {
- every { topologyService.findOne("testUser", 1, 1) } returns null
-
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(404)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test that tries to obtain a topology.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testGetExisting() {
- every { topologyService.findOne("testUser", 1, 1) } returns dummyTopology
-
- Given {
- pathParam("project", "1")
- } When {
- get("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- body("id", Matchers.equalTo(1))
- println(extract().asPrettyString())
- }
- }
-
- /**
- * Test to delete a non-existent topology.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testUpdateNonExistent() {
- every { topologyService.update("testUser", any(), any(), any()) } returns null
-
- Given {
- pathParam("project", "1")
- body(Topology.Update(emptyList()))
- contentType(ContentType.JSON)
- } When {
- put("/1")
- } Then {
- statusCode(404)
- }
- }
-
- /**
- * Test to update a topology.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testUpdate() {
- every { topologyService.update("testUser", any(), any(), any()) } returns dummyTopology
-
- Given {
- pathParam("project", "1")
- body(Topology.Update(emptyList()))
- contentType(ContentType.JSON)
- } When {
- put("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-
- /**
- * Test to delete a non-existent topology.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDeleteNonExistent() {
- every { topologyService.delete("testUser", 1, 1) } returns null
-
- Given {
- pathParam("project", "1")
- } When {
- delete("/1")
- } Then {
- statusCode(404)
- }
- }
-
- /**
- * Test to delete a topology.
- */
- @Test
- @TestSecurity(user = "testUser", roles = ["openid"])
- fun testDelete() {
- every { topologyService.delete("testUser", 1, 1) } returns dummyTopology
-
- Given {
- pathParam("project", "1")
- } When {
- delete("/1")
- } Then {
- statusCode(200)
- contentType(ContentType.JSON)
- }
- }
-}