summaryrefslogtreecommitdiff
path: root/simulator/opendc-compute/opendc-compute-service/src
diff options
context:
space:
mode:
Diffstat (limited to 'simulator/opendc-compute/opendc-compute-service/src')
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt85
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt103
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt41
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt31
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt68
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt61
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt113
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt500
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt44
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt66
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt56
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt153
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt50
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt66
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt64
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt40
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt39
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt36
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt391
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt80
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt81
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt285
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml38
31 files changed, 0 insertions, 2790 deletions
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt
deleted file mode 100644
index 1873eb99..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service
-
-import io.opentelemetry.api.metrics.Meter
-import org.opendc.compute.api.ComputeClient
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.scheduler.ComputeScheduler
-import java.time.Clock
-import kotlin.coroutines.CoroutineContext
-
-/**
- * The [ComputeService] hosts the API implementation of the OpenDC Compute service.
- */
-public interface ComputeService : AutoCloseable {
- /**
- * The hosts that are used by the compute service.
- */
- public val hosts: Set<Host>
-
- /**
- * The number of hosts available in the system.
- */
- public val hostCount: Int
-
- /**
- * Create a new [ComputeClient] to control the compute service.
- */
- public fun newClient(): ComputeClient
-
- /**
- * Add a [host] to the scheduling pool of the compute service.
- */
- public fun addHost(host: Host)
-
- /**
- * Remove a [host] from the scheduling pool of the compute service.
- */
- public fun removeHost(host: Host)
-
- /**
- * Terminate the lifecycle of the compute service, stopping all running instances.
- */
- public override fun close()
-
- public companion object {
- /**
- * Construct a new [ComputeService] implementation.
- *
- * @param context The [CoroutineContext] to use in the service.
- * @param clock The clock instance to use.
- * @param scheduler The scheduler implementation to use.
- */
- public operator fun invoke(
- context: CoroutineContext,
- clock: Clock,
- meter: Meter,
- scheduler: ComputeScheduler,
- schedulingQuantum: Long = 300000,
- ): ComputeService {
- return ComputeServiceImpl(context, clock, meter, scheduler, schedulingQuantum)
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
deleted file mode 100644
index bed15dfd..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.driver
-
-import org.opendc.compute.api.Server
-import java.util.*
-
-/**
- * Base interface for representing compute resources that host virtualized [Server] instances.
- */
-public interface Host {
- /**
- * A unique identifier representing the host.
- */
- public val uid: UUID
-
- /**
- * The name of this host.
- */
- public val name: String
-
- /**
- * The machine model of the host.
- */
- public val model: HostModel
-
- /**
- * The state of the host.
- */
- public val state: HostState
-
- /**
- * Meta-data associated with the host.
- */
- public val meta: Map<String, Any>
-
- /**
- * Determine whether the specified [instance][server] can still fit on this host.
- */
- public fun canFit(server: Server): Boolean
-
- /**
- * Register the specified [instance][server] on the host.
- *
- * Once the method returns, the instance should be running if [start] is true or else the instance should be
- * stopped.
- */
- public suspend fun spawn(server: Server, start: Boolean = true)
-
- /**
- * Determine whether the specified [instance][server] exists on the host.
- */
- public operator fun contains(server: Server): Boolean
-
- /**
- * Start the server [instance][server] if it is currently not running on this host.
- *
- * @throws IllegalArgumentException if the server is not present on the host.
- */
- public suspend fun start(server: Server)
-
- /**
- * Stop the server [instance][server] if it is currently running on this host.
- *
- * @throws IllegalArgumentException if the server is not present on the host.
- */
- public suspend fun stop(server: Server)
-
- /**
- * Delete the specified [instance][server] on this host and cleanup all resources associated with it.
- */
- public suspend fun delete(server: Server)
-
- /**
- * Add a [HostListener] to this host.
- */
- public fun addListener(listener: HostListener)
-
- /**
- * Remove a [HostListener] from this host.
- */
- public fun removeListener(listener: HostListener)
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt
deleted file mode 100644
index f076cae3..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.driver
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-
-/**
- * Listener interface for events originating from a [Host].
- */
-public interface HostListener {
- /**
- * This method is invoked when the state of an [instance][server] on [host] changes.
- */
- public fun onStateChanged(host: Host, server: Server, newState: ServerState) {}
-
- /**
- * This method is invoked when the state of a [Host] has changed.
- */
- public fun onStateChanged(host: Host, newState: HostState) {}
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt
deleted file mode 100644
index 5632a55e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.driver
-
-/**
- * Describes the static machine properties of the host.
- *
- * @property vcpuCount The number of logical processing cores available for this host.
- * @property memorySize The amount of memory available for this host in MB.
- */
-public data class HostModel(public val cpuCount: Int, public val memorySize: Long)
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt
deleted file mode 100644
index 6d85ee2d..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.driver
-
-/**
- * The state of a host.
- */
-public enum class HostState {
- /**
- * The host is up.
- */
- UP,
-
- /**
- * The host is down.
- */
- DOWN
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt
deleted file mode 100644
index 4a8d3046..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import org.opendc.compute.api.Flavor
-import java.util.UUID
-
-/**
- * A [Flavor] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientFlavor(private val delegate: Flavor) : Flavor {
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var cpuCount: Int = delegate.cpuCount
- private set
-
- override var memorySize: Long = delegate.memorySize
- private set
-
- override var labels: Map<String, String> = delegate.labels.toMap()
- private set
-
- override var meta: Map<String, Any> = delegate.meta.toMap()
- private set
-
- override suspend fun delete() {
- delegate.delete()
- }
-
- override suspend fun refresh() {
- delegate.refresh()
-
- name = delegate.name
- cpuCount = delegate.cpuCount
- memorySize = delegate.memorySize
- labels = delegate.labels
- meta = delegate.meta
- }
-
- override fun equals(other: Any?): Boolean = other is Flavor && other.uid == uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Flavor[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt
deleted file mode 100644
index e0b5c171..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import org.opendc.compute.api.Image
-import java.util.*
-
-/**
- * An [Image] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientImage(private val delegate: Image) : Image {
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var labels: Map<String, String> = delegate.labels.toMap()
- private set
-
- override var meta: Map<String, Any> = delegate.meta.toMap()
- private set
-
- override suspend fun delete() {
- delegate.delete()
- refresh()
- }
-
- override suspend fun refresh() {
- delegate.refresh()
-
- name = delegate.name
- labels = delegate.labels
- meta = delegate.meta
- }
-
- override fun equals(other: Any?): Boolean = other is Image && other.uid == uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Image[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt
deleted file mode 100644
index f2929bf3..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.api.ServerWatcher
-import java.util.*
-
-/**
- * A [Server] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientServer(private val delegate: Server) : Server, ServerWatcher {
- private val watchers = mutableListOf<ServerWatcher>()
-
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var flavor: Flavor = delegate.flavor
- private set
-
- override var image: Image = delegate.image
- private set
-
- override var labels: Map<String, String> = delegate.labels.toMap()
- private set
-
- override var meta: Map<String, Any> = delegate.meta.toMap()
- private set
-
- override var state: ServerState = delegate.state
- private set
-
- override suspend fun start() {
- delegate.start()
- refresh()
- }
-
- override suspend fun stop() {
- delegate.stop()
- refresh()
- }
-
- override suspend fun delete() {
- delegate.delete()
- refresh()
- }
-
- override fun watch(watcher: ServerWatcher) {
- if (watchers.isEmpty()) {
- delegate.watch(this)
- }
-
- watchers += watcher
- }
-
- override fun unwatch(watcher: ServerWatcher) {
- watchers += watcher
-
- if (watchers.isEmpty()) {
- delegate.unwatch(this)
- }
- }
-
- override suspend fun refresh() {
- delegate.refresh()
-
- name = delegate.name
- flavor = delegate.flavor
- image = delegate.image
- labels = delegate.labels
- meta = delegate.meta
- state = delegate.state
- }
-
- override fun onStateChanged(server: Server, newState: ServerState) {
- val watchers = watchers
-
- for (watcher in watchers) {
- watcher.onStateChanged(this, newState)
- }
- }
-
- override fun equals(other: Any?): Boolean = other is Server && other.uid == uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Server[uid=$uid,name=$name,state=$state]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
deleted file mode 100644
index 8af5f86e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import io.opentelemetry.api.metrics.Meter
-import kotlinx.coroutines.*
-import mu.KotlinLogging
-import org.opendc.compute.api.*
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.ComputeScheduler
-import org.opendc.utils.TimerScheduler
-import java.time.Clock
-import java.util.*
-import kotlin.coroutines.CoroutineContext
-import kotlin.math.max
-
-/**
- * Internal implementation of the OpenDC Compute service.
- *
- * @param context The [CoroutineContext] to use.
- * @param clock The clock instance to keep track of time.
- */
-internal class ComputeServiceImpl(
- private val context: CoroutineContext,
- private val clock: Clock,
- private val meter: Meter,
- private val scheduler: ComputeScheduler,
- private val schedulingQuantum: Long
-) : ComputeService, HostListener {
- /**
- * The [CoroutineScope] of the service bounded by the lifecycle of the service.
- */
- private val scope = CoroutineScope(context + Job())
-
- /**
- * The logger instance of this server.
- */
- private val logger = KotlinLogging.logger {}
-
- /**
- * The [Random] instance used to generate unique identifiers for the objects.
- */
- private val random = Random(0)
-
- /**
- * A mapping from host to host view.
- */
- private val hostToView = mutableMapOf<Host, HostView>()
-
- /**
- * The available hypervisors.
- */
- private val availableHosts: MutableSet<HostView> = mutableSetOf()
-
- /**
- * The servers that should be launched by the service.
- */
- private val queue: Deque<SchedulingRequest> = ArrayDeque()
-
- /**
- * The active servers in the system.
- */
- private val activeServers: MutableMap<Server, Host> = mutableMapOf()
-
- /**
- * The registered flavors for this compute service.
- */
- internal val flavors = mutableMapOf<UUID, InternalFlavor>()
-
- /**
- * The registered images for this compute service.
- */
- internal val images = mutableMapOf<UUID, InternalImage>()
-
- /**
- * The registered servers for this compute service.
- */
- private val servers = mutableMapOf<UUID, InternalServer>()
-
- private var maxCores = 0
- private var maxMemory = 0L
-
- /**
- * The number of servers that have been submitted to the service for provisioning.
- */
- private val _submittedServers = meter.longCounterBuilder("servers.submitted")
- .setDescription("Number of start requests")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that failed to be scheduled.
- */
- private val _unscheduledServers = meter.longCounterBuilder("servers.unscheduled")
- .setDescription("Number of unscheduled servers")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that are waiting to be provisioned.
- */
- private val _waitingServers = meter.longUpDownCounterBuilder("servers.waiting")
- .setDescription("Number of servers waiting to be provisioned")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that are waiting to be provisioned.
- */
- private val _runningServers = meter.longUpDownCounterBuilder("servers.active")
- .setDescription("Number of servers currently running")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that have finished running.
- */
- private val _finishedServers = meter.longCounterBuilder("servers.finished")
- .setDescription("Number of servers that finished running")
- .setUnit("1")
- .build()
-
- /**
- * The number of hosts registered at the compute service.
- */
- private val _hostCount = meter.longUpDownCounterBuilder("hosts.total")
- .setDescription("Number of hosts")
- .setUnit("1")
- .build()
-
- /**
- * The number of available hosts registered at the compute service.
- */
- private val _availableHostCount = meter.longUpDownCounterBuilder("hosts.available")
- .setDescription("Number of available hosts")
- .setUnit("1")
- .build()
-
- /**
- * The [TimerScheduler] to use for scheduling the scheduler cycles.
- */
- private var timerScheduler: TimerScheduler<Unit> = TimerScheduler(scope.coroutineContext, clock)
-
- override val hosts: Set<Host>
- get() = hostToView.keys
-
- override val hostCount: Int
- get() = hostToView.size
-
- override fun newClient(): ComputeClient {
- check(scope.isActive) { "Service is already closed" }
- return object : ComputeClient {
- private var isClosed: Boolean = false
-
- override suspend fun queryFlavors(): List<Flavor> {
- check(!isClosed) { "Client is already closed" }
-
- return flavors.values.map { ClientFlavor(it) }
- }
-
- override suspend fun findFlavor(id: UUID): Flavor? {
- check(!isClosed) { "Client is already closed" }
-
- return flavors[id]?.let { ClientFlavor(it) }
- }
-
- override suspend fun newFlavor(
- name: String,
- cpuCount: Int,
- memorySize: Long,
- labels: Map<String, String>,
- meta: Map<String, Any>
- ): Flavor {
- check(!isClosed) { "Client is already closed" }
-
- val uid = UUID(clock.millis(), random.nextLong())
- val flavor = InternalFlavor(
- this@ComputeServiceImpl,
- uid,
- name,
- cpuCount,
- memorySize,
- labels,
- meta
- )
-
- flavors[uid] = flavor
-
- return ClientFlavor(flavor)
- }
-
- override suspend fun queryImages(): List<Image> {
- check(!isClosed) { "Client is already closed" }
-
- return images.values.map { ClientImage(it) }
- }
-
- override suspend fun findImage(id: UUID): Image? {
- check(!isClosed) { "Client is already closed" }
-
- return images[id]?.let { ClientImage(it) }
- }
-
- override suspend fun newImage(name: String, labels: Map<String, String>, meta: Map<String, Any>): Image {
- check(!isClosed) { "Client is already closed" }
-
- val uid = UUID(clock.millis(), random.nextLong())
- val image = InternalImage(this@ComputeServiceImpl, uid, name, labels, meta)
-
- images[uid] = image
-
- return ClientImage(image)
- }
-
- override suspend fun newServer(
- name: String,
- image: Image,
- flavor: Flavor,
- labels: Map<String, String>,
- meta: Map<String, Any>,
- start: Boolean
- ): Server {
- check(!isClosed) { "Client is closed" }
-
- val uid = UUID(clock.millis(), random.nextLong())
- val server = InternalServer(
- this@ComputeServiceImpl,
- uid,
- name,
- requireNotNull(flavors[flavor.uid]) { "Unknown flavor" },
- requireNotNull(images[image.uid]) { "Unknown image" },
- labels.toMutableMap(),
- meta.toMutableMap()
- )
-
- servers[uid] = server
-
- if (start) {
- server.start()
- }
-
- return ClientServer(server)
- }
-
- override suspend fun findServer(id: UUID): Server? {
- check(!isClosed) { "Client is already closed" }
-
- return servers[id]?.let { ClientServer(it) }
- }
-
- override suspend fun queryServers(): List<Server> {
- check(!isClosed) { "Client is already closed" }
-
- return servers.values.map { ClientServer(it) }
- }
-
- override fun close() {
- isClosed = true
- }
-
- override fun toString(): String = "ComputeClient"
- }
- }
-
- override fun addHost(host: Host) {
- // Check if host is already known
- if (host in hostToView) {
- return
- }
-
- val hv = HostView(host)
- maxCores = max(maxCores, host.model.cpuCount)
- maxMemory = max(maxMemory, host.model.memorySize)
- hostToView[host] = hv
-
- if (host.state == HostState.UP) {
- _availableHostCount.add(1)
- availableHosts += hv
- }
-
- scheduler.addHost(hv)
- _hostCount.add(1)
- host.addListener(this)
- }
-
- override fun removeHost(host: Host) {
- val view = hostToView.remove(host)
- if (view != null) {
- if (availableHosts.remove(view)) {
- _availableHostCount.add(-1)
- }
- scheduler.removeHost(view)
- host.removeListener(this)
- _hostCount.add(-1)
- }
- }
-
- override fun close() {
- scope.cancel()
- }
-
- internal fun schedule(server: InternalServer): SchedulingRequest {
- logger.debug { "Enqueueing server ${server.uid} to be assigned to host." }
-
- val request = SchedulingRequest(server)
- queue.add(request)
- _submittedServers.add(1)
- _waitingServers.add(1)
- requestSchedulingCycle()
- return request
- }
-
- internal fun delete(flavor: InternalFlavor) {
- flavors.remove(flavor.uid)
- }
-
- internal fun delete(image: InternalImage) {
- images.remove(image.uid)
- }
-
- internal fun delete(server: InternalServer) {
- servers.remove(server.uid)
- }
-
- /**
- * Indicate that a new scheduling cycle is needed due to a change to the service's state.
- */
- private fun requestSchedulingCycle() {
- // Bail out in case we have already requested a new cycle or the queue is empty.
- if (timerScheduler.isTimerActive(Unit) || queue.isEmpty()) {
- return
- }
-
- // We assume that the provisioner runs at a fixed slot every time quantum (e.g t=0, t=60, t=120).
- // This is important because the slices of the VMs need to be aligned.
- // We calculate here the delay until the next scheduling slot.
- val delay = schedulingQuantum - (clock.millis() % schedulingQuantum)
-
- timerScheduler.startSingleTimer(Unit, delay) {
- doSchedule()
- }
- }
-
- /**
- * Run a single scheduling iteration.
- */
- private fun doSchedule() {
- while (queue.isNotEmpty()) {
- val request = queue.peek()
-
- if (request.isCancelled) {
- queue.poll()
- _waitingServers.add(-1)
- continue
- }
-
- val server = request.server
- val hv = scheduler.select(request.server)
- if (hv == null || !hv.host.canFit(server)) {
- logger.trace { "Server $server selected for scheduling but no capacity available for it at the moment" }
-
- if (server.flavor.memorySize > maxMemory || server.flavor.cpuCount > maxCores) {
- // Remove the incoming image
- queue.poll()
- _waitingServers.add(-1)
- _unscheduledServers.add(1)
-
- logger.warn("Failed to spawn $server: does not fit [${clock.millis()}]")
-
- server.state = ServerState.ERROR
- continue
- } else {
- break
- }
- }
-
- val host = hv.host
-
- // Remove request from queue
- queue.poll()
- _waitingServers.add(-1)
-
- logger.info { "Assigned server $server to host $host." }
-
- // Speculatively update the hypervisor view information to prevent other images in the queue from
- // deciding on stale values.
- hv.instanceCount++
- hv.provisionedCores += server.flavor.cpuCount
- hv.availableMemory -= server.flavor.memorySize // XXX Temporary hack
-
- scope.launch {
- try {
- server.host = host
- host.spawn(server)
- activeServers[server] = host
- } catch (e: Throwable) {
- logger.error("Failed to deploy VM", e)
-
- hv.instanceCount--
- hv.provisionedCores -= server.flavor.cpuCount
- hv.availableMemory += server.flavor.memorySize
- }
- }
- }
- }
-
- /**
- * A request to schedule an [InternalServer] onto one of the [Host]s.
- */
- internal data class SchedulingRequest(val server: InternalServer) {
- /**
- * A flag to indicate that the request is cancelled.
- */
- var isCancelled: Boolean = false
- }
-
- override fun onStateChanged(host: Host, newState: HostState) {
- when (newState) {
- HostState.UP -> {
- logger.debug { "[${clock.millis()}] Host ${host.uid} state changed: $newState" }
-
- val hv = hostToView[host]
- if (hv != null) {
- // Corner case for when the hypervisor already exists
- availableHosts += hv
- _availableHostCount.add(1)
- }
-
- // Re-schedule on the new machine
- requestSchedulingCycle()
- }
- HostState.DOWN -> {
- logger.debug { "[${clock.millis()}] Host ${host.uid} state changed: $newState" }
-
- val hv = hostToView[host] ?: return
- availableHosts -= hv
- _availableHostCount.add(-1)
-
- requestSchedulingCycle()
- }
- }
- }
-
- override fun onStateChanged(host: Host, server: Server, newState: ServerState) {
- require(server is InternalServer) { "Invalid server type passed to service" }
-
- if (server.host != host) {
- // This can happen when a server is rescheduled and started on another machine, while being deleted from
- // the old machine.
- return
- }
-
- server.state = newState
-
- if (newState == ServerState.RUNNING) {
- _runningServers.add(1)
- } else if (newState == ServerState.TERMINATED || newState == ServerState.DELETED) {
- logger.info { "[${clock.millis()}] Server ${server.uid} ${server.name} ${server.flavor} finished." }
-
- activeServers -= server
- _runningServers.add(-1)
- _finishedServers.add(1)
-
- val hv = hostToView[host]
- if (hv != null) {
- hv.provisionedCores -= server.flavor.cpuCount
- hv.instanceCount--
- hv.availableMemory += server.flavor.memorySize
- } else {
- logger.error { "Unknown host $host" }
- }
-
- // Try to reschedule if needed
- requestSchedulingCycle()
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt
deleted file mode 100644
index e2f33f11..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.driver.Host
-import java.util.UUID
-
-/**
- * A view of a [Host] as seen from the [ComputeService]
- */
-public class HostView(public val host: Host) {
- /**
- * The unique identifier of the host.
- */
- public val uid: UUID
- get() = host.uid
-
- public var instanceCount: Int = 0
- public var availableMemory: Long = host.model.memorySize
- public var provisionedCores: Int = 0
-
- override fun toString(): String = "HostView[host=$host]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt
deleted file mode 100644
index b8fb6279..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import org.opendc.compute.api.Flavor
-import java.util.*
-
-/**
- * Internal stateful representation of a [Flavor].
- */
-internal class InternalFlavor(
- private val service: ComputeServiceImpl,
- override val uid: UUID,
- name: String,
- cpuCount: Int,
- memorySize: Long,
- labels: Map<String, String>,
- meta: Map<String, Any>
-) : Flavor {
- override var name: String = name
- private set
-
- override var cpuCount: Int = cpuCount
- private set
-
- override var memorySize: Long = memorySize
- private set
-
- override val labels: MutableMap<String, String> = labels.toMutableMap()
-
- override val meta: MutableMap<String, Any> = meta.toMutableMap()
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override suspend fun delete() {
- service.delete(this)
- }
-
- override fun equals(other: Any?): Boolean = other is Flavor && uid == other.uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Flavor[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt
deleted file mode 100644
index d9ed5896..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import org.opendc.compute.api.Image
-import java.util.*
-
-/**
- * Internal stateful representation of an [Image].
- */
-internal class InternalImage(
- private val service: ComputeServiceImpl,
- override val uid: UUID,
- override val name: String,
- labels: Map<String, String>,
- meta: Map<String, Any>
-) : Image {
-
- override val labels: MutableMap<String, String> = labels.toMutableMap()
-
- override val meta: MutableMap<String, Any> = meta.toMutableMap()
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override suspend fun delete() {
- service.delete(this)
- }
-
- override fun equals(other: Any?): Boolean = other is Image && uid == other.uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Image[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt
deleted file mode 100644
index d9d0f3fc..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.internal
-
-import mu.KotlinLogging
-import org.opendc.compute.api.*
-import org.opendc.compute.service.driver.Host
-import java.util.UUID
-
-/**
- * Internal implementation of the [Server] interface.
- */
-internal class InternalServer(
- private val service: ComputeServiceImpl,
- override val uid: UUID,
- override val name: String,
- override val flavor: InternalFlavor,
- override val image: InternalImage,
- override val labels: MutableMap<String, String>,
- override val meta: MutableMap<String, Any>
-) : Server {
- /**
- * The logger instance of this server.
- */
- private val logger = KotlinLogging.logger {}
-
- /**
- * The watchers of this server object.
- */
- private val watchers = mutableListOf<ServerWatcher>()
-
- /**
- * The [Host] that has been assigned to host the server.
- */
- internal var host: Host? = null
-
- /**
- * The current scheduling request.
- */
- private var request: ComputeServiceImpl.SchedulingRequest? = null
-
- override suspend fun start() {
- when (state) {
- ServerState.RUNNING -> {
- logger.debug { "User tried to start server but server is already running" }
- return
- }
- ServerState.PROVISIONING -> {
- logger.debug { "User tried to start server but request is already pending: doing nothing" }
- return
- }
- ServerState.DELETED -> {
- logger.warn { "User tried to start terminated server" }
- throw IllegalStateException("Server is terminated")
- }
- else -> {
- logger.info { "User requested to start server $uid" }
- state = ServerState.PROVISIONING
- assert(request == null) { "Scheduling request already active" }
- request = service.schedule(this)
- }
- }
- }
-
- override suspend fun stop() {
- when (state) {
- ServerState.PROVISIONING -> {
- cancelProvisioningRequest()
- state = ServerState.TERMINATED
- }
- ServerState.RUNNING, ServerState.ERROR -> {
- val host = checkNotNull(host) { "Server not running" }
- host.stop(this)
- }
- ServerState.TERMINATED, ServerState.DELETED -> {} // No work needed
- }
- }
-
- override suspend fun delete() {
- when (state) {
- ServerState.PROVISIONING, ServerState.TERMINATED -> {
- cancelProvisioningRequest()
- service.delete(this)
- state = ServerState.DELETED
- }
- ServerState.RUNNING, ServerState.ERROR -> {
- val host = checkNotNull(host) { "Server not running" }
- host.delete(this)
- service.delete(this)
- state = ServerState.DELETED
- }
- else -> {} // No work needed
- }
- }
-
- override fun watch(watcher: ServerWatcher) {
- watchers += watcher
- }
-
- override fun unwatch(watcher: ServerWatcher) {
- watchers -= watcher
- }
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override var state: ServerState = ServerState.TERMINATED
- set(value) {
- if (value != field) {
- watchers.forEach { it.onStateChanged(this, value) }
- }
-
- field = value
- }
-
- /**
- * Cancel the provisioning request if active.
- */
- private fun cancelProvisioningRequest() {
- val request = request
- if (request != null) {
- this.request = null
- request.isCancelled = true
- }
- }
-
- override fun equals(other: Any?): Boolean = other is Server && uid == other.uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Server[uid=$uid,state=$state]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt
deleted file mode 100644
index a2ab3a2e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A generic scheduler interface used by the [ComputeService] to select hosts to place [Server]s on.
- */
-public interface ComputeScheduler {
- /**
- * Register the specified [host] to be used for scheduling.
- */
- public fun addHost(host: HostView)
-
- /**
- * Remove the specified [host] to be removed from the scheduling pool.
- */
- public fun removeHost(host: HostView)
-
- /**
- * Select a host for the specified [server].
- *
- * @param server The server to select a host for.
- * @return The host to schedule the server on or `null` if no server is available.
- */
- public fun select(server: Server): HostView?
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
deleted file mode 100644
index 0fd5b2a4..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import org.opendc.compute.service.scheduler.filters.HostFilter
-import org.opendc.compute.service.scheduler.weights.HostWeigher
-
-/**
- * A [ComputeScheduler] implementation that uses filtering and weighing passes to select
- * the host to schedule a [Server] on.
- *
- * This implementation is based on the filter scheduler from OpenStack Nova.
- * See: https://docs.openstack.org/nova/latest/user/filter-scheduler.html
- */
-public class FilterScheduler(private val filters: List<HostFilter>, private val weighers: List<Pair<HostWeigher, Double>>) : ComputeScheduler {
- /**
- * The pool of hosts available to the scheduler.
- */
- private val hosts = mutableListOf<HostView>()
-
- override fun addHost(host: HostView) {
- hosts.add(host)
- }
-
- override fun removeHost(host: HostView) {
- hosts.remove(host)
- }
-
- override fun select(server: Server): HostView? {
- return hosts.asSequence()
- .filter { host ->
- for (filter in filters) {
- if (!filter.test(host, server))
- return@filter false
- }
-
- true
- }
- .sortedByDescending { host ->
- weighers.sumByDouble { (weigher, factor) -> weigher.getWeight(host, server) * factor }
- }
- .firstOrNull()
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
deleted file mode 100644
index 284c1f91..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2020 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler
-
-import mu.KotlinLogging
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * Policy replaying VM-cluster assignment.
- *
- * Within each cluster, the active servers on each node determine which node gets
- * assigned the VM image.
- */
-public class ReplayScheduler(private val vmPlacements: Map<String, String>) : ComputeScheduler {
- private val logger = KotlinLogging.logger {}
-
- /**
- * The pool of hosts available to the scheduler.
- */
- private val hosts = mutableListOf<HostView>()
-
- override fun addHost(host: HostView) {
- hosts.add(host)
- }
-
- override fun removeHost(host: HostView) {
- hosts.remove(host)
- }
-
- override fun select(server: Server): HostView? {
- val clusterName = vmPlacements[server.name]
- ?: throw IllegalStateException("Could not find placement data in VM placement file for VM ${server.name}")
- val machinesInCluster = hosts.filter { it.host.name.contains(clusterName) }
-
- if (machinesInCluster.isEmpty()) {
- logger.info { "Could not find any machines belonging to cluster $clusterName for image ${server.name}, assigning randomly." }
- return hosts.maxByOrNull { it.availableMemory }
- }
-
- return machinesInCluster.maxByOrNull { it.availableMemory }
- ?: throw IllegalStateException("Cloud not find any machine and could not randomly assign")
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt
deleted file mode 100644
index 072440c5..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostFilter] that checks whether the capabilities provided by the host satisfies the requirements of the server
- * flavor.
- */
-public class ComputeCapabilitiesFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
- val fitsMemory = host.availableMemory >= server.flavor.memorySize
- val fitsCpu = host.host.model.cpuCount >= server.flavor.cpuCount
- return fitsMemory && fitsCpu
- }
-
- override fun toString(): String = "ComputeCapabilitiesFilter"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
deleted file mode 100644
index fb842415..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostFilter] that filters on active hosts.
- */
-public class ComputeFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
- return host.host.state == HostState.UP
- }
-
- override fun toString(): String = "ComputeFilter"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
deleted file mode 100644
index 9e909ca6..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import org.opendc.compute.service.scheduler.FilterScheduler
-
-/**
- * A filter used by the [FilterScheduler] to filter hosts.
- */
-public fun interface HostFilter {
- /**
- * Test whether the specified [host] should be included in the selection
- * for scheduling the specified [server].
- */
- public fun test(host: HostView, server: Server): Boolean
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
deleted file mode 100644
index ed6674b1..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostFilter] that filters hosts based on the number of instances on the host.
- *
- * @param limit The maximum number of instances on the host.
- */
-public class InstanceCountFilter(private val limit: Int) : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
- return host.instanceCount < limit
- }
-
- override fun toString(): String = "InstanceCountFilter[limit=$limit]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt
deleted file mode 100644
index 12e6510e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the available memory per core on the host.
- */
-public class CoreMemoryWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.availableMemory.toDouble() / host.host.model.cpuCount
- }
-
- override fun toString(): String = "CoreMemoryWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
deleted file mode 100644
index d48ee9e0..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import org.opendc.compute.service.scheduler.FilterScheduler
-
-/**
- * An interface used by the [FilterScheduler] to weigh the pool of host for a scheduling request.
- */
-public fun interface HostWeigher {
- /**
- * Obtain the weight of the specified [host] when scheduling the specified [server].
- */
- public fun getWeight(host: HostView, server: Server): Double
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
deleted file mode 100644
index 2ef733e5..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the number of instances on the host.
- */
-public class InstanceCountWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.instanceCount.toDouble()
- }
-
- override fun toString(): String = "InstanceCountWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt
deleted file mode 100644
index 115d8e4d..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the available memory on the host.
- */
-public class MemoryWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.availableMemory.toDouble()
- }
-
- override fun toString(): String = "MemoryWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt
deleted file mode 100644
index df5bcd6e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the number of provisioned cores on the host.
- */
-public class ProvisionedCoresWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.provisionedCores.toDouble()
- }
-
- override fun toString(): String = "ProvisionedCoresWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt
deleted file mode 100644
index 1615df3a..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import java.util.*
-
-/**
- * A [HostWeigher] that assigns random weights to each host every selection.
- */
-public class RandomWeigher(private val random: Random) : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double = random.nextDouble()
-
- override fun toString(): String = "RandomWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
deleted file mode 100644
index a6258845..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service
-
-import io.mockk.*
-import io.opentelemetry.api.metrics.MeterProvider
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.delay
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.*
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostModel
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.FilterScheduler
-import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.weights.MemoryWeigher
-import org.opendc.simulator.core.SimulationCoroutineScope
-import org.opendc.simulator.core.runBlockingSimulation
-import java.util.*
-
-/**
- * Test suite for the [ComputeService] interface.
- */
-@OptIn(ExperimentalCoroutinesApi::class)
-internal class ComputeServiceTest {
- lateinit var scope: SimulationCoroutineScope
- lateinit var service: ComputeService
-
- @BeforeEach
- fun setUp() {
- scope = SimulationCoroutineScope()
- val clock = scope.clock
- val computeScheduler = FilterScheduler(
- filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
- weighers = listOf(MemoryWeigher() to -1.0)
- )
- val meter = MeterProvider.noop().get("opendc-compute")
- service = ComputeService(scope.coroutineContext, clock, meter, computeScheduler)
- }
-
- @Test
- fun testClientClose() = scope.runBlockingSimulation {
- val client = service.newClient()
-
- assertEquals(emptyList<Flavor>(), client.queryFlavors())
- assertEquals(emptyList<Image>(), client.queryImages())
- assertEquals(emptyList<Server>(), client.queryServers())
-
- client.close()
-
- assertThrows<IllegalStateException> { client.queryFlavors() }
- assertThrows<IllegalStateException> { client.queryImages() }
- assertThrows<IllegalStateException> { client.queryServers() }
-
- assertThrows<IllegalStateException> { client.findFlavor(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findImage(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findServer(UUID.randomUUID()) }
-
- assertThrows<IllegalStateException> { client.newFlavor("test", 1, 2) }
- assertThrows<IllegalStateException> { client.newImage("test") }
- assertThrows<IllegalStateException> { client.newServer("test", mockk(), mockk()) }
- }
-
- @Test
- fun testClientCreate() = scope.runBlockingSimulation {
- val client = service.newClient()
-
- val flavor = client.newFlavor("test", 1, 1024)
- assertEquals(listOf(flavor), client.queryFlavors())
- assertEquals(flavor, client.findFlavor(flavor.uid))
- val image = client.newImage("test")
- assertEquals(listOf(image), client.queryImages())
- assertEquals(image, client.findImage(image.uid))
- val server = client.newServer("test", image, flavor, start = false)
- assertEquals(listOf(server), client.queryServers())
- assertEquals(server, client.findServer(server.uid))
-
- server.delete()
- assertNull(client.findServer(server.uid))
-
- image.delete()
- assertNull(client.findImage(image.uid))
-
- flavor.delete()
- assertNull(client.findFlavor(flavor.uid))
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testClientOnClose() = scope.runBlockingSimulation {
- service.close()
- assertThrows<IllegalStateException> {
- service.newClient()
- }
- }
-
- @Test
- fun testAddHost() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
-
- assertEquals(0, service.hostCount)
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
-
- assertEquals(1, service.hostCount)
- assertEquals(1, service.hosts.size)
-
- service.removeHost(host)
-
- verify(exactly = 1) { host.removeListener(any()) }
- }
-
- @Test
- fun testAddHostDouble() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.DOWN
-
- assertEquals(0, service.hostCount)
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
- }
-
- @Test
- fun testServerStartWithoutEnoughCpus() = scope.runBlockingSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 0)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.ERROR, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughMemory() = scope.runBlockingSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 0, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.ERROR, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughResources() = scope.runBlockingSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.ERROR, server.state)
- }
-
- @Test
- fun testServerCancelRequest() = scope.runBlockingSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- server.stop()
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerCannotFitOnHost() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(10 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostAvailableAfterSomeTime() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.DOWN
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5 * 60 * 1000)
-
- every { host.state } returns HostState.UP
- listeners.forEach { it.onStateChanged(host, HostState.UP) }
-
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostUnavailableAfterSomeTime() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- delay(5 * 60 * 1000)
-
- every { host.state } returns HostState.DOWN
- listeners.forEach { it.onStateChanged(host, HostState.DOWN) }
-
- server.start()
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
-
- verify(exactly = 0) { host.canFit(server) }
- }
-
- @Test
- fun testServerInvalidType() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- assertThrows<IllegalArgumentException> {
- listeners.forEach { it.onStateChanged(host, server, ServerState.RUNNING) }
- }
- }
-
- @Test
- fun testServerDeploy() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
- val slot = slot<Server>()
-
- val watcher = mockk<ServerWatcher>(relaxUnitFun = true)
- server.watch(watcher)
-
- // Start server
- server.start()
- delay(5 * 60 * 1000)
- coVerify { host.spawn(capture(slot), true) }
-
- listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.RUNNING) }
-
- server.refresh()
- assertEquals(ServerState.RUNNING, server.state)
-
- verify { watcher.onStateChanged(server, ServerState.RUNNING) }
-
- // Stop server
- listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.TERMINATED) }
-
- server.refresh()
- assertEquals(ServerState.TERMINATED, server.state)
-
- verify { watcher.onStateChanged(server, ServerState.TERMINATED) }
- }
-
- @Test
- fun testServerDeployFailure() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- coEvery { host.spawn(any(), true) } throws IllegalStateException()
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5 * 60 * 1000)
-
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt
deleted file mode 100644
index 18d698c6..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service
-
-import io.mockk.*
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Test
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.internal.InternalFlavor
-import java.util.*
-
-/**
- * Test suite for the [InternalFlavor] implementation.
- */
-class InternalFlavorTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
- val b = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testEqualityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Flavor>(relaxUnitFun = true)
- every { b.uid } returns uid
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Flavor>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt
deleted file mode 100644
index e1cb0128..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service
-
-import io.mockk.*
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Test
-import org.opendc.compute.api.Image
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.internal.InternalFlavor
-import org.opendc.compute.service.internal.InternalImage
-import java.util.*
-
-/**
- * Test suite for the [InternalFlavor] implementation.
- */
-class InternalImageTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
- val b = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testEqualityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- val b = mockk<Image>(relaxUnitFun = true)
- every { b.uid } returns uid
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- val b = mockk<Image>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt
deleted file mode 100644
index 20ea8d20..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.service
-
-import io.mockk.*
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.yield
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.internal.InternalFlavor
-import org.opendc.compute.service.internal.InternalImage
-import org.opendc.compute.service.internal.InternalServer
-import org.opendc.simulator.core.runBlockingSimulation
-import java.util.*
-
-/**
- * Test suite for the [InternalServer] implementation.
- */
-@OptIn(ExperimentalCoroutinesApi::class)
-class InternalServerTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val b = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testEqualityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Server>(relaxUnitFun = true)
- every { b.uid } returns uid
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Server>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- assertNotEquals(a, Unit)
- }
-
- @Test
- fun testStartTerminatedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- every { service.schedule(any()) } answers { ComputeServiceImpl.SchedulingRequest(it.invocation.args[0] as InternalServer) }
-
- server.start()
-
- verify(exactly = 1) { service.schedule(server) }
- assertEquals(ServerState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartDeletedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.DELETED
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testStartProvisioningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.PROVISIONING
-
- server.start()
-
- assertEquals(ServerState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartRunningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.RUNNING
-
- server.start()
-
- assertEquals(ServerState.RUNNING, server.state)
- }
-
- @Test
- fun testStopProvisioningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val request = ComputeServiceImpl.SchedulingRequest(server)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.stop()
-
- assertTrue(request.isCancelled)
- assertEquals(ServerState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopTerminatedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.TERMINATED
- server.stop()
-
- assertEquals(ServerState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopDeletedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.DELETED
- server.stop()
-
- assertEquals(ServerState.DELETED, server.state)
- }
-
- @Test
- fun testStopRunningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.state = ServerState.RUNNING
- server.host = host
- server.stop()
- yield()
-
- coVerify { host.stop(server) }
- }
-
- @Test
- fun testDeleteProvisioningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val request = ComputeServiceImpl.SchedulingRequest(server)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.delete()
-
- assertTrue(request.isCancelled)
- assertEquals(ServerState.DELETED, server.state)
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteTerminatedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.TERMINATED
- server.delete()
-
- assertEquals(ServerState.DELETED, server.state)
-
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteDeletedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.DELETED
- server.delete()
-
- assertEquals(ServerState.DELETED, server.state)
- }
-
- @Test
- fun testDeleteRunningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.state = ServerState.RUNNING
- server.host = host
- server.delete()
- yield()
-
- coVerify { host.delete(server) }
- verify { service.delete(server) }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml b/simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
deleted file mode 100644
index 0dfb75f2..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2021 AtLarge Research
- ~
- ~ Permission is hereby granted, free of charge, to any person obtaining a copy
- ~ of this software and associated documentation files (the "Software"), to deal
- ~ in the Software without restriction, including without limitation the rights
- ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- ~ copies of the Software, and to permit persons to whom the Software is
- ~ furnished to do so, subject to the following conditions:
- ~
- ~ The above copyright notice and this permission notice shall be included in all
- ~ copies or substantial portions of the Software.
- ~
- ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- ~ SOFTWARE.
- -->
-
-<Configuration status="WARN" packages="org.apache.logging.log4j.core">
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} [%highlight{%-5level}] %logger{36} - %msg%n" disableAnsi="false"/>
- </Console>
- </Appenders>
- <Loggers>
- <Logger name="org.opendc" level="trace" additivity="false">
- <AppenderRef ref="Console"/>
- </Logger>
- <Root level="info">
- <AppenderRef ref="Console"/>
- </Root>
- </Loggers>
-</Configuration>