summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2017-09-28 03:27:36 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2017-09-28 03:27:36 +0200
commitd6d9d37abf17071ff050e45ea37c693e659a4e98 (patch)
tree248d11c478ee71a6bc47cf3f5c73870c73b4c210
parent23a476613b000bf04194ec2962d270fa3cabfc5d (diff)
Implement JPA integration
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt5
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt)2
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt2
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt11
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt40
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Traversable.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/extension/topology/Traversable.kt)4
-rw-r--r--opendc-integration-jpa/build.gradle16
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt62
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt66
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt58
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt66
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt60
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt53
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt58
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt59
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt45
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt53
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt40
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt52
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt50
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt36
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt34
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt45
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt141
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt49
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt44
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt149
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt73
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt52
-rw-r--r--opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt87
-rw-r--r--opendc-integration-jpa/src/main/resources/META-INF/persistence.xml44
-rw-r--r--opendc-integration-jpa/src/main/resources/jpa/schema.xml325
-rw-r--r--opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt17
-rw-r--r--opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt89
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/FifoScheduler.kt)18
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/Scheduler.kt)9
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/SrtfScheduler.kt)9
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/Job.kt)29
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/Task.kt)72
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt37
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/User.kt)21
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt18
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt4
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt7
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt8
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt8
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt32
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt8
-rw-r--r--opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt5
49 files changed, 2065 insertions, 207 deletions
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt
index 32b45ca2..d07c3ba0 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt
@@ -62,6 +62,11 @@ interface Simulation {
val clock: Clock
/**
+ * The observable state of an [Entity] in simulation, which is provided by the simulation context.
+ */
+ val <E : Entity<S>, S> E.state: S
+
+ /**
* Step through one cycle in the simulation. This method will process all events in a single tick, update the
* internal clock and then return the control to the user.
*/
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt
index 2f36e6b7..66c33341 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.sampler
+package nl.atlarge.opendc.kernel.sampler
/**
* A sampler generates data points (samples) of the simulation based on the events that occur to [Entity] instances that
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt
index ef9e0396..74b046de 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt
@@ -55,7 +55,7 @@ internal class AdjacencyListTopologyBuilder : TopologyBuilder {
*
* @return The graph built from this builder.
*/
- override fun build(): MutableTopology = AdjacencyListTopology()
+ override fun create(): MutableTopology = AdjacencyListTopology()
}
/**
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt
index d5a57549..bb9c7e8e 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt
@@ -29,19 +29,12 @@ package nl.atlarge.opendc.topology
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-interface TopologyBuilder {
+interface TopologyBuilder : TopologyFactory {
/**
* Construct a [Topology] from the given block and return it.
*
* @param block The block to construct the topology.
* @return The topology that has been built.
*/
- fun construct(block: MutableTopology.() -> Unit): MutableTopology = build().apply(block)
-
- /**
- * Build a [Topology] instance from the current state of this builder.
- *
- * @return The graph built from this builder.
- */
- fun build(): MutableTopology
+ fun construct(block: MutableTopology.() -> Unit): MutableTopology = create().apply(block)
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt
new file mode 100644
index 00000000..42b30a94
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt
@@ -0,0 +1,40 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.topology
+
+/**
+ * An interface for producing [Topology] instances. Implementors of this interface provide a way of generating a
+ * topology based on the state of the factory.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface TopologyFactory {
+ /**
+ * Create a [MutableTopology] instance.
+ *
+ * @return A mutable topology.
+ */
+ fun create(): MutableTopology
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/extension/topology/Traversable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Traversable.kt
index b5b5ec82..e57060ed 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/extension/topology/Traversable.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Traversable.kt
@@ -22,9 +22,7 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.extension.topology
-
-import nl.atlarge.opendc.topology.Edge
+package nl.atlarge.opendc.topology
/**
* Filter a [Set] of [Edge]s based on the tag of the edges and return the origin nodes casted to type `T`.
diff --git a/opendc-integration-jpa/build.gradle b/opendc-integration-jpa/build.gradle
index dd4cce8c..a3aa9dc8 100644
--- a/opendc-integration-jpa/build.gradle
+++ b/opendc-integration-jpa/build.gradle
@@ -34,6 +34,7 @@ buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-RC3'
}
@@ -41,6 +42,7 @@ buildscript {
apply plugin: 'java'
apply plugin: 'kotlin'
+apply plugin: 'kotlin-jpa'
apply plugin: 'org.jetbrains.dokka'
apply plugin: 'org.junit.platform.gradle.plugin'
@@ -77,10 +79,14 @@ repositories {
dependencies {
compile project(':opendc-core')
- compile "org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final"
+ compile project(':opendc-stdlib')
+ compile project(':opendc-omega')
+ compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final'
+ runtime 'org.slf4j:slf4j-simple:1.7.25'
+ runtime 'org.hibernate:hibernate-core:5.2.5.Final'
+ runtime 'mysql:mysql-connector-java:5.1.13'
- testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-RC3"
- testRuntime "org.junit.jupiter:junit-jupiter-engine:5.0.0-RC3"
- testCompile "org.junit.platform:junit-platform-launcher:1.0.0-RC3"
- testCompile "org.slf4j:slf4j-simple:1.7.25"
+ testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0-RC3'
+ testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.0.0-RC3'
+ testCompile 'org.junit.platform:junit-platform-launcher:1.0.0-RC3'
}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt
new file mode 100644
index 00000000..11d5836e
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt
@@ -0,0 +1,62 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.converter
+
+import javax.persistence.AttributeConverter
+
+/**
+ * An internal [AttributeConverter] that maps the values _PARALLEL_ and _SEQUENTIAL_ to a
+ * boolean value indicating whether a task is parallelizable.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class ParallelizableConverter : AttributeConverter<Boolean, String> {
+ /**
+ * Converts the data stored in the database column into the
+ * value to be stored in the entity attribute.
+ * Note that it is the responsibility of the converter writer to
+ * specify the correct dbData type for the corresponding column
+ * for use by the JDBC driver: i.e., persistence providers are
+ * not expected to do such type conversion.
+ *
+ * @param dbData the data from the database column to be converted
+ * @return the converted value to be stored in the entity attribute
+ */
+ override fun convertToEntityAttribute(dbData: String?): Boolean = when(dbData?.toUpperCase()) {
+ "SEQUENTIAL" -> false
+ "PARALLEL" -> true
+ else -> false
+ }
+
+ /**
+ * Converts the value stored in the entity attribute into the
+ * data representation to be stored in the database.
+ *
+ * @param attribute the entity attribute value to be converted
+ * @return the converted data to be stored in the database column
+ */
+ override fun convertToDatabaseColumn(attribute: Boolean?): String =
+ if (attribute == true) "PARALLEL" else "SEQUENTIAL"
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt
new file mode 100644
index 00000000..95027440
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt
@@ -0,0 +1,66 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.converter
+
+import nl.atlarge.opendc.platform.scheduler.FifoScheduler
+import nl.atlarge.opendc.platform.scheduler.Scheduler
+import nl.atlarge.opendc.platform.scheduler.SrtfScheduler
+import javax.persistence.AttributeConverter
+
+/**
+ * An internal [AttributeConverter] that maps a name of a scheduler to the actual scheduler implementation.
+ * The converter currently chooses between the following two schedulers:
+ * - [FifoScheduler] (default)
+ * - [SrtfScheduler]
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class SchedulerConverter : AttributeConverter<Scheduler, String> {
+ /**
+ * Converts the data stored in the database column into the
+ * value to be stored in the entity attribute.
+ * Note that it is the responsibility of the converter writer to
+ * specify the correct dbData type for the corresponding column
+ * for use by the JDBC driver: i.e., persistence providers are
+ * not expected to do such type conversion.
+ *
+ * @param dbData the data from the database column to be converted
+ * @return the converted value to be stored in the entity attribute
+ */
+ override fun convertToEntityAttribute(dbData: String?): Scheduler = when(dbData?.toUpperCase()) {
+ "SRTF" -> SrtfScheduler()
+ else -> FifoScheduler()
+ }
+
+ /**
+ * Converts the value stored in the entity attribute into the
+ * data representation to be stored in the database.
+ *
+ * @param attribute the entity attribute value to be converted
+ * @return the converted data to be stored in the database column
+ */
+ override fun convertToDatabaseColumn(attribute: Scheduler?): String =
+ attribute?.name?.toUpperCase() ?: "FIFO"
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt
new file mode 100644
index 00000000..b775eb6e
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt
@@ -0,0 +1,58 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.topology.machine.Cpu
+import javax.persistence.Entity
+
+/**
+ * A cpu entity in the persistent schema.
+ *
+ * @property id The unique identifier of the cpu.
+ * @property manufacturer The manufacturer of the cpu.
+ * @property family The family of the cpu.
+ * @property generation The generation of the cpu.
+ * @property model The model of the cpu.
+ * @property clockRate The clock rate of the cpu.
+ * @property cores The amount of cores in the gpu.
+ * @property energyConsumption The energy consumption of the cpu in Watt.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Cpu(
+ val id: Int,
+ val manufacturer: String,
+ val family: String,
+ val generation: String,
+ val model: String,
+ override val clockRate: Int,
+ override val cores: Int,
+ override val energyConsumption: Double
+) : Cpu {
+ /**
+ * The initial state of the entity.
+ */
+ override val initialState = Unit
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt
new file mode 100644
index 00000000..26cf9706
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt
@@ -0,0 +1,66 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.kernel.time.Duration
+import nl.atlarge.opendc.platform.scheduler.Scheduler
+import nl.atlarge.opendc.topology.container.Datacenter
+import javax.persistence.Entity
+
+/**
+ * A datacenter entity in the persistent schema.
+ *
+ * @property id The unique identifier of the datacenter.
+ * @property rooms The rooms in the datacenter.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Datacenter(
+ val id: Int,
+ val rooms: Set<Room>
+): Datacenter {
+ /**
+ * Construct a datacenter. We need this useless constructor in order for Kotlin correctly initialise the
+ * constant fields of the class.
+ */
+ private constructor() : this(-1, emptySet())
+
+ /**
+ * The task scheduler the datacenter uses.
+ */
+ override lateinit var scheduler: Scheduler
+ internal set
+
+ /**
+ * The interval at which task will be (re)scheduled.
+ * We set this to a fixed constant since the database provides no way of configuring this.
+ */
+ override val interval: Duration = 50
+
+ /**
+ * The initial state of the datacenter.
+ */
+ override val initialState = Unit
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt
new file mode 100644
index 00000000..0b352cb4
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt
@@ -0,0 +1,60 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.kernel.time.Instant
+import nl.atlarge.opendc.platform.Experiment
+import nl.atlarge.opendc.platform.scheduler.Scheduler
+import nl.atlarge.opendc.platform.workload.Trace
+import javax.persistence.Entity
+
+/**
+ * An experiment definition for the OpenDC database schema.
+ *
+ * @property id The identifier of the experiment.
+ * @property name The name of the experiment.
+ * @property scheduler The scheduler used in the experiment.
+ * @property trace The trace used for the simulation.
+ * @property path The path of the experiment.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Experiment(
+ val id: Int,
+ val name: String,
+ val scheduler: Scheduler,
+ val trace: Trace,
+ val path: Path
+) {
+ /**
+ * The state of the experiment.
+ */
+ var state: ExperimentState = ExperimentState.QUEUED
+
+ /**
+ * The last tick that has been simulated.
+ */
+ var last: Instant = 0
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt
new file mode 100644
index 00000000..96fc112c
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt
@@ -0,0 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+/**
+ * Enumerations of the states an [Experiment] can assume.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+enum class ExperimentState {
+ /**
+ * This state indicates the experiment has been queued for simulation, but has not yet started.
+ */
+ QUEUED,
+
+ /**
+ * This state indicates the experiment has been claimed by a simulator for simulation, but
+ * not yet started.
+ */
+ CLAIMED,
+
+ /**
+ * This state indicates the experiment is currently in simulation.
+ */
+ SIMULATING,
+
+ /**
+ * This state indicates the experiment has finished simulating.
+ */
+ FINISHED,
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt
new file mode 100644
index 00000000..94625242
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt
@@ -0,0 +1,58 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.topology.machine.Gpu
+import javax.persistence.Entity
+
+/**
+ * A gpu entity in the persistent schema.
+ *
+ * @property id The unique identifier of the gpu.
+ * @property manufacturer The manufacturer of the gpu.
+ * @property family The family of the gpu.
+ * @property generation The generation of the gpu.
+ * @property model The model of the gpu.
+ * @property clockRate The clock rate of the gpu.
+ * @property cores The amount of cores in the gpu.
+ * @property energyConsumption The energy consumption of the gpu in Watt.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Gpu(
+ val id: Int,
+ val manufacturer: String,
+ val family: String,
+ val generation: String,
+ val model: String,
+ override val clockRate: Int,
+ override val cores: Int,
+ override val energyConsumption: Double
+) : Gpu {
+ /**
+ * The initial state of the entity.
+ */
+ override val initialState = Unit
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt
new file mode 100644
index 00000000..394cf478
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt
@@ -0,0 +1,59 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.platform.workload.Job
+import nl.atlarge.opendc.platform.workload.Task
+import nl.atlarge.opendc.platform.workload.User
+import javax.persistence.*
+
+/**
+ * A [Job] backed by the JPA API and an underlying database connection.
+ *
+ * @property id The unique identifier of the job.
+ * @property tasks The collection of tasks the job consists of.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Job(
+ override val id: Int,
+ override val tasks: Set<Task>
+) : Job {
+ /**
+ * The owner of the job, which is a singleton, since the database has no
+ * concept of ownership yet.
+ */
+ override val owner: User = object : User {
+ /**
+ * The unique identifier of the user.
+ */
+ override val id: Int = 0
+
+ /**
+ * The name of this user.
+ */
+ override val name: String = "admin"
+ }
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt
new file mode 100644
index 00000000..4071b342
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt
@@ -0,0 +1,45 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.topology.machine.Machine
+import javax.persistence.Entity
+
+/**
+ * A machine entity in the persistent schema.
+ *
+ * @property id The unique identifier of the machine.
+ * @property position The position of the machine in the rack.
+ * @property cpus The CPUs in the machine.
+ * @property gpus The GPUs in the machine.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Machine(
+ val id: Int,
+ val position: Int,
+ val cpus: Set<Cpu>,
+ val gpus: Set<Gpu>
+): Machine()
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt
new file mode 100644
index 00000000..23efe888
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt
@@ -0,0 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.kernel.time.Instant
+import javax.persistence.Entity
+
+/**
+ * The state of a [Machine].
+ *
+ * @property id The unique identifier of the state.
+ * @property machine The machine of the state.
+ * @property task The task the machine has been assigned.
+ * @property experiment The experiment the machine is running in.
+ * @property time The current moment in time.
+ * @property temperature The temperature of the machine.
+ * @property memoryUsage The memory usage of the machine.
+ * @property load The load of the machine.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class MachineState(
+ val id: Int,
+ val machine: Machine,
+ val task: Task?,
+ val experiment: Experiment,
+ val time: Instant,
+ val temperature: Double,
+ val memoryUsage: Int,
+ val load: Double
+)
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt
new file mode 100644
index 00000000..ccf3b6e8
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt
@@ -0,0 +1,40 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import javax.persistence.Entity
+
+/**
+ * A [Path] holds all sections of the parent experiment.
+ *
+ * @property id The unique identifier of the path.
+ * @property sections The sections of the path.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+open class Path(
+ val id: Int,
+ val sections: List<Section>
+)
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt
new file mode 100644
index 00000000..2d2099a2
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt
@@ -0,0 +1,52 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.topology.container.Rack
+import javax.persistence.Entity
+
+/**
+ * A rack entity in a room in the persistent schema.
+ *
+ * @property id The unique identifier of the rack.
+ * @property name The name of the rack.
+ * @property capacity The capacity of the rack in terms of units.
+ * @property powerCapacity The power capacity of the rack in Watt.
+ * @property machines The machines in the rack.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+class Rack(
+ id: Int,
+ val name: String,
+ val capacity: Int,
+ val powerCapacity: Int,
+ val machines: List<Machine>
+): RoomObject(id), Rack {
+ /**
+ * The initial state of the entity.
+ */
+ override val initialState = Unit
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt
new file mode 100644
index 00000000..f3b7ae06
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt
@@ -0,0 +1,50 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.topology.container.Room
+import javax.persistence.Entity
+
+/**
+ * A room entity in the persistent schema.
+ *
+ * @property id The unique identifier of the room.
+ * @property name The name of the room.
+ * @property type The type of the room.
+ * @property objects The objects in the room.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Room(
+ val id: Int,
+ val name: String,
+ val type: RoomType,
+ val objects: Set<RoomObject>
+): Room {
+ /**
+ * The initial state of the entity.
+ */
+ override val initialState = Unit
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt
new file mode 100644
index 00000000..0e9fb84f
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt
@@ -0,0 +1,36 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import javax.persistence.Entity
+
+/**
+ * An object in a room.
+ *
+ * @property id The unique identifier of the room.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+abstract class RoomObject(val id: Int)
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt
new file mode 100644
index 00000000..5e138947
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt
@@ -0,0 +1,34 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+/**
+ * This enumeration defines the room types available in the OpenDC frontend.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+enum class RoomType {
+ COOLING, HALLWAY, OFFICE, POWER, SERVER
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt
new file mode 100644
index 00000000..e3b8c350
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt
@@ -0,0 +1,45 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.kernel.time.Instant
+import javax.persistence.Entity
+
+/**
+ * A [Section] holds a datacenter and the tick on which the parent experiment should
+ * switch to this section.
+ *
+ * @property id The unique identifier of the section.
+ * @property datacenter The datacenter of this section.
+ * @property startTime The position in time when the experiment should start using the
+ * topology of this section.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Section(
+ val id: Int,
+ val datacenter: Datacenter,
+ val startTime: Instant
+)
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt
new file mode 100644
index 00000000..500c7e99
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt
@@ -0,0 +1,141 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.kernel.Context
+import nl.atlarge.opendc.kernel.time.Instant
+import nl.atlarge.opendc.platform.workload.Task
+import nl.atlarge.opendc.topology.container.Datacenter
+import nl.atlarge.opendc.topology.machine.Machine
+import javax.persistence.*
+
+/**
+ * A [Task] backed by the JPA API and an underlying database connection.
+ *
+ * @property id The unique identifier of the job.
+ * @property flops The total amount of flops for the task.
+ * @property dependency A dependency on another task.
+ * @property parallelizable A flag to indicate the task is parallelizable.
+ * @property startTime The start time in the simulation.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Task(
+ override val id: Int,
+ override val flops: Long,
+ private val dependency: Task?,
+ override val parallelizable: Boolean,
+ val startTime: Instant
+) : Task {
+ /**
+ * The dependencies of the task.
+ */
+ override val dependencies: Set<Task>
+ get() {
+ if (_dependencies != null)
+ return _dependencies!!
+ _dependencies = dependency?.let(::setOf) ?: emptySet()
+ return _dependencies!!
+ }
+
+ /**
+ * The dependencies set cache.
+ */
+ private var _dependencies: Set<Task>? = null
+
+ /**
+ * The remaining amount of flops to compute.
+ */
+ override var remaining: Long
+ get() {
+ if (_remaining == null)
+ _remaining = flops
+ return _remaining!!
+ }
+ private set(value) { _remaining = value }
+ private var _remaining: Long? = -1
+
+ /**
+ * A flag to indicate the task has been accepted by the datacenter.
+ */
+ override var accepted: Boolean = false
+ private set
+
+ /**
+ * A flag to indicate the task has been started.
+ */
+ override var started: Boolean = false
+ private set
+
+ /**
+ * A flag to indicate whether the task is finished.
+ */
+ override var finished: Boolean = false
+ private set
+
+ /**
+ * Accept the task into the scheduling queue.
+ */
+ override fun Context<Datacenter>.accept() {
+ accepted = true
+ }
+
+ /**
+ * Start a task.
+ */
+ override fun Context<Machine>.start() {
+ started = true
+ }
+
+ /**
+ * Consume the given amount of flops of this task.
+ *
+ * @param flops The total amount of flops to consume.
+ */
+ override fun Context<Machine>.consume(flops: Long) {
+ if (finished)
+ return
+ if (remaining <= flops) {
+ remaining = 0
+ } else {
+ remaining -= flops
+ }
+ }
+
+ /**
+ * Finalise the task.
+ */
+ override fun Context<Machine>.finalize() {
+ finished = true
+ }
+
+ /**
+ * Reset the task.
+ */
+ internal fun reset() {
+ remaining = flops
+ finished = false
+ }
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt
new file mode 100644
index 00000000..14441752
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt
@@ -0,0 +1,49 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.kernel.time.Instant
+import javax.persistence.Entity
+
+/**
+ * The state of a [Task].
+ *
+ * @property id The unique identifier of the state.
+ * @property task The task this is the state of.
+ * @property experiment The experiment the machine is running in.
+ * @property time The current moment in time.
+ * @property remaining The remaining flops for the task.
+ * @property cores The cores used for the task.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class TaskState(
+ val id: Int,
+ val task: Task,
+ val experiment: Experiment,
+ val time: Instant,
+ val remaining: Int,
+ val cores: Int
+)
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt
new file mode 100644
index 00000000..cd3d9348
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt
@@ -0,0 +1,44 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.integration.jpa.schema
+
+import nl.atlarge.opendc.platform.workload.Job
+import nl.atlarge.opendc.platform.workload.Trace
+import javax.persistence.Entity
+
+/**
+ * A [Trace] backed by the JPA API and an underlying database connection.
+ *
+ * @property id The unique identifier of the trace.
+ * @property name The name of the trace.
+ * @property jobs The collection of jobs for this trace.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Entity
+data class Trace(
+ val id: Int,
+ val name: String,
+ override val jobs: Set<Job>
+) : Trace
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt
new file mode 100644
index 00000000..4c284d1e
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt
@@ -0,0 +1,149 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.platform
+
+import mu.KotlinLogging
+import nl.atlarge.opendc.integration.jpa.schema.ExperimentState
+import nl.atlarge.opendc.integration.jpa.schema.MachineState
+import nl.atlarge.opendc.integration.jpa.schema.TaskState
+import nl.atlarge.opendc.integration.jpa.schema.Experiment as InternalExperiment
+import nl.atlarge.opendc.integration.jpa.schema.Task as InternalTask
+import nl.atlarge.opendc.kernel.Kernel
+import nl.atlarge.opendc.topology.JpaTopologyFactory
+import nl.atlarge.opendc.topology.container.Rack
+import nl.atlarge.opendc.topology.container.Room
+import nl.atlarge.opendc.topology.destinations
+import nl.atlarge.opendc.topology.machine.Machine
+import javax.persistence.EntityManager
+
+/**
+ * An [Experiment] backed by the JPA API and an underlying database connection.
+ *
+ * @property manager The entity manager for the database connection.
+ * @property experiment The internal experiment definition to use.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class JpaExperiment(val manager: EntityManager,
+ private val experiment: InternalExperiment): Experiment<Unit> {
+ /**
+ * The logging instance.
+ */
+ private val logger = KotlinLogging.logger {}
+
+ /**
+ * Run the experiment on the specified simulation [Kernel].
+ *
+ * @param kernel The simulation kernel to run the experiment.
+ * @throws IllegalStateException if the simulation is already running or finished.
+ */
+ override fun run(kernel: Kernel) {
+ if (experiment.state != ExperimentState.CLAIMED) {
+ throw IllegalStateException("The experiment is in illegal state ${experiment.state}")
+ }
+
+ // Set the simulation state
+ manager.run {
+ transaction.begin()
+ experiment.state = ExperimentState.SIMULATING
+ transaction.commit()
+ }
+ val section = experiment.path.sections.first()
+
+ // Important: initialise the scheduler of the datacenter
+ section.datacenter.scheduler = experiment.scheduler
+
+ val topology = JpaTopologyFactory(section).create()
+ val simulation = kernel.create(topology)
+ val trace = experiment.trace
+
+ logger.info { "Sending trace to kernel" }
+
+ // Schedule all messages in the trace
+ trace.jobs.forEach { job ->
+ job.tasks.forEach { task ->
+ if (task is InternalTask) {
+ task.reset()
+ simulation.schedule(task, section.datacenter, delay = task.startTime)
+ } else {
+ logger.warn { "Dropped invalid task $task" }
+ }
+ }
+ }
+
+ // Find all machines in the datacenter
+ val machines = topology.run {
+ section.datacenter.outgoingEdges.destinations<Room>("room").asSequence()
+ .flatMap { it.outgoingEdges.destinations<Rack>("rack").asSequence() }
+ .flatMap { it.outgoingEdges.destinations<Machine>("machine").asSequence() }.toList()
+ }
+
+ logger.info { "Starting simulation" }
+
+ while (trace.jobs.any { !it.finished }) {
+ simulation.run(simulation.clock.now + 1)
+
+ // Collect data of simulation cycle
+ manager.transaction.begin()
+ machines.forEach { machine ->
+ val state = simulation.run { machine.state }
+ val wrapped = MachineState(0,
+ machine as nl.atlarge.opendc.integration.jpa.schema.Machine,
+ state.task as nl.atlarge.opendc.integration.jpa.schema.Task?,
+ experiment,
+ simulation.clock.now,
+ state.temperature,
+ state.memory,
+ state.load
+ )
+ manager.persist(wrapped)
+ }
+
+ trace.jobs.asSequence()
+ .flatMap { it.tasks.asSequence() }
+ .forEach { task ->
+ val state = TaskState(0,
+ task as nl.atlarge.opendc.integration.jpa.schema.Task,
+ experiment,
+ simulation.clock.now,
+ task.remaining.toInt(),
+ 1
+ )
+ manager.persist(state)
+ }
+ manager.transaction.commit()
+
+ experiment.last = simulation.clock.now
+ }
+
+ // Set the experiment state
+ manager.run {
+ transaction.begin()
+ experiment.state = ExperimentState.FINISHED
+ transaction.commit()
+ }
+
+ logger.info { "Simulation done" }
+ }
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt
new file mode 100644
index 00000000..faa1a771
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt
@@ -0,0 +1,73 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.platform
+
+import nl.atlarge.opendc.integration.jpa.schema.Experiment as InternalExperiment
+import nl.atlarge.opendc.integration.jpa.schema.ExperimentState
+import javax.persistence.EntityManager
+
+/**
+ * A manager for [Experiment]s received from a JPA database.
+ *
+ * @property manager The JPA entity manager to retrieve entities from the database from.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class JpaExperimentManager(private val manager: EntityManager) {
+ /**
+ * The amount of experiments in the queue. This property makes a call to the database and does therefore not
+ * run in O(1) time.
+ */
+ val size: Int
+ get() {
+ return manager.createQuery("SELECT COUNT(e.id) FROM experiments e WHERE e.state = :s",
+ java.lang.Long::class.java)
+ .setParameter("s", ExperimentState.QUEUED)
+ .singleResult.toInt()
+ }
+
+ /**
+ * Poll an [Experiment] from the database and claim it.
+ *
+ * @return The experiment that has been polled from the database or `null` if there are no experiments in the
+ * queue.
+ */
+ fun poll(): Experiment<Unit>? {
+ manager.transaction.begin()
+ var experiment: InternalExperiment? = null
+ val results = manager.createQuery("SELECT e FROM experiments e WHERE e.state = :s",
+ InternalExperiment::class.java)
+ .setParameter("s", ExperimentState.QUEUED)
+ .setMaxResults(1)
+ .resultList
+
+
+ if (!results.isEmpty()) {
+ experiment = results.first()
+ experiment!!.state = ExperimentState.CLAIMED
+ }
+ manager.transaction.commit()
+ return experiment?.let { JpaExperiment(manager, it) }
+ }
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt
new file mode 100644
index 00000000..f95eb174
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt
@@ -0,0 +1,52 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.platform
+
+import mu.KotlinLogging
+import nl.atlarge.opendc.kernel.omega.OmegaKernel
+import javax.persistence.Persistence
+
+val logger = KotlinLogging.logger {}
+
+/**
+ * The main entry point of the program. This program polls experiments from a database and runs the
+ * simulation and reports the results back to the database.
+ *
+ * @param args The command line arguments of the program.
+ */
+fun main(args: Array<String>) {
+ val factory = Persistence.createEntityManagerFactory("opendc-frontend")
+ val manager = factory.createEntityManager()
+ val experiments = JpaExperimentManager(manager)
+
+ logger.info { "Waiting for enqueued experiments..." }
+ while (true) {
+ val experiment = experiments.poll()
+ experiment?.run {
+ logger.info { "Found experiment. Running simulating now..." }
+ run(OmegaKernel)
+ }
+ }
+}
diff --git a/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt
new file mode 100644
index 00000000..8def721e
--- /dev/null
+++ b/opendc-integration-jpa/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt
@@ -0,0 +1,87 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.topology
+
+import nl.atlarge.opendc.integration.jpa.schema.*
+
+/**
+ * A [TopologyFactory] that converts a [Section] of an experiment as defined by the API, into a proper [Topology].
+ *
+ * @property section The section to convert into a topology.
+ * @property builder A builder for a topology to use.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class JpaTopologyFactory(val section: Section, val builder: TopologyBuilder = AdjacencyList.builder()) : TopologyFactory {
+ /**
+ * Create a [MutableTopology] instance.
+ *
+ * @return A mutable topology.
+ */
+ override fun create(): MutableTopology = builder.construct {
+ val datacenter = section.datacenter
+ add(datacenter)
+ datacenter.rooms.forEach { room ->
+ add(room)
+ connect(datacenter, room, tag = "room")
+
+ room.objects.forEach { roomObject(room, it) }
+ }
+ }
+
+ /**
+ * Handle the objects in a room.
+ *
+ * @param obj The obj to handle.
+ */
+ private fun MutableTopology.roomObject(parent: Room, obj: RoomObject) = when(obj) {
+ is Rack -> rack(parent, obj)
+ else -> Unit
+ }
+
+ /**
+ * Handle a rack in a room.
+ *
+ * @param parent The parent of the rack.
+ * @param rack The rack to handle.
+ */
+ private fun MutableTopology.rack(parent: Room, rack: Rack) {
+ add(rack)
+ connect(parent, rack, tag = "rack")
+ rack.machines.forEach { machine ->
+ add(machine)
+ connect(rack, machine, tag = "machine")
+
+ machine.cpus.forEach { cpu ->
+ add(cpu)
+ connect(machine, cpu, tag = "cpu")
+ }
+
+ machine.gpus.forEach { gpu ->
+ add(gpu)
+ connect(machine, gpu, tag = "gpu")
+ }
+ }
+ }
+}
diff --git a/opendc-integration-jpa/src/main/resources/META-INF/persistence.xml b/opendc-integration-jpa/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 00000000..c997ab8d
--- /dev/null
+++ b/opendc-integration-jpa/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ MIT License
+ ~
+ ~ Copyright (c) 2017 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.
+ -->
+
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+ version="2.0">
+ <persistence-unit name="opendc-frontend">
+ <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+ <mapping-file>jpa/schema.xml</mapping-file>
+ <properties>
+ <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
+ <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/opendc" />
+ <property name="javax.persistence.jdbc.user" value="opendc" />
+ <property name="javax.persistence.jdbc.password" value="opendcpassword" />
+
+ <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
+ <property name="hibernate.show_sql" value="false" />
+ <property name="hibernate.hbm2ddl.auto" value="validate" />
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git a/opendc-integration-jpa/src/main/resources/jpa/schema.xml b/opendc-integration-jpa/src/main/resources/jpa/schema.xml
new file mode 100644
index 00000000..a14fb96d
--- /dev/null
+++ b/opendc-integration-jpa/src/main/resources/jpa/schema.xml
@@ -0,0 +1,325 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ MIT License
+ ~
+ ~ Copyright (c) 2017 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.
+ -->
+<entity-mappings version="2.1"
+ xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">
+
+ <package>nl.atlarge.opendc.integration.jpa.schema</package>
+
+ <entity class="Experiment" access="FIELD" name="experiments">
+ <convert converter="nl.atlarge.opendc.integration.jpa.converter.SchedulerConverter" attribute-name="scheduler" />
+ <attributes>
+ <id name="id" />
+
+ <basic name="name">
+ <column column-definition="text" />
+ </basic>
+
+ <basic name="state">
+ <column column-definition="text" />
+ <enumerated>STRING</enumerated>
+ </basic>
+
+ <basic name="last">
+ <column name="last_simulated_tick" column-definition="int(11)" />
+ </basic>
+
+ <basic name="scheduler">
+ <column name="scheduler_name" />
+ </basic>
+
+ <many-to-one name="trace" target-entity="nl.atlarge.opendc.integration.jpa.schema.Trace">
+ <join-column name="trace_id" />
+ </many-to-one>
+
+ <one-to-one name="path" target-entity="nl.atlarge.opendc.integration.jpa.schema.Path">
+ <join-column name="path_id" />
+ </one-to-one>
+ </attributes>
+ </entity>
+
+ <entity class="Path" access="FIELD" name="paths">
+ <attributes>
+ <id name="id" />
+
+ <one-to-many name="sections" target-entity="nl.atlarge.opendc.integration.jpa.schema.Section">
+ <join-column name="path_id" />
+ </one-to-many>
+ </attributes>
+ </entity>
+
+ <entity class="Section" access="FIELD" name="sections">
+ <attributes>
+ <id name="id" />
+
+ <basic name="startTime">
+ <column name="start_tick" column-definition="int(11)" />
+ </basic>
+
+ <many-to-one name="datacenter">
+ <join-column name="datacenter_id" />
+ </many-to-one>
+ </attributes>
+ </entity>
+
+ <entity class="Trace" access="FIELD" name="traces">
+ <attributes>
+ <id name="id" />
+ <basic name="name">
+ <column column-definition="text" />
+ </basic>
+ <one-to-many name="jobs" target-entity="nl.atlarge.opendc.integration.jpa.schema.Job">
+ <join-column name="trace_id" />
+ </one-to-many>
+ </attributes>
+ </entity>
+
+ <entity class="Job" access="FIELD" name="jobs">
+ <attributes>
+ <id name="id" />
+ <one-to-many name="tasks" target-entity="nl.atlarge.opendc.integration.jpa.schema.Task">
+ <join-column name="job_id" />
+ </one-to-many>
+ <transient name="owner" />
+ </attributes>
+ </entity>
+
+ <entity class="Task" access="FIELD" name="tasks">
+ <convert converter="nl.atlarge.opendc.integration.jpa.converter.ParallelizableConverter" attribute-name="parallelizable" />
+ <attributes>
+ <id name="id" />
+ <basic name="flops">
+ <column name="total_flop_count" column-definition="int(11)" />
+ </basic>
+ <basic name="startTime">
+ <column name="start_tick" column-definition="int(11)" />
+ </basic>
+ <basic name="parallelizable">
+ <column name="parallelizability" column-definition="text" />
+ </basic>
+
+ <one-to-one name="dependency" target-entity="nl.atlarge.opendc.integration.jpa.schema.Task">
+ <join-column name="task_dependency_id" />
+ </one-to-one>
+ <transient name="_dependencies" />
+ <transient name="_remaining" />
+ <transient name="accepted" />
+ <transient name="started" />
+ <transient name="finished" />
+ </attributes>
+ </entity>
+
+ <entity class="Datacenter" access="FIELD" name="datacenters">
+ <attributes>
+ <id name="id" />
+
+ <one-to-many name="rooms" target-entity="Room">
+ <join-column name="datacenter_id" />
+ </one-to-many>
+ <transient name="scheduler" />
+ <transient name="interval" />
+ <transient name="initialState" />
+ </attributes>
+ </entity>
+
+ <entity class="Room" access="FIELD" name="rooms">
+ <attributes>
+ <id name="id" />
+ <basic name="name">
+ <column column-definition="text" />
+ </basic>
+ <basic name="type">
+ <enumerated>STRING</enumerated>
+ </basic>
+ <one-to-many name="objects">
+ <join-table name="tiles">
+ <join-column name="room_id" />
+ <inverse-join-column name="object_id" />
+ </join-table>
+ </one-to-many>
+ <transient name="initialState" />
+ </attributes>
+ </entity>
+
+ <entity class="RoomObject" access="FIELD" name="objects">
+ <inheritance strategy="JOINED" />
+ <discriminator-column name="type" />
+ <attributes>
+ <id name="id"/>
+ </attributes>
+ </entity>
+
+ <entity class="Rack" access="FIELD" name="racks">
+ <discriminator-value>RACK</discriminator-value>
+ <attributes>
+ <id name="id" />
+ <basic name="name">
+ <column column-definition="text" />
+ </basic>
+ <basic name="capacity" />
+ <basic name="powerCapacity">
+ <column name="power_capacity_w" />
+ </basic>
+
+ <one-to-many name="machines">
+ <join-column name="rack_id" />
+ </one-to-many>
+ <transient name="initialState" />
+ </attributes>
+ </entity>
+
+ <entity class="Machine" access="FIELD" name="machines">
+ <attributes>
+ <id name="id" />
+ <basic name="position" />
+
+ <many-to-many name="cpus">
+ <join-table name="machine_cpus">
+ <join-column name="machine_id" />
+ <inverse-join-column name="cpu_id" />
+ </join-table>
+ </many-to-many>
+
+ <many-to-many name="gpus">
+ <join-table name="machine_gpus">
+ <join-column name="machine_id" />
+ <inverse-join-column name="gpu_id" />
+ </join-table>
+ </many-to-many>
+ <transient name="initialState" />
+ </attributes>
+ </entity>
+
+ <entity class="Cpu" access="FIELD" name="cpus">
+ <attributes>
+ <id name="id" />
+ <basic name="manufacturer">
+ <column column-definition="text" />
+ </basic>
+ <basic name="family">
+ <column column-definition="text" />
+ </basic>
+ <basic name="generation">
+ <column column-definition="text" />
+ </basic>
+ <basic name="model">
+ <column column-definition="text" />
+ </basic>
+ <basic name="clockRate">
+ <column name="clock_rate_mhz" />
+ </basic>
+ <basic name="cores">
+ <column name="number_of_cores" />
+ </basic>
+ <basic name="energyConsumption">
+ <column name="energy_consumption_w" />
+ </basic>
+ <transient name="initialState" />
+ </attributes>
+ </entity>
+
+ <entity class="Gpu" access="FIELD" name="gpus">
+ <attributes>
+ <id name="id" />
+ <basic name="manufacturer">
+ <column column-definition="text" />
+ </basic>
+ <basic name="family">
+ <column column-definition="text" />
+ </basic>
+ <basic name="generation">
+ <column column-definition="text" />
+ </basic>
+ <basic name="model">
+ <column column-definition="text" />
+ </basic>
+ <basic name="clockRate">
+ <column name="clock_rate_mhz" />
+ </basic>
+ <basic name="cores">
+ <column name="number_of_cores" />
+ </basic>
+ <basic name="energyConsumption">
+ <column name="energy_consumption_w" />
+ </basic>
+ <transient name="initialState" />
+ </attributes>
+ </entity>
+
+ <entity class="MachineState" access="FIELD" name="machine_states">
+ <attributes>
+ <id name="id">
+ <generated-value strategy="IDENTITY" />
+ </id>
+ <basic name="time">
+ <column name="tick" column-definition="int(11)" />
+ </basic>
+ <basic name="temperature">
+ <column name="temperature_c" />
+ </basic>
+ <basic name="memoryUsage">
+ <column name="in_use_memory_mb" />
+ </basic>
+ <basic name="load">
+ <column name="load_fraction" />
+ </basic>
+
+ <many-to-one name="task">
+ <join-column name="task_id" />
+ </many-to-one>
+ <many-to-one name="machine">
+ <join-column name="machine_id" />
+ </many-to-one>
+ <many-to-one name="experiment">
+ <join-column name="experiment_id" />
+ </many-to-one>
+ </attributes>
+ </entity>
+
+ <entity class="TaskState" access="FIELD" name="task_states">
+ <attributes>
+ <id name="id">
+ <generated-value strategy="IDENTITY" />
+ </id>
+ <basic name="time">
+ <column name="tick" column-definition="int(11)" />
+ </basic>
+ <basic name="remaining">
+ <column name="flops_left" />
+ </basic>
+ <basic name="cores">
+ <column name="cores_used" />
+ </basic>
+
+ <many-to-one name="task">
+ <join-column name="task_id" />
+ </many-to-one>
+ <many-to-one name="experiment">
+ <join-column name="experiment_id" />
+ </many-to-one>
+ </attributes>
+ </entity>
+</entity-mappings>
diff --git a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt b/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt
index e3477d3e..caaa335b 100644
--- a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt
+++ b/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt
@@ -71,6 +71,13 @@ internal class OmegaSimulation(override val kernel: OmegaKernel, override val to
private val queue: Queue<MessageContainer> = PriorityQueue(Comparator.comparingLong(MessageContainer::time))
/**
+ * The observable state of an [Entity] in simulation, which is provided by the simulation context.
+ */
+ @Suppress("UNCHECKED_CAST")
+ override val <E : Entity<S>, S> E.state: S
+ get() = (resolve(this) as OmegaContext<E, S>?)?.state ?: initialState
+
+ /**
* Initialise the simulator.
*/
init {
@@ -334,12 +341,7 @@ internal class OmegaSimulation(override val kernel: OmegaKernel, override val to
*/
suspend override fun wait(duration: Duration) {
require(duration >= 0) { "The amount of time to suspend must be a positive number" }
-
- if (duration == 0.toLong())
- return
-
schedule(Resume, entity, entity, duration)
-
while (true) {
if (receive() is Resume)
return
@@ -358,12 +360,7 @@ internal class OmegaSimulation(override val kernel: OmegaKernel, override val to
*/
suspend override fun wait(duration: Duration, queue: Queue<Any>) {
require(duration >= 0) { "The amount of time to suspend must be a positive number" }
-
- if (duration == 0.toLong())
- return
-
schedule(Resume, entity, entity, duration)
-
while (true) {
val msg = receive()
if (msg is Resume)
diff --git a/opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt b/opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt
deleted file mode 100644
index ed73d592..00000000
--- a/opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 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 nl.atlarge.opendc
-
-import nl.atlarge.opendc.kernel.omega.OmegaKernel
-import nl.atlarge.opendc.scheduler.FifoScheduler
-import nl.atlarge.opendc.scheduler.SrtfScheduler
-import nl.atlarge.opendc.topology.AdjacencyList
-import nl.atlarge.opendc.topology.TopologyListener
-import nl.atlarge.opendc.topology.container.Datacenter
-import nl.atlarge.opendc.topology.container.Rack
-import nl.atlarge.opendc.topology.container.Room
-import nl.atlarge.opendc.topology.machine.Cpu
-import nl.atlarge.opendc.topology.machine.Machine
-import nl.atlarge.opendc.workload.Task
-import org.junit.jupiter.api.Test
-import java.util.*
-
-internal class SmokeTest {
- @Test
- fun smoke() {
- val datacenter = Datacenter(SrtfScheduler(), 50)
- val builder = AdjacencyList.builder()
- val topology = builder.construct {
- add(datacenter)
-
- // Add a room to the datacenter
- val room = Room().also {
- add(it)
- connect(datacenter, it, tag = "room")
- }
-
- // Add a rack to the room
- val rack = Rack().also {
- add(it)
- connect(room, it, tag = "rack")
- }
-
- val n = 10
-
- // Create n machines in the rack
- repeat(n) {
- val machine = Machine().also {
- add(it)
- connect(rack, it, tag = "machine")
- }
-
- val cpu1 = Cpu(10, 2, 2)
- val cpu2 = Cpu(5, 3, 2)
- add(cpu1)
- add(cpu2)
-
- connect(machine, cpu1, tag = "cpu")
- connect(machine, cpu2, tag = "cpu")
- }
- }
-
- val simulation = OmegaKernel.create(topology)
- val random = Random(0)
- for (i in 0..100) {
- val task = Task(i, emptySet(), random.nextInt(10000).toLong())
- simulation.schedule(task, datacenter, delay = random.nextInt(15000).toLong())
- }
- simulation.run(50000)
-
- }
-}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/FifoScheduler.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt
index 5382e48b..1c3dc869 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/FifoScheduler.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt
@@ -22,12 +22,12 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.scheduler
+package nl.atlarge.opendc.platform.scheduler
import nl.atlarge.opendc.kernel.Context
import nl.atlarge.opendc.topology.Entity
import nl.atlarge.opendc.topology.machine.Machine
-import nl.atlarge.opendc.workload.Task
+import nl.atlarge.opendc.platform.workload.Task
import java.util.*
/**
@@ -37,6 +37,11 @@ import java.util.*
*/
class FifoScheduler : Scheduler {
/**
+ * The name of this scheduler.
+ */
+ override val name: String = "FIFO"
+
+ /**
* The set of machines the scheduler knows of.
*/
val machines: MutableSet<Machine> = HashSet()
@@ -54,6 +59,8 @@ class FifoScheduler : Scheduler {
return
}
+ // The tasks that need to be rescheduled
+ val rescheduled = ArrayDeque<Task>()
val iterator = queue.iterator()
machines
@@ -64,7 +71,7 @@ class FifoScheduler : Scheduler {
// TODO What to do with tasks that are not ready yet to be processed
if (!task.isReady()) {
iterator.remove()
- submit(task)
+ rescheduled.add(task)
continue
} else if (task.finished) {
iterator.remove()
@@ -75,6 +82,11 @@ class FifoScheduler : Scheduler {
break
}
}
+
+ // Reschedule all tasks that are not ready yet
+ while (!rescheduled.isEmpty()) {
+ submit(rescheduled.poll())
+ }
}
/**
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/Scheduler.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt
index 8c96341a..bf988802 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/Scheduler.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt
@@ -22,12 +22,12 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.scheduler
+package nl.atlarge.opendc.platform.scheduler
import nl.atlarge.opendc.kernel.Context
import nl.atlarge.opendc.topology.Entity
import nl.atlarge.opendc.topology.machine.Machine
-import nl.atlarge.opendc.workload.Task
+import nl.atlarge.opendc.platform.workload.Task
/**
* A task scheduler that is coupled to an [Entity] in the topology of the cloud network.
@@ -36,6 +36,11 @@ import nl.atlarge.opendc.workload.Task
*/
interface Scheduler {
/**
+ * The name of this scheduler.
+ */
+ val name: String
+
+ /**
* (Re)schedule the tasks submitted to the scheduler over the specified set of machines.
*
* This method should be invoked at some interval to allow the scheduler to reschedule existing tasks and schedule
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/SrtfScheduler.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt
index 0e94f81a..b2660964 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/scheduler/SrtfScheduler.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt
@@ -22,12 +22,12 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.scheduler
+package nl.atlarge.opendc.platform.scheduler
import nl.atlarge.opendc.kernel.Context
import nl.atlarge.opendc.topology.Entity
import nl.atlarge.opendc.topology.machine.Machine
-import nl.atlarge.opendc.workload.Task
+import nl.atlarge.opendc.platform.workload.Task
import java.util.*
/**
@@ -37,6 +37,11 @@ import java.util.*
*/
class SrtfScheduler : Scheduler {
/**
+ * The name of this scheduler.
+ */
+ override val name: String = "SRTF"
+
+ /**
* The set of machines the scheduler knows of.
*/
val machines: MutableSet<Machine> = HashSet()
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/Job.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt
index 6dbbf327..eb173229 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/Job.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt
@@ -22,15 +22,32 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.workload
+package nl.atlarge.opendc.platform.workload
/**
* A job that is submitted to a cloud network, which consists of one or multiple [Task]s.
*
- * @param id The unique identifier of this job.
- * @param name The name of this job.
- * @param owner The user to which the job belongs.
- * @param tasks The tasks of which the job consists.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class Job(val id: Int, val name: String, val owner: User, val tasks: Collection<Task>)
+interface Job {
+ /**
+ * A unique identifier of the job.
+ */
+ val id: Int
+
+ /**
+ * The owner of this job.
+ */
+ val owner: User
+
+ /**
+ * The tasks this job consists of.
+ */
+ val tasks: Set<Task>
+
+ /**
+ * A flag to indicate the job has finished.
+ */
+ val finished: Boolean
+ get() = !tasks.any { !it.finished }
+}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/Task.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt
index bd2b0604..140a5d5d 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/Task.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt
@@ -22,31 +22,57 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.workload
+package nl.atlarge.opendc.platform.workload
-import nl.atlarge.opendc.kernel.time.Instant
+import nl.atlarge.opendc.kernel.Context
+import nl.atlarge.opendc.topology.container.Datacenter
+import nl.atlarge.opendc.topology.machine.Machine
/**
* A task represents some computation that is part of a [Job].
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class Task(
- val id: Int,
- val dependencies: Set<Task>,
+interface Task {
+ /**
+ * The unique identifier of the task.
+ */
+ val id: Int
+
+ /**
+ * The amount of flops for this task.
+ */
val flops: Long
-) {
+
+ /**
+ * The dependencies of the task.
+ */
+ val dependencies: Set<Task>
+
+ /**
+ * A flag to indicate the task is parallelizable.
+ */
+ val parallelizable: Boolean
+
/**
* The remaining amount of flops to compute.
*/
- var remaining: Long = flops
- private set
+ val remaining: Long
+
+ /**
+ * A flag to indicate the task has been accepted by the datacenter.
+ */
+ val accepted: Boolean
+
+ /**
+ * A flag to indicate the task has been started.
+ */
+ val started: Boolean
/**
* A flag to indicate whether the task is finished.
*/
- var finished: Boolean = false
- private set
+ val finished: Boolean
/**
* Determine whether the task is ready to be processed.
@@ -56,18 +82,24 @@ data class Task(
fun isReady() = dependencies.all { it.finished }
/**
+ * Accept the task into the scheduling queue.
+ */
+ fun Context<Datacenter>.accept()
+
+ /**
+ * Start a task.
+ */
+ fun Context<Machine>.start()
+
+ /**
* Consume the given amount of flops of this task.
*
* @param flops The total amount of flops to consume.
*/
- fun consume(flops: Long) {
- if (finished)
- return
- if (remaining <= flops) {
- finished = true
- remaining = 0
- } else {
- remaining -= flops
- }
- }
+ fun Context<Machine>.consume(flops: Long)
+
+ /**
+ * Finalise the task.
+ */
+ fun Context<Machine>.finalize()
}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt
new file mode 100644
index 00000000..6dd2efb8
--- /dev/null
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt
@@ -0,0 +1,37 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 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 nl.atlarge.opendc.platform.workload
+
+/**
+ * A timestamped sequence of jobs received in a cloud network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Trace {
+ /**
+ * The [Job]s in the trace.
+ */
+ val jobs: Set<Job>
+}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/User.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt
index d0e90851..d827fee5 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/workload/User.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt
@@ -22,19 +22,24 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.workload
-
-import nl.atlarge.opendc.topology.Topology
+package nl.atlarge.opendc.platform.workload
/**
* A user of a cloud network that provides [Job]s for the simulation.
*
- * Each [User] in a simulation has its own logical view of the cloud network which is used to route its jobs in the
+ * Each user in a simulation has its own logical view of the cloud network which is used to route its jobs in the
* physical network.
*
- * @param id The unique identifier of the user.
- * @param name The name of the user.
- * @param view The view of the user on the topology.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class User(val id: Int, val name: String, val view: Topology)
+interface User {
+ /**
+ * The unique identifier of the user.
+ */
+ val id: Int
+
+ /**
+ * The name of this user.
+ */
+ val name: String
+}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt
index f8954527..333609bb 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt
@@ -25,14 +25,14 @@
package nl.atlarge.opendc.topology.container
import mu.KotlinLogging
-import nl.atlarge.opendc.extension.topology.destinations
+import nl.atlarge.opendc.topology.destinations
import nl.atlarge.opendc.kernel.Context
import nl.atlarge.opendc.kernel.Process
import nl.atlarge.opendc.kernel.time.Duration
-import nl.atlarge.opendc.scheduler.Scheduler
+import nl.atlarge.opendc.platform.scheduler.Scheduler
import nl.atlarge.opendc.topology.Entity
import nl.atlarge.opendc.topology.machine.Machine
-import nl.atlarge.opendc.workload.Task
+import nl.atlarge.opendc.platform.workload.Task
import java.util.*
/**
@@ -42,16 +42,16 @@ import java.util.*
* @property interval The interval at which task will be (re)scheduled.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class Datacenter(val scheduler: Scheduler, val interval: Duration) : Entity<Unit>, Process<Datacenter> {
+interface Datacenter : Entity<Unit>, Process<Datacenter> {
/**
- * The logger instance to use for the simulator.
+ * The task scheduler the datacenter uses.
*/
- private val logger = KotlinLogging.logger {}
+ val scheduler: Scheduler
/**
- * The initial state of the entity.
+ * The interval at which task will be (re)scheduled.
*/
- override val initialState = Unit
+ val interval: Duration
/**
* This method is invoked to start the simulation an [Entity] associated with this [Process].
@@ -69,6 +69,8 @@ class Datacenter(val scheduler: Scheduler, val interval: Duration) : Entity<Unit
* simulation will not run any further.
*/
suspend override fun Context<Datacenter>.run() {
+ val logger = KotlinLogging.logger {}
+
// The queue of messages to be processed after a cycle
val queue: Queue<Any> = ArrayDeque()
// Find all machines in the datacenter
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt
index 27207d4c..25429f71 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt
@@ -32,6 +32,4 @@ import nl.atlarge.opendc.topology.Entity
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class Rack : Entity<Unit> {
- override val initialState = Unit
-}
+interface Rack : Entity<Unit>
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt
index 109a5629..3b338899 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt
@@ -31,9 +31,4 @@ import nl.atlarge.opendc.topology.Entity
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class Room : Entity<Unit> {
- /**
- * The initial state of the entity.
- */
- override val initialState = Unit
-}
+interface Room : Entity<Unit>
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt
index 78e2eaaa..f97e73e9 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt
@@ -29,10 +29,4 @@ package nl.atlarge.opendc.topology.machine
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class Cpu(
- override val speed: Int,
- override val cores: Int,
- override val energyConsumption: Int
-) : ProcessingUnit {
- override val initialState = Unit
-}
+interface Cpu : ProcessingUnit
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt
index 09179c94..15c5263f 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt
@@ -29,11 +29,5 @@ package nl.atlarge.opendc.topology.machine
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class Gpu(
- override val speed: Int,
- override val cores: Int,
- override val energyConsumption: Int
-) : ProcessingUnit {
- override val initialState = Unit
-}
+interface Gpu : ProcessingUnit
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt
index 3305581a..4338ae04 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt
@@ -25,8 +25,8 @@
package nl.atlarge.opendc.topology.machine
import mu.KotlinLogging
-import nl.atlarge.opendc.extension.topology.destinations
-import nl.atlarge.opendc.workload.Task
+import nl.atlarge.opendc.topology.destinations
+import nl.atlarge.opendc.platform.workload.Task
import nl.atlarge.opendc.kernel.Context
import nl.atlarge.opendc.kernel.Process
import nl.atlarge.opendc.kernel.time.Duration
@@ -38,7 +38,7 @@ import nl.atlarge.opendc.topology.Entity
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class Machine : Entity<Machine.State>, Process<Machine> {
+open class Machine : Entity<Machine.State>, Process<Machine> {
/**
* The logger instance to use for the simulator.
*/
@@ -53,8 +53,18 @@ class Machine : Entity<Machine.State>, Process<Machine> {
/**
* The shape of the state of a [Machine] entity.
+ *
+ * @property status The status of the machine.
+ * @property task The task assign to the machine.
+ * @property memory The memory usage of the machine (defaults to 50mb for the kernel)
+ * @property load The load on the machine (defaults to 0.0)
+ * @property temperature The temperature of the machine (defaults to 23 degrees Celcius)
*/
- data class State(val status: Status, val task: Task? = null)
+ data class State(val status: Status,
+ val task: Task? = null,
+ val memory: Int = 50,
+ val load: Double = 0.0,
+ val temperature: Double = 23.0)
/**
* The initial state of a [Machine] entity.
@@ -69,24 +79,28 @@ class Machine : Entity<Machine.State>, Process<Machine> {
val interval: Duration = 10
val cpus = outgoingEdges.destinations<Cpu>("cpu")
- val speed = cpus.fold(0, { acc, (speed, cores) -> acc + speed * cores })
+ val speed = cpus.fold(0, { acc, cpu -> acc + cpu.clockRate * cpu.cores }) / 10
+
var task: Task = receiveTask()
- update(State(Status.RUNNING, task))
+ update(State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0))
+ task.run { start() }
while (true) {
- if (task.finished) {
+ if (task.remaining <= 0) {
+ task.run { finalize() }
logger.info { "${entity.id}: Task ${task.id} finished. Machine idle at $time" }
update(State(Status.IDLE))
task = receiveTask()
} else {
- task.consume(speed * delta)
+ task.run { consume(speed * delta) }
}
// Check if we have received a new order in the meantime.
val msg = receive(interval)
if (msg is Task) {
task = msg
- update(State(Status.RUNNING, task))
+ update(State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0))
+ task.run { start() }
}
}
}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt
index 31bfbcd6..abc8608b 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt
@@ -33,9 +33,9 @@ import nl.atlarge.opendc.topology.Entity
*/
interface ProcessingUnit : Entity<Unit> {
/**
- * The speed of this [ProcessingUnit] per core.
+ * The speed of this [ProcessingUnit] per core in MHz.
*/
- val speed: Int
+ val clockRate: Int
/**
* The amount of cores within this [ProcessingUnit].
@@ -43,7 +43,7 @@ interface ProcessingUnit : Entity<Unit> {
val cores: Int
/**
- * The energy consumption of this [ProcessingUnit] in Kj/s.
+ * The energy consumption of this [ProcessingUnit] in Watt.
*/
- val energyConsumption: Int
+ val energyConsumption: Double
}
diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt
index aac4ce03..b9602e55 100644
--- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt
+++ b/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt
@@ -29,9 +29,6 @@ import nl.atlarge.opendc.topology.Entity
/**
* An [Entity] which provides power for other entities a cloud network to run.
*
- * @param output The power output of the power unit in Watt.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class PowerUnit(val output: Double) : Entity<Unit> {
- override val initialState = Unit
-}
+interface PowerUnit : Entity<Unit>