summaryrefslogtreecommitdiff
path: root/opendc-common/src/main/kotlin/org/opendc
diff options
context:
space:
mode:
authormjkwiatkowski <mati.rewa@gmail.com>2026-06-15 23:48:44 +0200
committermjkwiatkowski <mati.rewa@gmail.com>2026-06-15 23:48:44 +0200
commit0731bd58889df127ef87aba2590d505d79e6646f (patch)
tree128aceeaf60ac5c098297f7cfda9fa47f974fc84 /opendc-common/src/main/kotlin/org/opendc
parentf1ecbf0ce40d43685d8a6aeba0fe4cdebbd4536f (diff)
feat: migrated the past project to the sunfish repo
Diffstat (limited to 'opendc-common/src/main/kotlin/org/opendc')
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/annotations/Endpoint.kt6
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/api/AssetsController.kt72
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/api/ResourceController.kt30
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt46
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt33
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt38
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/utils/PostgresqlDB.kt52
-rw-r--r--opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt43
8 files changed, 320 insertions, 0 deletions
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/annotations/Endpoint.kt b/opendc-common/src/main/kotlin/org/opendc/common/annotations/Endpoint.kt
new file mode 100644
index 00000000..4ef08a71
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/annotations/Endpoint.kt
@@ -0,0 +1,6 @@
+package org.opendc.common.annotations
+
+@RequiresOptIn(message = "This is a registered API endpoint.")
+@Retention(AnnotationRetention.BINARY)
+@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.CONSTRUCTOR)
+public annotation class Endpoint(val method: String, val name : String) \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/api/AssetsController.kt b/opendc-common/src/main/kotlin/org/opendc/common/api/AssetsController.kt
new file mode 100644
index 00000000..c6f34d19
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/api/AssetsController.kt
@@ -0,0 +1,72 @@
+package org.opendc.common.api
+
+import org.opendc.common.annotations.Endpoint
+import io.javalin.http.Handler
+
+/**
+ * This class represents the `/assets` endpoint.
+ *
+ * @author Mateusz Kwiatkowski
+ *
+ * */
+
+
+//TODO: fix -> this is all wrong.
+// Sending the experiment file is completely useless.
+// You need to send tasks.parquet
+public class AssetsController {
+ /**
+ * Returns a concatenated JSON string of all assets.
+ */
+ @Endpoint("GET","/assets")
+ public fun getAssets() : Handler {
+ return Handler { ctx -> ctx.status(200)
+ println(ctx.body())
+ }
+ }
+
+ /**
+ * Returns an asset with `id` as a JSON string.
+ */
+ @Endpoint("GET", "/assets/{id}")
+ public fun getAssetsId(): Handler {
+ return Handler { ctx -> ctx.status(200) }
+ }
+
+ /**
+ * Saves the asset specified in the HTTP body.
+ * Returns the asset `id`.
+ */
+ @Endpoint("POST", "/assets")
+ public fun postAsset() : Handler {
+ return Handler { ctx -> ctx.status(200)
+ println(ctx.body())
+ }
+ }
+
+ /**
+ * Modifies the specified asset.
+ * Deletes all results from experiments with this asset.
+ */
+ @Endpoint("PUT", "/assets/{id}")
+ public fun putAssetId() : Handler {
+ return Handler { ctx -> ctx.status(200) }
+ }
+
+ /**
+ * Deletes an asset with `id`.
+ * Deletes all results from experiments with this asset.
+ */
+ @Endpoint("DELETE", "/assets/{id}")
+ public fun deleteAssetId() : Handler {
+ return Handler { ctx -> ctx.status(200) }
+ }
+
+ /**
+ * Deletes all assets
+ */
+ @Endpoint("DELETE", "/assets")
+ public fun deleteAsset() : Handler {
+ return Handler { ctx -> ctx.status(200) }
+ }
+} \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/api/ResourceController.kt b/opendc-common/src/main/kotlin/org/opendc/common/api/ResourceController.kt
new file mode 100644
index 00000000..cf1d3cac
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/api/ResourceController.kt
@@ -0,0 +1,30 @@
+package org.opendc.common.api
+
+import org.opendc.common.annotations.Endpoint
+
+/**
+ * This class represents the `/resources` endpoint.
+ *
+ * @author Mateusz Kwiatkowski
+ *
+ * */
+
+public class ResourceController {
+
+ /**
+ * Returns all data analytics for all experiments.
+ */
+ @Endpoint("GET", "/resources")
+ public fun getResources() {
+ return
+ }
+
+ /**
+ * Returns data analytics for experiment with `id`.
+ *
+ * */
+ @Endpoint("GET", "/resources")
+ public fun getResourcesId() {
+ return
+ }
+} \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt b/opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt
new file mode 100644
index 00000000..fc5bc57b
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt
@@ -0,0 +1,46 @@
+package org.opendc.common.utils
+
+import java.io.File
+import java.io.InputStreamReader
+import java.net.URI
+import java.net.http.*
+import java.net.http.HttpResponse.BodyHandlers.ofString
+
+/**
+ * Singleton class representing the real datacenter client.
+ * The client is asynchronous and initiates the connection first.
+ *
+ * @author Mateusz Kwiatkowski
+ */
+
+public class HTTPClient private constructor() {
+ public companion object {
+ private var instance: HTTPClient? = null
+ private var client = HttpClient.newBuilder().build()
+
+ public fun getInstance(): HTTPClient? {
+ if (instance == null) {
+ instance = HTTPClient()
+ }
+ return instance
+ }
+ }
+
+ // TODO: this class must send the experiment JSON file to the digital twin
+ public fun sendExperiment(experiment: File) {
+ val input = experiment.inputStream()
+ val charArray = CharArray(experiment.length().toInt())
+ val isr = InputStreamReader(input)
+
+ isr.read(charArray)
+
+ val request = HttpRequest.newBuilder()
+ .uri(URI.create("http://localhost:8080/assets"))
+ .header("Content-type", "application/json")
+ // TODO: this is obviously wrong, find an efficient way to send JSON over network
+ .POST(HttpRequest.BodyPublishers.ofString(String(charArray)))
+ .build()
+ val response = client?.send(request, ofString())
+ check(response?.statusCode() == 200)
+ }
+} \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt b/opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt
new file mode 100644
index 00000000..23baac27
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt
@@ -0,0 +1,33 @@
+package org.opendc.common.utils
+
+import io.javalin.Javalin
+import org.opendc.common.annotations.Endpoint
+import org.opendc.common.api.AssetsController
+
+/**
+ * Represents the digital twin monitoring server.
+ * For endpoint documentation see `AssetsController`.
+ * @author Mateusz Kwiatkowski
+ * @see <a href=https://javalin.io/documentation>https://javalin.io/documentation</a>
+ * @see org.opendc.common.api.AssetsController
+ */
+
+@OptIn(Endpoint::class)
+public class JavalinRunner {
+ private val assetsController : AssetsController = AssetsController()
+
+ init {
+ val app = Javalin.create().start()
+ app.get("/assets", assetsController.getAssets())
+
+ app.get("/assets/{id}", assetsController.getAssetsId())
+
+ app.post("/assets", assetsController.postAsset())
+
+ app.put("/assets/{id}", assetsController.putAssetId())
+
+ app.delete("/assets/{id}", assetsController.deleteAssetId())
+
+ app.delete("/assets", assetsController.deleteAsset())
+ }
+} \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt b/opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt
new file mode 100644
index 00000000..81eb6752
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt
@@ -0,0 +1,38 @@
+package org.opendc.common.utils
+
+import com.fasterxml.jackson.dataformat.toml.TomlMapper
+import org.apache.kafka.clients.producer.KafkaProducer
+import org.apache.kafka.clients.producer.ProducerRecord
+import org.opendc.common.ProtobufMetrics
+import java.util.*
+/**
+ * Represents the Kafka interface.
+ * @constructor `topic` the Kafka topic
+ * @author Mateusz Kwiatkowski
+ * @see <a href=https://kafka.apache.org/23/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html>
+ * https://kafka.apache.org/23/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html</a>
+ * @see <a href=https://kafka.apache.org/23/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html>
+ * https://kafka.apache.org/23/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html</a>
+ */
+
+@Suppress("DEPRECATION")
+public class Kafka(private val topic: String) {
+ private var properties : Properties
+
+ init {
+ check(!topic.contains("-"))
+ properties = TomlMapper().readerFor(Properties().javaClass)
+ .readValue(Kafka::class.java.getResource("/producer.toml"))
+ }
+
+ public fun getSend() : (ProtobufMetrics.ProtoExport) -> Unit {
+ val producer = KafkaProducer<String, ProtobufMetrics.ProtoExport>(properties)
+ return fun (value : ProtobufMetrics.ProtoExport) {
+ try {
+ producer.send(ProducerRecord(this.topic, value))
+ } catch (e: Exception) {
+ println("${e.message}")
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/utils/PostgresqlDB.kt b/opendc-common/src/main/kotlin/org/opendc/common/utils/PostgresqlDB.kt
new file mode 100644
index 00000000..35d03feb
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/PostgresqlDB.kt
@@ -0,0 +1,52 @@
+package org.opendc.common.utils
+
+import com.fasterxml.jackson.dataformat.toml.TomlMapper
+import java.sql.Connection
+import java.sql.DriverManager
+import java.sql.SQLException
+import java.util.Properties
+/**
+ * Represents the Postgresql database.
+ * On setup cleans the entire database.
+ *
+ * @author Mateusz Kwiatkowski
+ *
+ * @see <a href=https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/java/sql/DriverManager.html>
+ * https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/java/sql/DriverManager.html</a>
+ */
+@Suppress("DEPRECATION")
+public class PostgresqlDB {
+ private var properties = Properties()
+ private var connection : Connection? = null
+
+ init {
+ try {
+ properties = TomlMapper().readerFor(Properties().javaClass)
+ .readValue(PostgresqlDB::class.java.getResource("/database.toml"))
+ connection = DriverManager.getConnection(
+ properties.getProperty("address").asJdbc(properties.getProperty("database")),
+ properties.getProperty("user"),
+ properties.getProperty("password"))
+ clear()
+ } catch (e: SQLException) {
+ print("${e.message}")
+ }
+ }
+ public fun clear(){
+ val DELETE_ALL_TABLES = """
+ DROP SCHEMA public CASCADE;
+ CREATE SCHEMA public;
+ """.trimIndent()
+ try {
+ val st = connection?.createStatement()
+ st?.executeQuery(DELETE_ALL_TABLES)
+ } catch (e: SQLException){
+ println("${e.message}")
+ }
+ }
+
+ private fun String.asJdbc(database : String) : String {
+ return "jdbc:postgresql://$this/$database"
+ }
+
+} \ No newline at end of file
diff --git a/opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt b/opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt
new file mode 100644
index 00000000..b659d40a
--- /dev/null
+++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt
@@ -0,0 +1,43 @@
+package org.opendc.common.utils
+
+import com.fasterxml.jackson.dataformat.toml.TomlMapper
+import redis.clients.jedis.RedisClient
+import redis.clients.jedis.StreamEntryID
+import redis.clients.jedis.params.XReadParams
+import java.util.Properties
+
+/**
+ * This class represents the Redis server instance.
+ * @author Mateusz Kwiatkowski
+ * @see <a href=https://redis.io/docs/latest/>https://redis.io/docs/latest/</a>
+ *
+ * @see <a href=https://redis.io/docs/latest/develop/data-types/streams/>https://redis.io/docs/latest/develop/data-types/streams/</a>
+ */
+
+@Suppress("DEPRECATION")
+public class Redis {
+ private var properties : Properties
+
+ init {
+ properties = TomlMapper().readerFor(Properties().javaClass)
+ .readValue(Kafka::class.java.getResource("/producer.toml"))
+ }
+
+ public fun run() {
+ val jedis : RedisClient = RedisClient.create("redis://localhost:6379")
+
+ val res5 = jedis.xread(
+ XReadParams.xReadParams().block(300).count(100),
+ object : HashMap<String?, StreamEntryID?>() {
+ init {
+ put("${properties.getProperty("table")}", StreamEntryID())
+ }
+ })
+
+ // in Redis you can subscribe to updates to a stream.
+ // you should base your application off this.
+ // you can listen for new items with XREAD
+ println(res5)
+ jedis.close()
+ }
+} \ No newline at end of file