From 82f8418f49b0564c5093c28be1ca522a628d0b4f Mon Sep 17 00:00:00 2001 From: mjkwiatkowski Date: Thu, 26 Feb 2026 19:51:57 +0100 Subject: feat: added notes from last meeting with my supervisor --- opendc-common/build.gradle.kts | 1 - .../org/opendc/common/annotations/Endpoint.kt | 6 ++ .../org/opendc/common/annotations/InternalUse.kt | 2 + .../org/opendc/common/api/AssetsController.kt | 72 ++++++++++++++++++++++ .../org/opendc/common/api/ResourceController.kt | 30 +++++++++ .../kotlin/org/opendc/common/utils/HTTPClient.kt | 30 ++++----- .../org/opendc/common/utils/JavalinRunner.kt | 41 ++++-------- .../main/kotlin/org/opendc/common/utils/Kafka.kt | 5 +- .../main/kotlin/org/opendc/common/utils/Redis.kt | 1 - opendc-common/src/main/resources/producer.toml | 2 +- 10 files changed, 137 insertions(+), 53 deletions(-) create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/annotations/Endpoint.kt create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/api/AssetsController.kt create mode 100644 opendc-common/src/main/kotlin/org/opendc/common/api/ResourceController.kt (limited to 'opendc-common') diff --git a/opendc-common/build.gradle.kts b/opendc-common/build.gradle.kts index dc323140..5838d2d4 100644 --- a/opendc-common/build.gradle.kts +++ b/opendc-common/build.gradle.kts @@ -70,7 +70,6 @@ dependencies { // Source: https://mvnrepository.com/artifact/redis.clients/jedis implementation("redis.clients:jedis:7.3.0") - } 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/annotations/InternalUse.kt b/opendc-common/src/main/kotlin/org/opendc/common/annotations/InternalUse.kt index e32aa811..0a57aae9 100644 --- a/opendc-common/src/main/kotlin/org/opendc/common/annotations/InternalUse.kt +++ b/opendc-common/src/main/kotlin/org/opendc/common/annotations/InternalUse.kt @@ -26,3 +26,5 @@ package org.opendc.common.annotations @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.CONSTRUCTOR) public annotation class InternalUse + + 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 index cc89d48f..fc5bc57b 100644 --- a/opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt +++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/HTTPClient.kt @@ -1,35 +1,25 @@ 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. * - * @constructor Initiates the connection. - * * @author Mateusz Kwiatkowski */ public class HTTPClient private constructor() { public companion object { private var instance: HTTPClient? = null - private var client: HttpClient? = null - private var handshake = HttpRequest.newBuilder() - .uri(URI.create("http://localhost:8080/")) - .build() + private var client = HttpClient.newBuilder().build() public fun getInstance(): HTTPClient? { if (instance == null) { - try { - client = HttpClient.newBuilder().build() - val response = client?.send(handshake, ofString()) - check(response?.statusCode() == 200) - } catch (e: IllegalStateException) { - println("${e.message}") - } instance = HTTPClient() } return instance @@ -38,13 +28,19 @@ public class HTTPClient private constructor() { // TODO: this class must send the experiment JSON file to the digital twin public fun sendExperiment(experiment: File) { - val body : HttpRequest.BodyPublisher + 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/")) + .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(experiment)) + .POST(HttpRequest.BodyPublishers.ofString(String(charArray))) .build() - println("Haha") + 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 index a43e23a8..23baac27 100644 --- a/opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt +++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/JavalinRunner.kt @@ -1,50 +1,33 @@ package org.opendc.common.utils import io.javalin.Javalin -import io.javalin.http.Handler +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 handshake: Handler = Handler { ctx -> ctx.status(200) } - - private val scenario: Handler = Handler { ctx -> - } + private val assetsController : AssetsController = AssetsController() init { - // Make a CRUD RESTful API - // Specify server config val app = Javalin.create().start() + app.get("/assets", assetsController.getAssets()) - // returns a list of all experiments - app.get("/experiment", handshake) - - // returns a specific experiment - app.get("/experiment/:id", handshake) - - // you need another endpoint for the metrics - - // get the results for the metrics evaluation - app.get("/results/:id", handshake) - - // returns all results - app.get("/results", handshake) + app.get("/assets/{id}", assetsController.getAssetsId()) - // sends a specific experiment - app.post("/experiment", scenario) + app.post("/assets", assetsController.postAsset()) - // changes a specific experiment - app.put("/experiment/:id", scenario) - // this should delete metrics associated with the experiment + app.put("/assets/{id}", assetsController.putAssetId()) - // deletes an experiment with id - app.delete("/experiment/:id", scenario) + app.delete("/assets/{id}", assetsController.deleteAssetId()) - // deletes all experiments - app.delete("/experiment", scenario) + 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 index 1430898e..81eb6752 100644 --- a/opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt +++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/Kafka.kt @@ -1,13 +1,10 @@ package org.opendc.common.utils import com.fasterxml.jackson.dataformat.toml.TomlMapper -import org.apache.kafka.clients.consumer.KafkaConsumer import org.apache.kafka.clients.producer.KafkaProducer import org.apache.kafka.clients.producer.ProducerRecord import org.opendc.common.ProtobufMetrics import java.util.* -import kotlin.time.Duration.Companion.microseconds -import kotlin.time.toJavaDuration /** * Represents the Kafka interface. * @constructor `topic` the Kafka topic @@ -34,7 +31,7 @@ public class Kafka(private val topic: String) { try { producer.send(ProducerRecord(this.topic, value)) } catch (e: Exception) { - println("${e.message}") + println("${e.message}") } } } 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 index 67547778..b659d40a 100644 --- a/opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt +++ b/opendc-common/src/main/kotlin/org/opendc/common/utils/Redis.kt @@ -40,5 +40,4 @@ public class Redis { println(res5) jedis.close() } - } \ No newline at end of file diff --git a/opendc-common/src/main/resources/producer.toml b/opendc-common/src/main/resources/producer.toml index 33a09284..8202e93b 100644 --- a/opendc-common/src/main/resources/producer.toml +++ b/opendc-common/src/main/resources/producer.toml @@ -2,4 +2,4 @@ "key.serializer" = "org.apache.kafka.common.serialization.VoidSerializer" "value.serializer" = "io.confluent.kafka.serializers.protobuf.KafkaProtobufSerializer" "schema.registry.url" = "http://localhost:8081" -"auto.register.schemas" = "true" \ No newline at end of file +"auto.register.schemas" = "true" -- cgit v1.2.3