summaryrefslogtreecommitdiff
path: root/opendc-model-odc
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2018-01-11 16:27:05 +0100
committerFabian Mastenbroek <mail.fabianm@gmail.com>2018-01-11 16:52:17 +0100
commitb1c4d1f94e35445bdba5a56b614d0ec28a332624 (patch)
treef2a7244fd52a85f0bd5a4a51f8b3243d10005878 /opendc-model-odc
parent8666a78b86a40c1d8dab28dd18e841318c01f97f (diff)
refactor(#18): Redesign core simulation API
This change contains the redesign of the core simulation API and provides a cleaner interface for developing simulation models for the users.
Diffstat (limited to 'opendc-model-odc')
-rw-r--r--opendc-model-odc/core/build.gradle87
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt10
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt118
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt71
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt110
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt53
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt92
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt72
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt37
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt45
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt102
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt36
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt35
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt32
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt33
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt123
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt50
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt35
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt35
-rw-r--r--opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt35
-rw-r--r--opendc-model-odc/jpa/build.gradle89
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt44
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt14
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt38
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt62
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt66
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt58
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt66
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt58
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt53
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt58
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt58
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt45
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt53
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt40
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt52
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt50
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt36
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt34
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt45
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt117
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt49
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt44
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt179
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt93
-rw-r--r--opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt95
-rw-r--r--opendc-model-odc/jpa/src/main/resources/jpa/schema.xml324
-rw-r--r--opendc-model-odc/setup/Dockerfile30
-rw-r--r--opendc-model-odc/setup/build.gradle87
-rw-r--r--opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.kt66
-rw-r--r--opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml41
51 files changed, 3355 insertions, 0 deletions
diff --git a/opendc-model-odc/core/build.gradle b/opendc-model-odc/core/build.gradle
new file mode 100644
index 00000000..c8336196
--- /dev/null
+++ b/opendc-model-odc/core/build.gradle
@@ -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.
+ */
+
+/* Build configuration */
+buildscript {
+ ext.kotlin_version = '1.2.10'
+ ext.dokka_version = '0.9.15'
+
+ repositories {
+ mavenCentral()
+ jcenter()
+ }
+
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
+ classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-RC3'
+ }
+}
+
+apply plugin: 'java'
+apply plugin: 'kotlin'
+apply plugin: 'org.jetbrains.dokka'
+apply plugin: 'org.junit.platform.gradle.plugin'
+
+compileKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+kotlin {
+ experimental {
+ coroutines 'enable'
+ }
+}
+
+dokka {
+ outputFormat = 'html'
+ outputDirectory = "$buildDir/javadoc"
+}
+
+/* Project configuration */
+group 'com.atlarge.opendc'
+version '1.1'
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+ compile project(':opendc-core')
+ compile project(':opendc-stdlib')
+ compile "io.github.microutils:kotlin-logging:1.4.6"
+
+ 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"
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt
new file mode 100644
index 00000000..01ffbd2c
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt
@@ -0,0 +1,10 @@
+package com.atlarge.opendc.model.odc
+
+import com.atlarge.opendc.model.topology.MutableTopology
+
+/**
+ * The OpenDC standard simulation model used for datacenter simulations.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface OdcModel: MutableTopology
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt
new file mode 100644
index 00000000..d2cbcdfe
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt
@@ -0,0 +1,118 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.platform.scheduler
+
+import com.atlarge.opendc.simulator.Context
+import com.atlarge.opendc.model.odc.platform.workload.Task
+import com.atlarge.opendc.model.odc.topology.machine.Machine
+import java.util.*
+
+/**
+ * A [Scheduler] that distributes work according to the first-in-first-out principle.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+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()
+
+ /**
+ * The queue of [Task]s that need to be scheduled.
+ */
+ val queue: Queue<Task> = ArrayDeque()
+
+ /**
+ * (Re)schedule the tasks submitted to the scheduler over the specified set of machines.
+ */
+ override suspend fun <S, M> Context<S, M>.schedule() {
+ if (queue.isEmpty()) {
+ return
+ }
+
+ // The tasks that need to be rescheduled
+ val rescheduled = ArrayDeque<Task>()
+ val iterator = queue.iterator()
+
+ machines
+ .filter { it.state.status != Machine.Status.HALT }
+ .forEach { machine ->
+ while (iterator.hasNext()) {
+ val task = iterator.next()
+
+ // TODO What to do with tasks that are not ready yet to be processed
+ if (!task.ready) {
+ iterator.remove()
+ rescheduled.add(task)
+ continue
+ } else if (task.finished) {
+ iterator.remove()
+ continue
+ }
+
+ machine.send(task)
+ break
+ }
+ }
+
+ // Reschedule all tasks that are not ready yet
+ while (!rescheduled.isEmpty()) {
+ queue.add(rescheduled.poll())
+ }
+ }
+
+ /**
+ * Submit a [Task] to this scheduler.
+ *
+ * @param task The task to submit to the scheduler.
+ */
+ override fun submit(task: Task) {
+ queue.add(task)
+ }
+
+ /**
+ * Register a [Machine] to this scheduler.
+ *
+ * @param machine The machine to register.
+ */
+ override fun register(machine: Machine) {
+ machines.add(machine)
+ }
+
+ /**
+ * Deregister a [Machine] from this scheduler.
+ *
+ * @param machine The machine to deregister.
+ */
+ override fun deregister(machine: Machine) {
+ machines.remove(machine)
+ }
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt
new file mode 100644
index 00000000..ee965af9
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt
@@ -0,0 +1,71 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.platform.scheduler
+
+import com.atlarge.opendc.simulator.Context
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.odc.platform.workload.Task
+import com.atlarge.opendc.model.odc.topology.machine.Machine
+
+/**
+ * A task scheduler that is coupled to an [Entity] in the topology of the cloud network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+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
+ * new tasks.
+ */
+ suspend fun <S, M> Context<S, M>.schedule()
+
+ /**
+ * Submit a [Task] to this scheduler.
+ *
+ * @param task The task to submit to the scheduler.
+ */
+ fun submit(task: Task)
+
+ /**
+ * Register a [Machine] to this scheduler.
+ *
+ * @param machine The machine to register.
+ */
+ fun register(machine: Machine)
+
+ /**
+ * Deregister a [Machine] from this scheduler.
+ *
+ * @param machine The machine to deregister.
+ */
+ fun deregister(machine: Machine)
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt
new file mode 100644
index 00000000..0e497b56
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt
@@ -0,0 +1,110 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.platform.scheduler
+
+import com.atlarge.opendc.simulator.Context
+import com.atlarge.opendc.model.odc.platform.workload.Task
+import com.atlarge.opendc.model.odc.topology.machine.Machine
+import java.util.*
+
+/**
+ * A [Scheduler] that distributes work according to the shortest job first policy.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+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()
+
+ /**
+ * The set of [Task]s that need to be scheduled.
+ */
+ val tasks: MutableSet<Task> = HashSet()
+
+ /**
+ * (Re)schedule the tasks submitted to the scheduler over the specified set of machines.
+ */
+ override suspend fun <S, M> Context<S, M>.schedule() {
+ if (tasks.isEmpty()) {
+ return
+ }
+
+ val iterator = tasks.sortedBy { it.remaining }.iterator()
+
+ machines
+ .filter { it.state.status != Machine.Status.HALT }
+ .forEach { machine ->
+ while (iterator.hasNext()) {
+ val task = iterator.next()
+
+ // TODO What to do with tasks that are not ready yet to be processed
+ if (!task.ready) {
+ tasks.add(task)
+ continue
+ } else if (task.finished) {
+ tasks.remove(task)
+ continue
+ }
+
+ machine.send(task)
+ break
+ }
+ }
+ }
+
+ /**
+ * Submit a [Task] to this scheduler.
+ *
+ * @param task The task to submit to the scheduler.
+ */
+ override fun submit(task: Task) {
+ tasks.add(task)
+ }
+
+ /**
+ * Register a [Machine] to this scheduler.
+ *
+ * @param machine The machine to register.
+ */
+ override fun register(machine: Machine) {
+ machines.add(machine)
+ }
+
+ /**
+ * Deregister a [Machine] from this scheduler.
+ *
+ * @param machine The machine to deregister.
+ */
+ override fun deregister(machine: Machine) {
+ machines.remove(machine)
+ }
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt
new file mode 100644
index 00000000..c42bb667
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.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 com.atlarge.opendc.model.odc.platform.workload
+
+/**
+ * A bag of tasks which are submitted by a [User] to the cloud network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+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-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt
new file mode 100644
index 00000000..f7b9d60f
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt
@@ -0,0 +1,92 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.platform.workload
+
+import com.atlarge.opendc.simulator.Instant
+import com.atlarge.opendc.model.odc.topology.machine.Machine
+
+/**
+ * A task that runs as part of a [Job] on a [Machine].
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+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 flops for this task.
+ */
+ val remaining: Long
+
+ /**
+ * The state of the task.
+ */
+ val state: TaskState
+
+ /**
+ * A flag to indicate whether the task is ready to be started.
+ */
+ val ready: Boolean
+ get() = !dependencies.any { !it.finished }
+
+ /**
+ * A flag to indicate whether the task has finished.
+ */
+ val finished: Boolean
+ get() = state is TaskState.Finished
+
+ /**
+ * 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.
+ */
+ fun arrive(time: Instant)
+
+ /**
+ * 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.
+ */
+ fun consume(time: Instant, flops: Long)
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt
new file mode 100644
index 00000000..2fb3acd9
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt
@@ -0,0 +1,72 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.platform.workload
+
+import com.atlarge.opendc.simulator.Instant
+
+
+/**
+ * This class hierarchy describes the states of a [Task].
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+sealed class TaskState {
+ /**
+ * A state to indicate the task has not yet arrived at the [Datacenter].
+ */
+ object Underway : TaskState()
+
+ /**
+ * A state to indicate the task has arrived at the [Datacenter].
+ *
+ * @property at The moment in time the task has arrived.
+ */
+ data class Queued(val at: Instant) : TaskState()
+
+ /**
+ * A state to indicate the task has started running on a machine.
+ *
+ * @property previous The previous state of the task.
+ * @property at The moment in time the task started.
+ */
+ data class Running(val previous: Queued, val at: Instant) : TaskState()
+
+ /**
+ * A state to indicate the task has finished.
+ *
+ * @property previous The previous state of the task.
+ * @property at The moment in time the task finished.
+ */
+ data class Finished(val previous: Running, val at: Instant) : TaskState()
+
+ /**
+ * A state to indicate the task has failed.
+ *
+ * @property previous The previous state of the task.
+ * @property at The moment in time the task failed.
+ * @property reason The reason of the failure.
+ */
+ data class Failed(val previous: Running, val at: Instant, val reason: String) : TaskState()
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt
new file mode 100644
index 00000000..b2d65277
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt
new file mode 100644
index 00000000..6099db3e
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.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 com.atlarge.opendc.model.odc.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
+ * physical network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface User {
+ /**
+ * The unique identifier of the user.
+ */
+ val id: Int
+
+ /**
+ * The name of this user.
+ */
+ val name: String
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt
new file mode 100644
index 00000000..2b682410
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt
@@ -0,0 +1,102 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.container
+
+import mu.KotlinLogging
+import com.atlarge.opendc.simulator.Context
+import com.atlarge.opendc.simulator.Duration
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.simulator.Process
+import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler
+import com.atlarge.opendc.model.odc.platform.workload.Task
+import com.atlarge.opendc.model.odc.topology.machine.Machine
+import com.atlarge.opendc.model.topology.Topology
+import com.atlarge.opendc.model.topology.destinations
+import java.util.*
+
+/**
+ * A representation of a facility used to house computer systems and associated components.
+ *
+ * @property scheduler The tasks scheduler the datacenter uses.
+ * @property interval The interval at which task will be (re)scheduled.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Datacenter : Process<Unit, Topology> {
+ /**
+ * The task scheduler the datacenter uses.
+ */
+ val scheduler: Scheduler
+
+ /**
+ * The interval at which task will be (re)scheduled.
+ */
+ val interval: Duration
+
+ /**
+ * This method is invoked to start the simulation an [Entity] associated with this [Context].
+ *
+ * This method is assumed to be running during a simulation, but should hand back control to the simulator at
+ * some point by suspending the process. This allows other processes to do work in the current tick of the
+ * simulation.
+ * Suspending the process can be achieved by calling suspending method in the context:
+ * - [Context.hold] - Wait for `n` amount of ticks before resuming execution.
+ * - [Context.receive] - Wait for a message to be received in the mailbox of the [Entity] before resuming
+ * execution.
+ *
+ * If this method exits early, before the simulation has finished, the entity is assumed to be shutdown and its
+ * simulation will not run any further.
+ */
+ suspend override fun Context<Unit, Topology>.run() = model.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
+ val machines = outgoingEdges.destinations<Room>("room").asSequence()
+ .flatMap { it.outgoingEdges.destinations<Rack>("rack").asSequence() }
+ .flatMap { it.outgoingEdges.destinations<Machine>("machine").asSequence() }.toList()
+
+ logger.info { "Initialising datacenter with ${machines.size} machines" }
+
+ // Register all machines to the scheduler
+ machines.forEach(scheduler::register)
+
+ while (true) {
+ // Context all messages in the queue
+ while (queue.isNotEmpty()) {
+ val msg = queue.poll()
+ if (msg is Task) {
+ msg.arrive(time)
+ scheduler.submit(msg)
+ }
+ }
+ // (Re)schedule the tasks
+ scheduler.run { schedule() }
+
+ // Sleep a time quantum
+ hold(interval, queue)
+ }
+ }
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt
new file mode 100644
index 00000000..0ec43f9a
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.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 com.atlarge.opendc.model.odc.topology.container
+
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.topology.Topology
+
+/**
+ * A type of physical steel and electronic framework that is designed to house servers, networking devices, cables and
+ * other datacenter computing equipment.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Rack : Entity<Unit, Topology>
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt
new file mode 100644
index 00000000..50cfc3e6
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt
@@ -0,0 +1,35 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.container
+
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.topology.Topology
+
+/**
+ * A physical room in a datacenter with relationships to the entities within the room.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Room : Entity<Unit, Topology>
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt
new file mode 100644
index 00000000..58eacdc1
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt
@@ -0,0 +1,32 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.machine
+
+/**
+ * A central processing unit.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Cpu : ProcessingUnit
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt
new file mode 100644
index 00000000..84afc711
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt
@@ -0,0 +1,33 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.machine
+
+/**
+ * A graphics processing unit.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Gpu : ProcessingUnit
+
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt
new file mode 100644
index 00000000..4f4ce645
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt
@@ -0,0 +1,123 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.machine
+
+import com.atlarge.opendc.simulator.Context
+import com.atlarge.opendc.simulator.Process
+import com.atlarge.opendc.model.odc.platform.workload.Task
+import com.atlarge.opendc.model.topology.Topology
+import com.atlarge.opendc.model.topology.destinations
+import com.atlarge.opendc.simulator.Duration
+import mu.KotlinLogging
+
+/**
+ * A Physical Machine (PM) inside a rack of a datacenter. It has a speed, and can be given a workload on which it will
+ * work until finished or interrupted.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+open class Machine : Process<Machine.State, Topology> {
+ /**
+ * The logger instance to use for the simulator.
+ */
+ private val logger = KotlinLogging.logger {}
+
+ /**
+ * The status of a machine.
+ */
+ enum class Status {
+ HALT, IDLE, RUNNING
+ }
+
+ /**
+ * 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,
+ val memory: Int = 50,
+ val load: Double = 0.0,
+ val temperature: Double = 23.0)
+
+ /**
+ * The initial state of a [Machine] entity.
+ */
+ override val initialState = State(Status.HALT)
+
+ /**
+ * Run the simulation kernel for this entity.
+ */
+ override suspend fun Context<State, Topology>.run() = model.run {
+ state = State(Status.IDLE)
+
+ val interval: Duration = 10
+ val cpus = outgoingEdges.destinations<Cpu>("cpu")
+ val speed = cpus.fold(0, { acc, cpu -> acc + cpu.clockRate * cpu.cores })
+
+ // Halt the machine if it has not processing units (see bug #4)
+ if (cpus.isEmpty()) {
+ state = State(Status.HALT)
+ return
+ }
+
+ var task: Task = receiveTask()
+ state = State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0)
+
+ while (true) {
+ if (task.finished) {
+ logger.info { "$id: Task ${task.id} finished. Machine idle at $time" }
+ state = State(Status.IDLE)
+ task = receiveTask()
+ } else {
+ task.consume(time, speed * delta)
+ }
+
+ // Check if we have received a new order in the meantime.
+ val msg = receive(interval)
+ if (msg is Task) {
+ task = msg
+ state = State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0)
+ }
+ }
+ }
+
+ /**
+ * Wait for a [Task] to be received by the [Context] and discard all other messages received in the meantime.
+ *
+ * @return The task that has been received.
+ */
+ private suspend fun Context<State, Topology>.receiveTask(): Task {
+ while (true) {
+ val msg = receive()
+ if (msg is Task)
+ return msg
+ }
+ }
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt
new file mode 100644
index 00000000..0b8989de
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.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 com.atlarge.opendc.model.odc.topology.machine
+
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.topology.Topology
+
+/**
+ * An interface representing a generic processing unit which is placed into a [Machine].
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface ProcessingUnit : Entity<Unit, Topology> {
+ /**
+ * The speed of this [ProcessingUnit] per core in MHz.
+ */
+ val clockRate: Int
+
+ /**
+ * The amount of cores within this [ProcessingUnit].
+ */
+ val cores: Int
+
+ /**
+ * The energy consumption of this [ProcessingUnit] in Watt.
+ */
+ val energyConsumption: Double
+}
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt
new file mode 100644
index 00000000..a41a8326
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt
@@ -0,0 +1,35 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.network
+
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.topology.Topology
+
+/**
+ * A generic interface for a network unit in a cloud network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface NetworkUnit : Entity<Unit, Topology>
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt
new file mode 100644
index 00000000..8650b5dc
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt
@@ -0,0 +1,35 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.power
+
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.topology.Topology
+
+/**
+ * An [Entity] which provides power for other entities a cloud network to run.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface PowerUnit : Entity<Unit, Topology>
diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt
new file mode 100644
index 00000000..b5bb4dfb
--- /dev/null
+++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt
@@ -0,0 +1,35 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology.storage
+
+import com.atlarge.opendc.simulator.Entity
+import com.atlarge.opendc.model.topology.Topology
+
+/**
+ * A generic interface for a storage unit in a cloud network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface StorageUnit : Entity<Unit, Topology>
diff --git a/opendc-model-odc/jpa/build.gradle b/opendc-model-odc/jpa/build.gradle
new file mode 100644
index 00000000..819ef735
--- /dev/null
+++ b/opendc-model-odc/jpa/build.gradle
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+/* Build configuration */
+buildscript {
+ ext.kotlin_version = '1.2.10'
+ ext.dokka_version = '0.9.15'
+
+ repositories {
+ mavenCentral()
+ jcenter()
+ }
+
+ 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'
+ }
+}
+
+apply plugin: 'java'
+apply plugin: 'kotlin'
+apply plugin: 'kotlin-jpa'
+apply plugin: 'org.jetbrains.dokka'
+apply plugin: 'org.junit.platform.gradle.plugin'
+
+compileKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+kotlin {
+ experimental {
+ coroutines 'enable'
+ }
+}
+
+dokka {
+ outputFormat = 'html'
+ outputDirectory = "$buildDir/javadoc"
+}
+
+/* Project configuration */
+group 'com.atlarge.opendc'
+version '1.1'
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+ compile project(':opendc-core')
+ compile project(':opendc-stdlib')
+ compile project(':opendc-model-odc:core')
+ compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final'
+
+ 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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt
new file mode 100644
index 00000000..10fc54b5
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt
@@ -0,0 +1,44 @@
+package com.atlarge.opendc.model.odc
+
+import com.atlarge.opendc.simulator.Bootstrap
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Task
+import com.atlarge.opendc.model.odc.topology.JpaTopologyFactory
+import com.atlarge.opendc.model.topology.bootstrap
+
+/**
+ * A [Bootstrap] procedure for experiments retrieved from a JPA data store.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+class JpaBootstrap(val experiment: Experiment) : Bootstrap<JpaModel> {
+ /**
+ * Bootstrap a model `M` for a kernel in the given context.
+ *
+ * @param context The context to bootstrap to model in.
+ * @return The initialised model for the simulation.
+ */
+ override fun bootstrap(context: Bootstrap.Context<JpaModel>): JpaModel {
+ val section = experiment.path.sections.first()
+
+ // TODO We should not modify parts of the experiment in a bootstrap as the bootstrap should be reproducible.
+ // Important: initialise the scheduler of the datacenter
+ section.datacenter.scheduler = experiment.scheduler
+
+ val topology = JpaTopologyFactory(section)
+ .create()
+ .bootstrap()
+ .bootstrap(context)
+ val trace = experiment.trace
+ val tasks = trace.jobs.flatMap { it.tasks }
+
+ // Schedule all messages in the trace
+ tasks.forEach { task ->
+ if (task is Task) {
+ context.schedule(task, section.datacenter, delay = task.startTime)
+ }
+ }
+
+ return JpaModel(experiment, topology)
+ }
+}
diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt
new file mode 100644
index 00000000..6b12a68a
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt
@@ -0,0 +1,14 @@
+package com.atlarge.opendc.model.odc
+
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment
+import com.atlarge.opendc.model.topology.MutableTopology
+
+/**
+ * Implementation of the [OdcModel] using a JPA backend.
+ *
+ * @property experiment The experiment that is simulated.
+ * @property topology The topology the simulation runs on.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+data class JpaModel(val experiment: Experiment, val topology: MutableTopology): OdcModel, MutableTopology by topology
+
diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt
new file mode 100644
index 00000000..4f683f65
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt
new file mode 100644
index 00000000..c1123490
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt
new file mode 100644
index 00000000..7c793cba
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.converter
+
+import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler
+import com.atlarge.opendc.model.odc.platform.scheduler.FifoScheduler
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt
new file mode 100644
index 00000000..98a51401
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt
new file mode 100644
index 00000000..8dcc1fc5
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.simulator.Duration
+import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt
new file mode 100644
index 00000000..62a56bab
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.simulator.Instant
+import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler
+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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt
new file mode 100644
index 00000000..3e84707f
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt
new file mode 100644
index 00000000..6b4f77a5
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt
new file mode 100644
index 00000000..192e345c
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.platform.workload.Job
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt
new file mode 100644
index 00000000..b1a2e428
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt
new file mode 100644
index 00000000..3bd017bc
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.simulator.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt
new file mode 100644
index 00000000..f24cf6a0
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt
new file mode 100644
index 00000000..571c6e88
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt
new file mode 100644
index 00000000..70f326c2
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt
new file mode 100644
index 00000000..49db076c
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt
new file mode 100644
index 00000000..574677da
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt
new file mode 100644
index 00000000..79b2d74d
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.simulator.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt
new file mode 100644
index 00000000..9379478f
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.simulator.Instant
+import com.atlarge.opendc.model.odc.platform.workload.Task
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt
new file mode 100644
index 00000000..dab8b345
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.simulator.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt
new file mode 100644
index 00000000..eddc1a03
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.integration.jpa.schema
+
+import com.atlarge.opendc.model.odc.platform.workload.Job
+import com.atlarge.opendc.model.odc.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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt
new file mode 100644
index 00000000..08e89c59
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt
@@ -0,0 +1,179 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.platform
+
+import mu.KotlinLogging
+import com.atlarge.opendc.model.odc.integration.jpa.schema.ExperimentState
+import com.atlarge.opendc.model.odc.integration.jpa.schema.MachineState
+import com.atlarge.opendc.model.odc.integration.jpa.schema.TaskState as InternalTaskState
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Trace as InternalTrace
+import com.atlarge.opendc.model.odc.integration.jpa.transaction
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment as InternalExperiment
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Task as InternalTask
+import com.atlarge.opendc.simulator.kernel.KernelFactory
+import com.atlarge.opendc.simulator.Duration
+import com.atlarge.opendc.model.odc.JpaBootstrap
+import com.atlarge.opendc.model.odc.platform.workload.TaskState
+import com.atlarge.opendc.model.odc.topology.container.Rack
+import com.atlarge.opendc.model.odc.topology.container.Room
+import com.atlarge.opendc.model.odc.topology.machine.Machine
+import com.atlarge.opendc.simulator.platform.Experiment
+import com.atlarge.opendc.model.topology.destinations
+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 using the specified simulation kernel implementation.
+ *
+ * @param factory The simulation kernel implementation to use.
+ * @param timeout The maximum duration of the experiment before returning to the caller.
+ * @return The result of the experiment or `null`.
+ */
+ override fun run(factory: KernelFactory, timeout: Duration): Unit? {
+ 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 bootstrap = JpaBootstrap(experiment)
+ val simulation = factory.create(bootstrap)
+ val topology = simulation.model
+
+ val section = experiment.path.sections.first()
+ val trace = experiment.trace
+ val tasks = trace.jobs.flatMap { it.tasks }
+
+ // 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 }) {
+ // If we have reached a timeout, return
+ if (simulation.time >= timeout)
+ return null
+
+ // Collect data of simulation cycle
+ manager.transaction {
+ experiment.last = simulation.time
+
+ machines.forEach { machine ->
+ val state = simulation.run { machine.state }
+ val wrapped = MachineState(0,
+ machine as com.atlarge.opendc.model.odc.integration.jpa.schema.Machine,
+ state.task as com.atlarge.opendc.model.odc.integration.jpa.schema.Task?,
+ experiment,
+ simulation.time,
+ state.temperature,
+ state.memory,
+ state.load
+ )
+ manager.persist(wrapped)
+ }
+
+ trace.jobs.asSequence()
+ .flatMap { it.tasks.asSequence() }
+ .forEach { task ->
+ val state = InternalTaskState(0,
+ task as com.atlarge.opendc.model.odc.integration.jpa.schema.Task,
+ experiment,
+ simulation.time,
+ task.remaining.toInt(),
+ 1
+ )
+ manager.persist(state)
+ }
+ }
+
+ // Run next simulation cycle
+ simulation.run(simulation.time + 1)
+ }
+
+ // Set the experiment state
+ manager.transaction {
+ experiment.state = ExperimentState.FINISHED
+ }
+
+ logger.info { "Kernel 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" }
+
+ return Unit
+ }
+
+ /**
+ * Run the experiment on the specified simulation kernel implementation.
+ *
+ * @param factory The factory to create the simulation kernel with.
+ * @throws IllegalStateException if the simulation is already running or finished.
+ */
+ override fun run(factory: KernelFactory) = run(factory, -1)!!
+
+ /**
+ * 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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt
new file mode 100644
index 00000000..698a1129
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/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 com.atlarge.opendc.model.odc.platform
+
+import com.atlarge.opendc.simulator.platform.Experiment
+import com.atlarge.opendc.model.odc.integration.jpa.transaction
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment as InternalExperiment
+import com.atlarge.opendc.model.odc.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 is not guaranteed to run in constant 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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt
new file mode 100644
index 00000000..3f7c1b8e
--- /dev/null
+++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt
@@ -0,0 +1,95 @@
+/*
+ * 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 com.atlarge.opendc.model.odc.topology
+
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Rack
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Room
+import com.atlarge.opendc.model.odc.integration.jpa.schema.RoomObject
+import com.atlarge.opendc.model.odc.integration.jpa.schema.Section
+import com.atlarge.opendc.model.topology.AdjacencyList
+import com.atlarge.opendc.model.topology.Topology
+import com.atlarge.opendc.model.topology.MutableTopology
+import com.atlarge.opendc.model.topology.TopologyBuilder
+import com.atlarge.opendc.model.topology.TopologyFactory
+
+/**
+ * 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-model-odc/jpa/src/main/resources/jpa/schema.xml b/opendc-model-odc/jpa/src/main/resources/jpa/schema.xml
new file mode 100644
index 00000000..9c5e58bd
--- /dev/null
+++ b/opendc-model-odc/jpa/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>com.atlarge.opendc.model.odc.integration.jpa.schema</package>
+
+ <entity class="Experiment" access="FIELD" name="experiments">
+ <convert converter="com.atlarge.opendc.model.odc.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="com.atlarge.opendc.model.odc.integration.jpa.schema.Trace">
+ <join-column name="trace_id" />
+ </many-to-one>
+
+ <one-to-one name="path" target-entity="com.atlarge.opendc.model.odc.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="com.atlarge.opendc.model.odc.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="com.atlarge.opendc.model.odc.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="com.atlarge.opendc.model.odc.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>
diff --git a/opendc-model-odc/setup/Dockerfile b/opendc-model-odc/setup/Dockerfile
new file mode 100644
index 00000000..70e6fe11
--- /dev/null
+++ b/opendc-model-odc/setup/Dockerfile
@@ -0,0 +1,30 @@
+# Docker mysql image for the OpenDC simulator project
+# This image requires the context to be set to the root directory of the project in order to correctly build.
+FROM gradle:alpine
+MAINTAINER Fabian Mastenbroek <f.s.mastenbroek@student.tudelft.nl>
+
+# Set the home directory to our gradle user's home.
+ENV HOME=/home/gradle
+ENV APP_HOME=$HOME/simulator
+
+# Copy OpenDC simulator
+COPY ./ $APP_HOME
+
+# Build as root
+USER root
+
+# Set the working directory to the simulator
+WORKDIR $APP_HOME
+
+# Build the application
+RUN gradle --no-daemon :opendc-model-odc:setup:installDist
+
+# Fix permissions
+RUN chown -R gradle:gradle $APP_HOME
+
+# Downgrade user
+USER gradle
+
+# Start the Gradle application on run
+CMD opendc-odc-model/setup/build/install/setup/bin/setup
+
diff --git a/opendc-model-odc/setup/build.gradle b/opendc-model-odc/setup/build.gradle
new file mode 100644
index 00000000..042b8f37
--- /dev/null
+++ b/opendc-model-odc/setup/build.gradle
@@ -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.
+ */
+
+/* Build configuration */
+buildscript {
+ ext.kotlin_version = '1.2.10'
+ ext.dokka_version = '0.9.15'
+
+ repositories {
+ mavenCentral()
+ jcenter()
+ }
+
+ 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"
+ }
+}
+
+apply plugin: 'java'
+apply plugin: 'application'
+apply plugin: 'kotlin'
+apply plugin: 'org.jetbrains.dokka'
+
+mainClassName = "nl.atlarge.opendc.model.odc.platform.JpaPlatformRunnerKt"
+
+compileKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+kotlin {
+ experimental {
+ coroutines 'enable'
+ }
+}
+
+dokka {
+ outputFormat = 'html'
+ outputDirectory = "$buildDir/javadoc"
+}
+
+/* Project configuration */
+group 'com.atlarge.opendc'
+version '1.1'
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+ compile project(':opendc-model-odc:jpa')
+ compile project(':opendc-kernel-omega')
+
+ 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'
+}
diff --git a/opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.kt b/opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.kt
new file mode 100644
index 00000000..3f0fe589
--- /dev/null
+++ b/opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.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 platform
+
+import com.atlarge.opendc.model.odc.platform.JpaExperimentManager
+import com.atlarge.opendc.omega.OmegaKernelFactory
+import mu.KotlinLogging
+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 timeout = 10000L
+ val threads = 4
+ val executorService = Executors.newFixedThreadPool(threads)
+ val experiments = JpaExperimentManager(factory)
+ val kernel = OmegaKernelFactory
+
+ 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, timeout) }
+ }
+ }
+
+ Thread.sleep(500)
+ }
+}
diff --git a/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml b/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 00000000..0e40dc6e
--- /dev/null
+++ b/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,41 @@
+<?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-simulator">
+ <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="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
+ <property name="hibernate.show_sql" value="false" />
+ <property name="hibernate.hbm2ddl.auto" value="validate" />
+ <property name="hibernate.jdbc.batch_size" value="50" />
+ </properties>
+ </persistence-unit>
+</persistence>