summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-quarkus/src/main/java/org/opendc
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-quarkus/src/main/java/org/opendc')
-rw-r--r--opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRecorder.java79
-rw-r--r--opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRuntimeConfig.java70
-rw-r--r--opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/AuthConfiguration.java51
-rw-r--r--opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiConfig.java51
-rw-r--r--opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiRecorder.java76
-rw-r--r--opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/QuinoaNextRoutingRecorder.java55
6 files changed, 382 insertions, 0 deletions
diff --git a/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRecorder.java b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRecorder.java
new file mode 100644
index 00000000..814ddf15
--- /dev/null
+++ b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRecorder.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2023 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.web.quarkus.runtime.runner;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.ShutdownContext;
+import io.quarkus.runtime.annotations.Recorder;
+import jakarta.enterprise.inject.spi.CDI;
+import java.io.File;
+import org.jboss.logging.Logger;
+import org.opendc.web.runner.JobManager;
+import org.opendc.web.runner.OpenDCRunner;
+
+/**
+ * Helper class for starting the OpenDC web runner.
+ */
+@Recorder
+public class OpenDCRunnerRecorder {
+ private static final Logger LOGGER = Logger.getLogger(OpenDCRunnerRecorder.class.getName());
+
+ /**
+ * Helper method to create an {@link OpenDCRunner} instance.
+ */
+ public RuntimeValue<OpenDCRunner> createRunner(OpenDCRunnerRuntimeConfig config) {
+ int parallelism = config.parallelism;
+ if (parallelism < 0) {
+ throw new IllegalArgumentException("Parallelism must be non-negative");
+ } else if (parallelism == 0) {
+ parallelism = Math.min(1, Runtime.getRuntime().availableProcessors() - 1);
+ }
+
+ JobManager manager = CDI.current().select(JobManager.class).get();
+ OpenDCRunner runner = new OpenDCRunner(
+ manager,
+ new File(config.tracePath),
+ parallelism,
+ config.jobTimeout,
+ config.pollInterval,
+ config.heartbeatInterval);
+
+ return new RuntimeValue<>(runner);
+ }
+
+ /**
+ * Helper method to start the OpenDC runner service.
+ */
+ public void startRunner(
+ RuntimeValue<OpenDCRunner> runner, OpenDCRunnerRuntimeConfig config, ShutdownContext shutdownContext) {
+ if (config.enable) {
+ LOGGER.info("Starting OpenDC Runner in background (polling every " + config.pollInterval + ")");
+
+ Thread thread = new Thread(runner.getValue());
+ thread.setName("opendc-runner");
+ thread.start();
+
+ shutdownContext.addShutdownTask(thread::interrupt);
+ }
+ }
+}
diff --git a/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRuntimeConfig.java b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRuntimeConfig.java
new file mode 100644
index 00000000..fbc56bfa
--- /dev/null
+++ b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/runner/OpenDCRunnerRuntimeConfig.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2023 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.web.quarkus.runtime.runner;
+
+import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConfigPhase;
+import io.quarkus.runtime.annotations.ConfigRoot;
+import java.time.Duration;
+
+/**
+ * Configuration for the OpenDC web runner.
+ */
+@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "opendc-runner")
+public class OpenDCRunnerRuntimeConfig {
+ /**
+ * Flag to indicate whether the runner should be enabled.
+ */
+ @ConfigItem(defaultValue = "true")
+ public boolean enable;
+
+ /**
+ * The path where the workload traces are located.
+ */
+ @ConfigItem(defaultValue = "traces")
+ public String tracePath;
+
+ /**
+ * The number of concurrent simulations
+ */
+ @ConfigItem(defaultValue = "1")
+ public int parallelism;
+
+ /**
+ * The maximum duration of a job.
+ */
+ @ConfigItem(defaultValue = "10m")
+ public Duration jobTimeout;
+
+ /**
+ * The interval between successive polls to the API.
+ */
+ @ConfigItem(defaultValue = "30s")
+ public Duration pollInterval;
+
+ /**
+ * The interval between successive heartbeats to the API.
+ */
+ @ConfigItem(defaultValue = "1m")
+ public Duration heartbeatInterval;
+}
diff --git a/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/AuthConfiguration.java b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/AuthConfiguration.java
new file mode 100644
index 00000000..10f91923
--- /dev/null
+++ b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/AuthConfiguration.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023 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.web.quarkus.runtime.ui;
+
+import io.quarkus.runtime.annotations.ConfigGroup;
+import io.quarkus.runtime.annotations.ConfigItem;
+import java.util.Optional;
+
+/**
+ * Auth configuration for the OpenDC UI extension.
+ */
+@ConfigGroup
+public class AuthConfiguration {
+ /**
+ * The authentication domain.
+ */
+ @ConfigItem
+ Optional<String> domain;
+
+ /**
+ * The client identifier used by the OpenDC web ui.
+ */
+ @ConfigItem
+ Optional<String> clientId;
+
+ /**
+ * The audience of the OpenDC API.
+ */
+ @ConfigItem
+ Optional<String> audience;
+}
diff --git a/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiConfig.java b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiConfig.java
new file mode 100644
index 00000000..541cfdc1
--- /dev/null
+++ b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiConfig.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023 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.web.quarkus.runtime.ui;
+
+import io.quarkus.runtime.annotations.ConfigItem;
+import io.quarkus.runtime.annotations.ConfigPhase;
+import io.quarkus.runtime.annotations.ConfigRoot;
+import java.util.Optional;
+
+/**
+ * Configuration for the OpenDC web UI.
+ */
+@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "opendc-ui")
+public class OpenDCUiConfig {
+ /**
+ * The base URL of the OpenDC API.
+ */
+ @ConfigItem(defaultValue = "/api")
+ String apiBaseUrl;
+
+ /**
+ * Configuration properties for web UI authentication.
+ */
+ AuthConfiguration auth;
+
+ /**
+ * Sentry DSN.
+ */
+ @ConfigItem
+ Optional<String> sentryDsn;
+}
diff --git a/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiRecorder.java b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiRecorder.java
new file mode 100644
index 00000000..5783e431
--- /dev/null
+++ b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/OpenDCUiRecorder.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2023 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.web.quarkus.runtime.ui;
+
+import static io.vertx.ext.web.handler.StaticHandler.DEFAULT_MAX_AGE_SECONDS;
+
+import io.quarkus.runtime.annotations.Recorder;
+import io.vertx.core.Handler;
+import io.vertx.core.http.HttpHeaders;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.json.JsonObject;
+import io.vertx.ext.web.RoutingContext;
+import io.vertx.ext.web.impl.Utils;
+
+/**
+ * Recorder class for the OpenDC web UI.
+ */
+@Recorder
+public class OpenDCUiRecorder {
+ /**
+ * Construct a {@link Handler} for serving the configuration of the OpenDC web UI.
+ */
+ public Handler<RoutingContext> configHandler(OpenDCUiConfig config) {
+ return (event) -> {
+ HttpServerRequest request = event.request();
+ if (request.method() != HttpMethod.GET && request.method() != HttpMethod.HEAD) {
+ event.next();
+ return;
+ }
+
+ event.response()
+ .setStatusCode(200)
+ .putHeader(HttpHeaders.CONTENT_TYPE, "text/javascript")
+ .putHeader(HttpHeaders.CACHE_CONTROL, "public, immutable, max-age=" + DEFAULT_MAX_AGE_SECONDS)
+ .putHeader(HttpHeaders.DATE, Utils.formatRFC1123DateTime(System.currentTimeMillis()))
+ .end(OpenDCUiRecorder.serializeConfig(config));
+ };
+ }
+
+ /**
+ * Serialize the configuration of the OpenDC web UI into JSON.
+ *
+ * @param config The configuration of the OpenDC web UI specified by the user.
+ * @return JS serialized version of the OpenDC web UI config.
+ */
+ private static String serializeConfig(OpenDCUiConfig config) {
+ JsonObject configJson = JsonObject.of("NEXT_PUBLIC_API_BASE_URL", config.apiBaseUrl);
+ config.auth.domain.ifPresent(s -> configJson.put("NEXT_PUBLIC_AUTH0_DOMAIN", s));
+ config.auth.clientId.ifPresent(s -> configJson.put("NEXT_PUBLIC_AUTH0_CLIENT_ID", s));
+ config.auth.audience.ifPresent(s -> configJson.put("NEXT_PUBLIC_AUTH0_AUDIENCE", s));
+ config.sentryDsn.ifPresent(s -> configJson.put("NEXT_PUBLIC_SENTRY_DSN", s));
+
+ return "window.__ENV = " + configJson.encode() + ";";
+ }
+}
diff --git a/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/QuinoaNextRoutingRecorder.java b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/QuinoaNextRoutingRecorder.java
new file mode 100644
index 00000000..c511220d
--- /dev/null
+++ b/opendc-web/opendc-web-quarkus/src/main/java/org/opendc/web/quarkus/runtime/ui/QuinoaNextRoutingRecorder.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023 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.web.quarkus.runtime.ui;
+
+import io.quarkus.runtime.annotations.Recorder;
+import io.vertx.core.Handler;
+import io.vertx.ext.web.RoutingContext;
+
+/**
+ * Recorder class for building route handlers for Next.js pages and redirects.
+ */
+@Recorder
+public class QuinoaNextRoutingRecorder {
+ /**
+ * Construct a {@link Handler} for serving a dynamic route of a Next.js application.
+ */
+ public Handler<RoutingContext> pageHandler(String basePath, String page) {
+ return (event) -> event.reroute(basePath + page + ".html");
+ }
+
+ /**
+ * Construct a {@link Handler} for handling redirects of a Next.js application.
+ */
+ public Handler<RoutingContext> redirectHandler(String destination, int statusCode) {
+ return (event) -> {
+ String query = event.request().query();
+ String fullDestination = query != null ? destination + "?" + query : destination;
+
+ event.response()
+ .setStatusCode(statusCode)
+ .putHeader("Location", fullDestination)
+ .end();
+ };
+ }
+}