summaryrefslogtreecommitdiff
path: root/opendc-integration-jpa/core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-integration-jpa/core/src/main')
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt38
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt62
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt66
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt58
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt66
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt60
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt53
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt58
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt59
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt45
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt53
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt40
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt52
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt50
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt36
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt34
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt45
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt117
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt49
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt44
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt176
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt93
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt64
-rw-r--r--opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt87
-rw-r--r--opendc-integration-jpa/core/src/main/resources/jpa/schema.xml324
25 files changed, 1829 insertions, 0 deletions
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt
new file mode 100644
index 00000000..cbbe280a
--- /dev/null
+++ b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt
@@ -0,0 +1,38 @@
+/*
+ * 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
+
+import javax.persistence.EntityManager
+
+/**
+ * Run the given block in a transaction, committing on return of the block.
+ *
+ * @param block The block to execute in the transaction.
+ */
+inline fun EntityManager.transaction(block: () -> Unit) {
+ transaction.begin()
+ block()
+ transaction.commit()
+}
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt
new file mode 100644
index 00000000..11d5836e
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt
new file mode 100644
index 00000000..95027440
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt
new file mode 100644
index 00000000..b775eb6e
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt
new file mode 100644
index 00000000..1e6eaa2b
--- /dev/null
+++ b/opendc-integration-jpa/core/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 = 10
+
+ /**
+ * The initial state of the datacenter.
+ */
+ override val initialState = Unit
+}
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt
new file mode 100644
index 00000000..0b352cb4
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt
new file mode 100644
index 00000000..96fc112c
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt
new file mode 100644
index 00000000..94625242
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt
new file mode 100644
index 00000000..394cf478
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt
new file mode 100644
index 00000000..4071b342
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt
new file mode 100644
index 00000000..23efe888
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt
new file mode 100644
index 00000000..ccf3b6e8
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt
new file mode 100644
index 00000000..2d2099a2
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt
new file mode 100644
index 00000000..f3b7ae06
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt
new file mode 100644
index 00000000..0e9fb84f
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt
new file mode 100644
index 00000000..5e138947
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt
new file mode 100644
index 00000000..e3b8c350
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt
new file mode 100644
index 00000000..83a98cfb
--- /dev/null
+++ b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.workload.Task
+import nl.atlarge.opendc.platform.workload.TaskState
+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 lateinit var dependencies: Set<Task>
+ private set
+
+ /**
+ * The remaining flops for this task.
+ */
+ override var remaining: Long = 0
+ private set
+
+ /**
+ * A flag to indicate whether the task has finished.
+ */
+ override var finished: Boolean = false
+ private set
+
+ /**
+ * The state of the task.
+ */
+ override lateinit var state: TaskState
+ private set
+
+ /**
+ * This method initialises the task object after it has been created by the JPA implementation. We use this
+ * initialisation method because JPA implementations only call the default constructor
+ */
+ @PostLoad
+ internal fun init() {
+ remaining = flops
+ dependencies = dependency?.let(::setOf) ?: emptySet()
+ state = TaskState.Underway
+ }
+
+ /**
+ * This method is invoked when a task has arrived at a datacenter.
+ *
+ * @param time The moment in time the task has arrived at the datacenter.
+ */
+ override fun arrive(time: Instant) {
+ if (state !is TaskState.Underway) {
+ throw IllegalStateException("The task has already been submitted to a datacenter")
+ }
+ remaining = flops
+ state = TaskState.Queued(time)
+ }
+
+ /**
+ * Consume the given amount of flops of this task.
+ *
+ * @param time The current moment in time of the consumption.
+ * @param flops The total amount of flops to consume.
+ */
+ override fun consume(time: Instant, flops: Long) {
+ if (state is TaskState.Queued) {
+ state = TaskState.Running(state as TaskState.Queued, time)
+ } else if (finished) {
+ return
+ }
+ remaining -= flops
+ if (remaining <= 0) {
+ remaining = 0
+ finished = true
+ state = TaskState.Finished(state as TaskState.Running, time)
+ }
+ }
+}
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt
new file mode 100644
index 00000000..14441752
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt
new file mode 100644
index 00000000..cd3d9348
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt
new file mode 100644
index 00000000..59b28d0b
--- /dev/null
+++ b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt
@@ -0,0 +1,176 @@
+/*
+ * 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.transaction
+import nl.atlarge.opendc.integration.jpa.schema.Trace as InternalTrace
+import nl.atlarge.opendc.integration.jpa.schema.TaskState as InternalTaskState
+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.platform.workload.TaskState
+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 java.util.*
+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(private val manager: EntityManager,
+ private val experiment: InternalExperiment): Experiment<Unit>, AutoCloseable {
+ /**
+ * 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.transaction {
+ experiment.state = ExperimentState.SIMULATING
+ }
+
+ 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
+ val tasks = trace.jobs.flatMap { it.tasks }
+
+ logger.info { "Sending trace to kernel ${Objects.hashCode(trace)} ${(trace as InternalTrace).id}" }
+
+ // Schedule all messages in the trace
+ tasks.forEach { task ->
+ if (task is InternalTask) {
+ 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 }) {
+ // Collect data of simulation cycle
+ manager.transaction {
+ experiment.last = simulation.clock.now
+
+ 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 = InternalTaskState(0,
+ task as nl.atlarge.opendc.integration.jpa.schema.Task,
+ experiment,
+ simulation.clock.now,
+ task.remaining.toInt(),
+ 1
+ )
+ manager.persist(state)
+ }
+ }
+
+ // Run next simulation cycle
+ simulation.run(simulation.clock.now + 1)
+ }
+
+ // Set the experiment state
+ manager.transaction {
+ experiment.state = ExperimentState.FINISHED
+ }
+
+ logger.info { "Simulation done" }
+ val waiting: Long = tasks.fold(0.toLong()) { acc, task ->
+ val finished = task.state as TaskState.Finished
+ acc + (finished.previous.at - finished.previous.previous.at)
+ } / tasks.size
+
+ val execution: Long = tasks.fold(0.toLong()) { acc, task ->
+ val finished = task.state as TaskState.Finished
+ acc + (finished.at - finished.previous.at)
+ } / tasks.size
+
+ val turnaround: Long = tasks.fold(0.toLong()) { acc, task ->
+ val finished = task.state as TaskState.Finished
+ acc + (finished.at - finished.previous.previous.at)
+ } / tasks.size
+
+ logger.info { "Average waiting time: $waiting seconds" }
+ logger.info { "Average execution time: $execution seconds" }
+ logger.info { "Average turnaround time: $turnaround seconds" }
+ }
+
+ /**
+ * Closes this resource, relinquishing any underlying resources.
+ * This method is invoked automatically on objects managed by the
+ * `try`-with-resources statement.
+ *
+ * @throws Exception if this resource cannot be closed
+ */
+ override fun close() = manager.close()
+}
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt
new file mode 100644
index 00000000..1d1e118d
--- /dev/null
+++ b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.transaction
+import nl.atlarge.opendc.integration.jpa.schema.Experiment as InternalExperiment
+import nl.atlarge.opendc.integration.jpa.schema.ExperimentState
+import javax.persistence.EntityManager
+import javax.persistence.EntityManagerFactory
+
+/**
+ * A manager for [Experiment]s received from a JPA database.
+ *
+ * @property factory The JPA entity manager factory to create [EntityManager]s to retrieve entities from the database
+ * from.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class JpaExperimentManager(private val factory: EntityManagerFactory): AutoCloseable {
+ /**
+ * The entity manager for this experiment.
+ */
+ private var manager: EntityManager = factory.createEntityManager()
+
+ /**
+ * 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(): JpaExperiment? {
+ var result: JpaExperiment? = null
+ manager.transaction {
+ 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
+ }
+ result = experiment?.let { JpaExperiment(manager, it) }
+ }
+ manager = factory.createEntityManager()
+ return result
+ }
+
+ /**
+ * Close this resource, relinquishing any underlying resources.
+ * This method is invoked automatically on objects managed by the
+ * `try`-with-resources statement.*
+ *
+ * @throws Exception if this resource cannot be closed
+ */
+ override fun close() = manager.close()
+}
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt
new file mode 100644
index 00000000..794ca44e
--- /dev/null
+++ b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt
@@ -0,0 +1,64 @@
+/*
+ * 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 java.util.concurrent.Executors
+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 properties = HashMap<Any, Any>()
+ val env = System.getenv()
+ properties["javax.persistence.jdbc.url"] = env["PERSISTENCE_URL"] ?: ""
+ properties["javax.persistence.jdbc.user"] = env["PERSISTENCE_USER"] ?: ""
+ properties["javax.persistence.jdbc.password"] = env["PERSISTENCE_PASSWORD"] ?: ""
+ val factory = Persistence.createEntityManagerFactory("opendc-simulator", properties)
+
+ val threads = 4
+ val executorService = Executors.newFixedThreadPool(threads)
+ val experiments = JpaExperimentManager(factory)
+ val kernel = OmegaKernel
+
+ logger.info { "Waiting for enqueued experiments..." }
+ while (true) {
+ experiments.poll()?.let { experiment ->
+ logger.info { "Found experiment. Submitting for simulation now..." }
+ executorService.submit {
+ experiment.use { it.run(kernel) }
+ }
+ }
+
+ Thread.sleep(500)
+ }
+}
diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt b/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt
new file mode 100644
index 00000000..8def721e
--- /dev/null
+++ b/opendc-integration-jpa/core/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/core/src/main/resources/jpa/schema.xml b/opendc-integration-jpa/core/src/main/resources/jpa/schema.xml
new file mode 100644
index 00000000..bd6ea7a1
--- /dev/null
+++ b/opendc-integration-jpa/core/src/main/resources/jpa/schema.xml
@@ -0,0 +1,324 @@
+<?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" cacheable="false">
+ <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" cacheable="false">
+ <attributes>
+ <id name="id" />
+ <one-to-many name="tasks" target-entity="Task">
+ <join-column name="job_id" />
+ </one-to-many>
+ <transient name="owner" />
+ </attributes>
+ </entity>
+
+ <entity class="Task" access="FIELD" name="tasks" cacheable="false">
+ <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="Task">
+ <join-column name="task_dependency_id" />
+ </one-to-one>
+ <transient name="dependencies" />
+ <transient name="state" />
+ <transient name="remaining" />
+ <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>