aboutsummaryrefslogtreecommitdiff
path: root/spark-common/src/main/java/me/lucko/spark/common/util
diff options
context:
space:
mode:
authorlucko <git@lucko.me>2023-01-28 11:07:45 +0000
committerGitHub <noreply@github.com>2023-01-28 11:07:45 +0000
commit06b794dcea806150770fb88d43e366a3496a9d0f (patch)
tree15ed2a6b7de22d90844b67291250dab4ec14eeda /spark-common/src/main/java/me/lucko/spark/common/util
parentd83e49128ad59308f4b3ff19cf4b22b53236be8d (diff)
downloadspark-06b794dcea806150770fb88d43e366a3496a9d0f.tar.gz
spark-06b794dcea806150770fb88d43e366a3496a9d0f.tar.bz2
spark-06b794dcea806150770fb88d43e366a3496a9d0f.zip
Stream live data to the viewer using WebSockets (#294)
Diffstat (limited to 'spark-common/src/main/java/me/lucko/spark/common/util')
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java14
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/Configuration.java27
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/MediaTypes.java29
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClient.java118
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClientImpl.java40
5 files changed, 224 insertions, 4 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java b/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java
index e69b94e..8f11edc 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java
@@ -32,6 +32,8 @@ import java.util.zip.GZIPOutputStream;
/**
* Utility for posting content to bytebin.
+ *
+ * @see <a href="https://github.com/lucko/bytebin">https://github.com/lucko/bytebin</a>
*/
public class BytebinClient {
@@ -45,7 +47,7 @@ public class BytebinClient {
this.userAgent = userAgent;
}
- private Content postContent(String contentType, Consumer<OutputStream> consumer) throws IOException {
+ private Content postContent(String contentType, Consumer<OutputStream> consumer, String userAgent) throws IOException {
URL url = new URL(this.url + "post");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
@@ -55,7 +57,7 @@ public class BytebinClient {
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", contentType);
- connection.setRequestProperty("User-Agent", this.userAgent);
+ connection.setRequestProperty("User-Agent", userAgent);
connection.setRequestProperty("Content-Encoding", "gzip");
connection.connect();
@@ -74,14 +76,18 @@ public class BytebinClient {
}
}
- public Content postContent(AbstractMessageLite<?, ?> proto, String contentType) throws IOException {
+ public Content postContent(AbstractMessageLite<?, ?> proto, String contentType, String userAgentExtra) throws IOException {
return postContent(contentType, outputStream -> {
try (OutputStream out = new GZIPOutputStream(outputStream)) {
proto.writeTo(out);
} catch (IOException e) {
throw new RuntimeException(e);
}
- });
+ }, this.userAgent + "/" + userAgentExtra);
+ }
+
+ public Content postContent(AbstractMessageLite<?, ?> proto, String contentType) throws IOException {
+ return postContent(proto, contentType, this.userAgent);
}
public static final class Content {
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/Configuration.java b/spark-common/src/main/java/me/lucko/spark/common/util/Configuration.java
index 32f3bc6..d19ba64 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/util/Configuration.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/Configuration.java
@@ -22,6 +22,7 @@ package me.lucko.spark.common.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
@@ -32,6 +33,9 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
public final class Configuration {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
@@ -103,6 +107,21 @@ public final class Configuration {
return val.isBoolean() ? val.getAsInt() : def;
}
+ public List<String> getStringList(String path) {
+ JsonElement el = this.root.get(path);
+ if (el == null || !el.isJsonArray()) {
+ return Collections.emptyList();
+ }
+
+ List<String> list = new ArrayList<>();
+ for (JsonElement child : el.getAsJsonArray()) {
+ if (child.isJsonPrimitive()) {
+ list.add(child.getAsJsonPrimitive().getAsString());
+ }
+ }
+ return list;
+ }
+
public void setString(String path, String value) {
this.root.add(path, new JsonPrimitive(value));
}
@@ -115,6 +134,14 @@ public final class Configuration {
this.root.add(path, new JsonPrimitive(value));
}
+ public void setStringList(String path, List<String> value) {
+ JsonArray array = new JsonArray();
+ for (String str : value) {
+ array.add(str);
+ }
+ this.root.add(path, array);
+ }
+
public boolean contains(String path) {
return this.root.has(path);
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/MediaTypes.java b/spark-common/src/main/java/me/lucko/spark/common/util/MediaTypes.java
new file mode 100644
index 0000000..2c49540
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/MediaTypes.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common.util;
+
+public enum MediaTypes {
+ ;
+
+ public static final String SPARK_SAMPLER_MEDIA_TYPE = "application/x-spark-sampler";
+ public static final String SPARK_HEAP_MEDIA_TYPE = "application/x-spark-heap";
+
+}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClient.java b/spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClient.java
new file mode 100644
index 0000000..1db7a67
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClient.java
@@ -0,0 +1,118 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common.util.ws;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * A client that can interact with bytesocks.
+ *
+ * @see <a href="https://github.com/lucko/bytesocks">https://github.com/lucko/bytesocks</a>
+ */
+public interface BytesocksClient {
+
+ /**
+ * Creates a new {@link BytesocksClient}.
+ *
+ * <p>Returns {@code null} on Java versions before 11.</p>
+ *
+ * @param host the host
+ * @param userAgent the user agent
+ * @return the client
+ */
+ static BytesocksClient create(String host, String userAgent) {
+ try {
+ return new BytesocksClientImpl(host, userAgent);
+ } catch (UnsupportedOperationException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new bytesocks channel and returns a socket connected to it.
+ *
+ * @param listener the listener
+ * @return the socket
+ * @throws Exception if something goes wrong
+ */
+ Socket createAndConnect(Listener listener) throws Exception;
+
+ /**
+ * Connects to an existing bytesocks channel.
+ *
+ * @param channelId the channel id
+ * @param listener the listener
+ * @return the socket
+ * @throws Exception if something goes wrong
+ */
+ Socket connect(String channelId, Listener listener) throws Exception;
+
+ /**
+ * A socket connected to a bytesocks channel.
+ */
+ interface Socket {
+
+ /**
+ * Gets the id of the connected channel.
+ *
+ * @return the id of the channel
+ */
+ String getChannelId();
+
+ /**
+ * Gets if the socket is open.
+ *
+ * @return true if the socket is open
+ */
+ boolean isOpen();
+
+ /**
+ * Sends a message to the channel using the socket.
+ *
+ * @param msg the message to send
+ * @return a future to encapsulate the progress of sending the message
+ */
+ CompletableFuture<?> send(CharSequence msg);
+
+ /**
+ * Closes the socket.
+ *
+ * @param statusCode the status code
+ * @param reason the reason
+ */
+ void close(int statusCode, String reason);
+ }
+
+ /**
+ * Socket listener
+ */
+ interface Listener {
+
+ default void onOpen() {}
+
+ default void onError(Throwable error) {}
+
+ default void onText(CharSequence data) {}
+
+ default void onClose(int statusCode, String reason) {}
+ }
+
+}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClientImpl.java b/spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClientImpl.java
new file mode 100644
index 0000000..cf1489c
--- /dev/null
+++ b/spark-common/src/main/java/me/lucko/spark/common/util/ws/BytesocksClientImpl.java
@@ -0,0 +1,40 @@
+/*
+ * This file is part of spark.
+ *
+ * Copyright (c) lucko (Luck) <luck@lucko.me>
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package me.lucko.spark.common.util.ws;
+
+// Overridden by java 11 source set
+
+class BytesocksClientImpl implements BytesocksClient {
+
+ BytesocksClientImpl(String host, String userAgent) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket createAndConnect(Listener listener) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Socket connect(String channelId, Listener listener) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+}