diff options
author | Luck <git@lucko.me> | 2019-04-16 21:37:59 +0100 |
---|---|---|
committer | Luck <git@lucko.me> | 2019-04-16 21:37:59 +0100 |
commit | ecd4cec8545460a4fc4ca65b911c2503a00cd8e7 (patch) | |
tree | 62067383a1044abc3a09724e89c6e7c619e87ec0 /spark-common/src/main/java/me/lucko/spark/common/util | |
parent | 8a61b404848ed8e3c27f06eb73239d37d4273240 (diff) | |
download | spark-ecd4cec8545460a4fc4ca65b911c2503a00cd8e7.tar.gz spark-ecd4cec8545460a4fc4ca65b911c2503a00cd8e7.tar.bz2 spark-ecd4cec8545460a4fc4ca65b911c2503a00cd8e7.zip |
Lots of refactoring, add tps command
Diffstat (limited to 'spark-common/src/main/java/me/lucko/spark/common/util')
4 files changed, 335 insertions, 0 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/AbstractHttpClient.java b/spark-common/src/main/java/me/lucko/spark/common/util/AbstractHttpClient.java new file mode 100644 index 0000000..1ff169d --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/AbstractHttpClient.java @@ -0,0 +1,45 @@ +/* + * 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; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +public class AbstractHttpClient { + + /** The http client */ + protected final OkHttpClient okHttp; + + public AbstractHttpClient(OkHttpClient okHttp) { + this.okHttp = okHttp; + } + + protected Response makeHttpRequest(Request request) throws IOException { + Response response = this.okHttp.newCall(request).execute(); + if (!response.isSuccessful()) { + throw new RuntimeException("Request was unsuccessful: " + response.code() + " - " + response.message()); + } + return response; + } +} 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 new file mode 100644 index 0000000..ff8f4e3 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/BytebinClient.java @@ -0,0 +1,149 @@ +/* + * This file is part of bytebin, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * 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 me.lucko.spark.common.util; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import java.io.IOException; + +/** + * Utility for posting content to bytebin. + */ +public class BytebinClient extends AbstractHttpClient { + + /** The bytebin URL */ + private final String url; + /** The client user agent */ + private final String userAgent; + + /** + * Creates a new bytebin instance + * + * @param url the bytebin url + * @param userAgent the client user agent string + */ + public BytebinClient(OkHttpClient okHttpClient, String url, String userAgent) { + super(okHttpClient); + if (url.endsWith("/")) { + this.url = url; + } else { + this.url = url + "/"; + } + this.userAgent = userAgent; + } + + /** + * POSTs GZIP compressed content to bytebin. + * + * @param buf the compressed content + * @param contentType the type of the content + * @param allowModification if the paste should be modifiable + * @return the key of the resultant content + * @throws IOException if an error occurs + */ + public Content postContent(byte[] buf, MediaType contentType, boolean allowModification) throws IOException { + RequestBody body = RequestBody.create(contentType, buf); + + Request.Builder requestBuilder = new Request.Builder() + .url(this.url + "post") + .header("User-Agent", this.userAgent) + .header("Content-Encoding", "gzip"); + + if (allowModification) { + requestBuilder.header("Allow-Modification", "true"); + } + + Request request = requestBuilder.post(body).build(); + try (Response response = makeHttpRequest(request)) { + String key = response.header("Location"); + if (key == null) { + throw new IllegalStateException("Key not returned"); + } + + if (allowModification) { + String modificationKey = response.header("Modification-Key"); + if (modificationKey == null) { + throw new IllegalStateException("Modification key not returned"); + } + return new Content(key, modificationKey); + } else { + return new Content(key); + } + } + } + + /** + * PUTs modified GZIP compressed content to bytebin in place of existing content. + * + * @param existingContent the existing content + * @param buf the compressed content to put + * @param contentType the type of the content + * @throws IOException if an error occurs + */ + public void modifyContent(Content existingContent, byte[] buf, MediaType contentType) throws IOException { + if (!existingContent.modifiable) { + throw new IllegalArgumentException("Existing content is not modifiable"); + } + + RequestBody body = RequestBody.create(contentType, buf); + + Request.Builder requestBuilder = new Request.Builder() + .url(this.url + existingContent.key()) + .header("User-Agent", this.userAgent) + .header("Content-Encoding", "gzip") + .header("Modification-Key", existingContent.modificationKey); + + Request request = requestBuilder.put(body).build(); + makeHttpRequest(request).close(); + } + + public static final class Content { + private final String key; + private final boolean modifiable; + private final String modificationKey; + + Content(String key) { + this.key = key; + this.modifiable = false; + this.modificationKey = null; + } + + Content(String key, String modificationKey) { + this.key = key; + this.modifiable = true; + this.modificationKey = modificationKey; + } + + public String key() { + return this.key; + } + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/ThreadFinder.java b/spark-common/src/main/java/me/lucko/spark/common/util/ThreadFinder.java new file mode 100644 index 0000000..cc0722a --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/ThreadFinder.java @@ -0,0 +1,60 @@ +/* + * 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; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * Utility to find active threads. + */ +public final class ThreadFinder { + + private static final ThreadGroup ROOT_THREAD_GROUP; + static { + ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup parentGroup; + while ((parentGroup = rootGroup.getParent()) != null) { + rootGroup = parentGroup; + } + ROOT_THREAD_GROUP = rootGroup; + } + + // cache the approx active count at the time of construction. + // the usages of this class are likely to be somewhat short-lived, so it's good + // enough to just cache a value on init. + private final int approxActiveCount = ROOT_THREAD_GROUP.activeCount(); + + /** + * Gets a stream of all known active threads. + * + * @return a stream of threads + */ + public Stream<Thread> getThreads() { + Thread[] threads = new Thread[this.approxActiveCount + 20]; // +20 to allow a bit of growth for newly created threads + while (ROOT_THREAD_GROUP.enumerate(threads, true) == threads.length) { + threads = new Thread[threads.length * 2]; + } + return Arrays.stream(threads).filter(Objects::nonNull); + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/TypeDescriptors.java b/spark-common/src/main/java/me/lucko/spark/common/util/TypeDescriptors.java new file mode 100644 index 0000000..a232e77 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/TypeDescriptors.java @@ -0,0 +1,81 @@ +/* + * 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; + +/** + * Utilities for working with Java type descriptors. + */ +public final class TypeDescriptors { + + /** + * Returns the Java type corresponding to the given type descriptor. + * + * @param typeDescriptor a type descriptor. + * @return the Java type corresponding to the given type descriptor. + */ + public static String getJavaType(String typeDescriptor) { + return getJavaType(typeDescriptor.toCharArray(), 0); + } + + private static String getJavaType(char[] buf, int offset) { + int len; + switch (buf[offset]) { + case 'V': + return "void"; + case 'Z': + return "boolean"; + case 'C': + return "char"; + case 'B': + return "byte"; + case 'S': + return "short"; + case 'I': + return "int"; + case 'F': + return "float"; + case 'J': + return "long"; + case 'D': + return "double"; + case '[': // array + len = 1; + while (buf[offset + len] == '[') { + len++; + } + + StringBuilder sb = new StringBuilder(getJavaType(buf, offset + len)); + for (int i = len; i > 0; --i) { + sb.append("[]"); + } + return sb.toString(); + case 'L': // object + len = 1; + while (buf[offset + len] != ';') { + len++; + } + return new String(buf, offset + 1, len - 1); + default: + return new String(buf, offset, buf.length - offset); + } + } + +} |