Fix various issues for the native distributions

This commit is contained in:
Christopher Schnick 2022-01-31 12:13:27 +01:00
parent 41837479fc
commit cb8f1239ad
26 changed files with 208 additions and 199 deletions

View file

@ -21,7 +21,7 @@ public abstract class XPipeApiConnector extends BeaconConnector {
@Override
protected BeaconClient constructSocket() throws ConnectorException {
if (!JacksonHelper.isInit()) {
JacksonHelper.init(ModuleLayer.boot());
JacksonHelper.initModularized(ModuleLayer.boot());
}
if (!BeaconServer.isRunning()) {

View file

@ -6,7 +6,7 @@ import io.xpipe.beacon.BeaconClient;
import io.xpipe.beacon.ClientException;
import io.xpipe.beacon.ConnectorException;
import io.xpipe.beacon.ServerException;
import io.xpipe.beacon.exchange.ReadInfoExchange;
import io.xpipe.beacon.exchange.InfoExchange;
import io.xpipe.beacon.exchange.StoreResourceExchange;
import io.xpipe.beacon.exchange.StoreStreamExchange;
import io.xpipe.core.source.DataSourceConfig;
@ -23,8 +23,8 @@ public abstract class DataSourceImpl implements DataSource {
new XPipeApiConnector() {
@Override
protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException {
var req = ReadInfoExchange.Request.builder().sourceId(ds).build();
ReadInfoExchange.Response res = performSimpleExchange(sc, req);
var req = InfoExchange.Request.builder().id(ds).build();
InfoExchange.Response res = performSimpleExchange(sc, req);
}
}.execute();

View file

@ -6,14 +6,12 @@ import io.xpipe.beacon.BeaconClient;
import io.xpipe.beacon.ClientException;
import io.xpipe.beacon.ConnectorException;
import io.xpipe.beacon.ServerException;
import io.xpipe.beacon.exchange.ReadTableDataExchange;
import io.xpipe.core.data.node.ArrayNode;
import io.xpipe.core.data.node.DataStructureNode;
import io.xpipe.core.data.node.TupleNode;
import io.xpipe.core.data.type.TupleType;
import io.xpipe.core.data.typed.TypedAbstractReader;
import io.xpipe.core.data.typed.TypedDataStreamParser;
import io.xpipe.core.data.typed.TypedDataStructureNodeReader;
import io.xpipe.core.data.typed.TypedReusableDataStructureNodeReader;
import io.xpipe.core.source.DataSourceConfig;
import io.xpipe.core.source.DataSourceId;
@ -90,12 +88,12 @@ public class DataTableImpl extends DataSourceImpl implements DataTable {
new XPipeApiConnector() {
@Override
protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException {
var req = ReadTableDataExchange.Request.builder()
.sourceId(id).maxRows(maxToRead).build();
performInputExchange(sc, req, (ReadTableDataExchange.Response res, InputStream in) -> {
var r = new TypedDataStreamParser(info.getDataType());
r.parseStructures(in, TypedDataStructureNodeReader.immutable(info.getDataType()), nodes::add);
});
// var req = ReadTableDataExchange.Request.builder()
// .sourceId(id).maxRows(maxToRead).build();
// performInputExchange(sc, req, (ReadTableDataExchange.Response res, InputStream in) -> {
// var r = new TypedDataStreamParser(info.getDataType());
// r.parseStructures(in, TypedDataStructureNodeReader.immutable(info.getDataType()), nodes::add);
// });
}
}.execute();
return ArrayNode.of(nodes);
@ -115,12 +113,12 @@ public class DataTableImpl extends DataSourceImpl implements DataTable {
new XPipeApiConnector() {
@Override
protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException {
var req = ReadTableDataExchange.Request.builder()
.sourceId(id).maxRows(Integer.MAX_VALUE).build();
performInputExchange(sc, req,
(ReadTableDataExchange.Response res, InputStream in) -> {
input = in;
});
// var req = ReadTableDataExchange.Request.builder()
// .sourceId(id).maxRows(Integer.MAX_VALUE).build();
// performInputExchange(sc, req,
// (ReadTableDataExchange.Response res, InputStream in) -> {
// input = in;
// });
}
}.execute();

View file

@ -21,5 +21,4 @@ repositories {
dependencies {
implementation project(':core')
implementation project(':extension')
}

View file

@ -7,10 +7,10 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import io.xpipe.beacon.exchange.MessageExchanges;
import io.xpipe.beacon.message.ClientErrorMessage;
import io.xpipe.beacon.exchange.data.ClientErrorMessage;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import io.xpipe.beacon.message.ServerErrorMessage;
import io.xpipe.beacon.exchange.data.ServerErrorMessage;
import io.xpipe.core.util.JacksonHelper;
import java.io.IOException;

View file

@ -3,6 +3,9 @@ package io.xpipe.beacon;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
public class BeaconServer {
@ -26,6 +29,66 @@ public class BeaconServer {
return true;
}
var launcher = getLauncherExecutable();
if (launcher.isPresent()) {
// Tell launcher that we launched from an external tool
new ProcessBuilder(launcher.get().toString(), "--external")
.redirectErrorStream(true)
.redirectOutput(ProcessBuilder.Redirect.DISCARD)
.start();
return true;
}
return false;
}
private static Optional<Path> getPortableExecutable() {
var env = System.getenv("XPIPE_HOME");
Path file = null;
// Prepare for invalid XPIPE_HOME path value
try {
if (System.getProperty("os.name").startsWith("Windows")) {
file = Path.of(env, "xpipe.exe");
} else {
file = Path.of(env, "xpipe");
}
return Files.exists(file) ? Optional.of(file) : Optional.empty();
} catch (Exception ex) {
return Optional.empty();
}
}
public static Optional<Path> getLauncherExecutable() {
var portable = getPortableExecutable();
if (portable.isPresent()) {
return portable;
}
try {
Path file = null;
if (System.getProperty("os.name").startsWith("Windows")) {
file = Path.of(System.getenv("LOCALAPPDATA"), "X-Pipe", "xpipe.exe");
} else {
file = Path.of("/opt/xpipe/xpipe");
}
return Files.exists(file) ? Optional.of(file) : Optional.empty();
} catch (Exception ex) {
return Optional.empty();
}
}
public static Optional<Path> getDaemonExecutable() {
try {
Path file = null;
if (System.getProperty("os.name").startsWith("Windows")) {
file = Path.of(System.getenv("LOCALAPPDATA"), "X-Pipe", "app", "xpipe.exe");
} else {
file = Path.of("/opt/xpipe/app/bin/xpipe");
}
return Files.exists(file) ? Optional.of(file) : Optional.empty();
} catch (Exception ex) {
return Optional.empty();
}
}
}

View file

@ -2,7 +2,22 @@ package io.xpipe.beacon;
public class ClientException extends Exception {
public ClientException() {
}
public ClientException(String message) {
super(message);
}
public ClientException(String message, Throwable cause) {
super(message, cause);
}
public ClientException(Throwable cause) {
super(cause);
}
public ClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -2,7 +2,22 @@ package io.xpipe.beacon;
public class ServerException extends Exception {
public ServerException() {
}
public ServerException(String message) {
super(message);
}
public ServerException(String message, Throwable cause) {
super(message, cause);
}
public ServerException(Throwable cause) {
super(cause);
}
public ServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -1,12 +1,12 @@
package io.xpipe.beacon.exchange;
import io.xpipe.beacon.exchange.data.CollectionListEntry;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.time.Instant;
import java.util.List;
public class ListCollectionsExchange implements MessageExchange<ListCollectionsExchange.Request, ListCollectionsExchange.Response> {
@ -33,14 +33,10 @@ public class ListCollectionsExchange implements MessageExchange<ListCollectionsE
}
public static record Entry(String name, int size, Instant lastUsed) {
}
@Jacksonized
@Builder
@Value
public static class Response implements ResponseMessage {
List<Entry> entries;
List<CollectionListEntry> entries;
}
}

View file

@ -1,12 +1,12 @@
package io.xpipe.beacon.exchange;
import io.xpipe.beacon.exchange.data.EntryListEntry;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.time.Instant;
import java.util.List;
public class ListEntriesExchange implements MessageExchange<ListEntriesExchange.Request, ListEntriesExchange.Response> {
@ -33,14 +33,10 @@ public class ListEntriesExchange implements MessageExchange<ListEntriesExchange.
String collection;
}
public static record Entry(String name, String type, String description, Instant lastUsed) {
}
@Jacksonized
@Builder
@Value
public static class Response implements ResponseMessage {
List<Entry> entries;
List<EntryListEntry> entries;
}
}

View file

@ -3,6 +3,7 @@ package io.xpipe.beacon.exchange;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
@ -27,6 +28,7 @@ public class ModeExchange implements MessageExchange<ModeExchange.Request, ModeE
@Builder
@Value
public static class Request implements RequestMessage {
@NonNull
String modeId;
}

View file

@ -1,58 +0,0 @@
package io.xpipe.beacon.exchange;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import io.xpipe.core.data.type.DataType;
import io.xpipe.core.source.DataSourceConfig;
import io.xpipe.core.source.DataSourceId;
import io.xpipe.core.source.DataSourceType;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
public class ReadInfoExchange implements MessageExchange<ReadInfoExchange.Request, ReadInfoExchange.Response> {
@Override
public String getId() {
return "readTableInfo";
}
@Override
public Class<ReadInfoExchange.Request> getRequestClass() {
return ReadInfoExchange.Request.class;
}
@Override
public Class<ReadInfoExchange.Response> getResponseClass() {
return ReadInfoExchange.Response.class;
}
@Jacksonized
@Builder
@Value
public static class Request implements RequestMessage {
DataSourceId sourceId;
}
@Jacksonized
@Builder
@Value
public static class Response implements ResponseMessage {
DataSourceId sourceId;
DataSourceType type;
DataSourceConfig config;
Object data;
public TableData getTableData() {
return (TableData) data;
}
}
@Jacksonized
@Builder
@Value
public static class TableData {
DataType dataType;
int rowCount;
}
}

View file

@ -1,31 +0,0 @@
package io.xpipe.beacon.exchange;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import io.xpipe.core.source.DataSourceId;
public class ReadStructureExchange implements MessageExchange<ReadStructureExchange.Request, ReadStructureExchange.Response> {
@Override
public String getId() {
return "readStructure";
}
@Override
public Class<Request> getRequestClass() {
return Request.class;
}
@Override
public Class<Response> getResponseClass() {
return Response.class;
}
public static record Request(DataSourceId id) implements RequestMessage {
}
public static record Response() implements ResponseMessage {
}
}

View file

@ -1,41 +0,0 @@
package io.xpipe.beacon.exchange;
import io.xpipe.beacon.message.RequestMessage;
import io.xpipe.beacon.message.ResponseMessage;
import io.xpipe.core.source.DataSourceId;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
public class ReadTableDataExchange implements MessageExchange<ReadTableDataExchange.Request, ReadTableDataExchange.Response> {
@Override
public String getId() {
return "readTableData";
}
@Override
public Class<ReadTableDataExchange.Request> getRequestClass() {
return ReadTableDataExchange.Request.class;
}
@Override
public Class<ReadTableDataExchange.Response> getResponseClass() {
return ReadTableDataExchange.Response.class;
}
@Jacksonized
@Builder
@Value
public static class Request implements RequestMessage {
DataSourceId sourceId;
int maxRows;
}
@Jacksonized
@Builder
@Value
public static class Response implements ResponseMessage {
}
}

View file

@ -41,9 +41,5 @@ public class StoreStreamExchange implements MessageExchange<StoreStreamExchange.
DataSourceType sourceType;
DataSourceConfig config;
Object data;
public ReadInfoExchange.TableData getTableData() {
return (ReadInfoExchange.TableData) data;
}
}
}

View file

@ -0,0 +1,20 @@
package io.xpipe.beacon.exchange.data;
import io.xpipe.beacon.ClientException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
@Value
@Builder
@Jacksonized
@AllArgsConstructor
public class ClientErrorMessage {
String message;
public ClientException throwException() {
return new ClientException(message);
}
}

View file

@ -0,0 +1,17 @@
package io.xpipe.beacon.exchange.data;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.time.Instant;
@Value
@Jacksonized
@Builder
public class CollectionListEntry {
String name;
int size;
Instant lastUsed;
}

View file

@ -0,0 +1,17 @@
package io.xpipe.beacon.exchange.data;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.time.Instant;
@Value
@Jacksonized
@Builder
public class EntryListEntry {
String name;
String type;
String description;
Instant lastUsed;
}

View file

@ -0,0 +1,23 @@
package io.xpipe.beacon.exchange.data;
import io.xpipe.beacon.ServerException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.util.UUID;
@Value
@Builder
@Jacksonized
@AllArgsConstructor
public class ServerErrorMessage {
UUID requestId;
Throwable error;
public void throwError() throws ServerException {
throw new ServerException(error.getMessage(), error);
}
}

View file

@ -1,10 +0,0 @@
package io.xpipe.beacon.message;
import io.xpipe.beacon.ClientException;
public record ClientErrorMessage(String message) {
public ClientException throwException() {
return new ClientException(message);
}
}

View file

@ -1,12 +0,0 @@
package io.xpipe.beacon.message;
import io.xpipe.beacon.ServerException;
import java.util.UUID;
public record ServerErrorMessage(UUID requestId, Throwable error) {
public void throwError() throws ServerException {
throw new ServerException(error.getMessage(), error);
}
}

View file

@ -7,12 +7,13 @@ module io.xpipe.beacon {
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires com.fasterxml.jackson.module.paramnames;
requires transitive io.xpipe.core;
opens io.xpipe.beacon;
opens io.xpipe.beacon.exchange;
opens io.xpipe.beacon.message;
exports io.xpipe.beacon.exchange.data;
opens io.xpipe.beacon.exchange.data;
requires static lombok;
@ -20,8 +21,7 @@ module io.xpipe.beacon {
provides io.xpipe.beacon.exchange.MessageExchange with
ListCollectionsExchange,
ListEntriesExchange,
ReadTableDataExchange,
ReadInfoExchange,
ModeExchange,
StatusExchange,
StopExchange,
StoreResourceExchange,

View file

@ -37,7 +37,7 @@ public class CoreJacksonModule extends SimpleModule {
addSerializer(Path.class, new LocalPathSerializer());
addDeserializer(Path.class, new LocalPathDeserializer());
context.setMixInAnnotations(Throwable.class, ExceptionTypeMixIn.class);
context.setMixInAnnotations(Throwable.class, ThrowableTypeMixIn.class);
}
public static class CharsetSerializer extends JsonSerializer<Charset> {
@ -75,8 +75,6 @@ public class CoreJacksonModule extends SimpleModule {
}
@JsonSerialize(as = Throwable.class)
public abstract static class ExceptionTypeMixIn {
public abstract static class ThrowableTypeMixIn {
}
}

View file

@ -14,7 +14,11 @@ public class JacksonHelper {
private static final ObjectMapper INSTANCE = new ObjectMapper();
private static boolean init = false;
public static synchronized void init(ModuleLayer layer) {
public static synchronized void initClassBased() {
initModularized(null);
}
public static synchronized void initModularized(ModuleLayer layer) {
ObjectMapper objectMapper = INSTANCE;
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
@ -30,7 +34,8 @@ public class JacksonHelper {
private static List<Module> findModules(ModuleLayer layer) {
ArrayList<Module> modules = new ArrayList<Module>();
ServiceLoader<Module> loader = ServiceLoader.load(layer, Module.class);
ServiceLoader<Module> loader = layer != null ?
ServiceLoader.load(layer, Module.class) : ServiceLoader.load(Module.class);
for (Module module : loader) {
modules.add(module);
}

View file

@ -3,7 +3,6 @@ import io.xpipe.core.util.CoreJacksonModule;
module io.xpipe.core {
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires com.fasterxml.jackson.module.paramnames;
requires static lombok;
@ -17,6 +16,7 @@ module io.xpipe.core {
opens io.xpipe.core.data.type;
opens io.xpipe.core.data.generic;
exports io.xpipe.core.util;
opens io.xpipe.core.util;
exports io.xpipe.core.data.node;
opens io.xpipe.core.data.node;
exports io.xpipe.core.data.typed;

View file

@ -0,0 +1 @@
io.xpipe.core.util.CoreJacksonModule