From 0731bd58889df127ef87aba2590d505d79e6646f Mon Sep 17 00:00:00 2001 From: mjkwiatkowski Date: Mon, 15 Jun 2026 23:48:44 +0200 Subject: feat: migrated the past project to the sunfish repo --- .../kotlin/org/opendc/common/utils/HTTPClient.kt | 46 +++++++++++++++++++ .../org/opendc/common/utils/JavalinRunner.kt | 33 ++++++++++++++ .../main/kotlin/org/opendc/common/utils/Kafka.kt | 38 ++++++++++++++++ .../kotlin/org/opendc/common/utils/PostgresqlDB.kt | 52 ++++++++++++++++++++++ .../main/kotlin/org/opendc/common/utils/Redis.kt | 43 ++++++++++++++++++ 5 files changed, 212 insertions(+) create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/utils/PostgresqlDB.kt create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt (limited to 'opendc-common/src/main/kotlin/org/opendc/common/utils') 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 https://javalin.io/documentation + * @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 + * https://kafka.apache.org/23/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html + * @see + * https://kafka.apache.org/23/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html + */ + +@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(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 + * https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/java/sql/DriverManager.html + */ +@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 https://redis.io/docs/latest/ + * + * @see https://redis.io/docs/latest/develop/data-types/streams/ + */ + +@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() { + 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 -- cgit v1.2.3