mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-02 18:17:27 +13:00
More work on proxies
This commit is contained in:
parent
de70b0d5b0
commit
803ff2ccf2
9 changed files with 107 additions and 35 deletions
|
@ -11,7 +11,6 @@ import com.fasterxml.jackson.databind.node.TextNode;
|
||||||
import io.xpipe.beacon.exchange.MessageExchanges;
|
import io.xpipe.beacon.exchange.MessageExchanges;
|
||||||
import io.xpipe.beacon.exchange.data.ClientErrorMessage;
|
import io.xpipe.beacon.exchange.data.ClientErrorMessage;
|
||||||
import io.xpipe.beacon.exchange.data.ServerErrorMessage;
|
import io.xpipe.beacon.exchange.data.ServerErrorMessage;
|
||||||
import io.xpipe.core.process.CommandProcessControl;
|
|
||||||
import io.xpipe.core.store.ShellStore;
|
import io.xpipe.core.store.ShellStore;
|
||||||
import io.xpipe.core.util.JacksonMapper;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
@ -107,16 +106,10 @@ public class BeaconClient implements AutoCloseable {
|
||||||
public static BeaconClient connectProxy(ShellStore proxy) throws Exception {
|
public static BeaconClient connectProxy(ShellStore proxy) throws Exception {
|
||||||
var control = proxy.create().start();
|
var control = proxy.create().start();
|
||||||
var command = control.command("xpipe beacon").start();
|
var command = control.command("xpipe beacon").start();
|
||||||
return BeaconClient.connectGateway(
|
command.discardErr();
|
||||||
command,
|
return new BeaconClient(() -> {
|
||||||
BeaconClient.GatewayClientInformation.builder()
|
command.close();
|
||||||
.build());
|
}, command.getStdout(), command.getStdin());
|
||||||
}
|
|
||||||
|
|
||||||
private static BeaconClient connectGateway(CommandProcessControl control, GatewayClientInformation information) throws Exception {
|
|
||||||
var client = new BeaconClient(() -> {}, control.getStdout(), control.getStdin());
|
|
||||||
client.sendObject(JacksonMapper.newMapper().valueToTree(information));
|
|
||||||
return client;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<BeaconClient> tryConnect(ClientInformation information) {
|
public static Optional<BeaconClient> tryConnect(ClientInformation information) {
|
||||||
|
|
|
@ -16,6 +16,14 @@ public class BeaconConfig {
|
||||||
private static final String EXEC_DEBUG_PROP = "io.xpipe.beacon.printDaemonOutput";
|
private static final String EXEC_DEBUG_PROP = "io.xpipe.beacon.printDaemonOutput";
|
||||||
private static final String EXEC_PROCESS_PROP = "io.xpipe.beacon.customDaemonCommand";
|
private static final String EXEC_PROCESS_PROP = "io.xpipe.beacon.customDaemonCommand";
|
||||||
private static final String DAEMON_ARGUMENTS_PROP = "io.xpipe.beacon.daemonArgs";
|
private static final String DAEMON_ARGUMENTS_PROP = "io.xpipe.beacon.daemonArgs";
|
||||||
|
private static final String LOCAL_PROXY_PROP = "io.xpipe.beacon.localProxy";
|
||||||
|
|
||||||
|
public static boolean localProxy() {
|
||||||
|
if (System.getProperty(LOCAL_PROXY_PROP) != null) {
|
||||||
|
return Boolean.parseBoolean(System.getProperty(LOCAL_PROXY_PROP));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean printMessages() {
|
public static boolean printMessages() {
|
||||||
if (System.getProperty(PRINT_MESSAGES_PROPERTY) != null) {
|
if (System.getProperty(PRINT_MESSAGES_PROPERTY) != null) {
|
||||||
|
|
|
@ -1,17 +1,70 @@
|
||||||
package io.xpipe.beacon;
|
package io.xpipe.beacon;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.core.JacksonException;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.TextNode;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||||
import io.xpipe.beacon.exchange.NamedFunctionExchange;
|
import io.xpipe.beacon.exchange.NamedFunctionExchange;
|
||||||
import io.xpipe.core.util.Proxyable;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
|
|
||||||
public abstract class NamedFunction<T> {
|
public abstract class NamedFunction<T> {
|
||||||
|
|
||||||
|
private static ModuleLayer layer;
|
||||||
|
|
||||||
|
public static void init(ModuleLayer l) {
|
||||||
|
layer = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Serializer extends StdSerializer<NamedFunction> {
|
||||||
|
|
||||||
|
protected Serializer() {
|
||||||
|
super(NamedFunction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(NamedFunction value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||||
|
var node = (ObjectNode) JacksonMapper.getDefault().valueToTree(value);
|
||||||
|
node.set("module", new TextNode(value.getClass().getModule().getName()));
|
||||||
|
node.set("class", new TextNode(value.getClass().getName()));
|
||||||
|
gen.writeTree(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Deserializer extends StdDeserializer<NamedFunction<?>> {
|
||||||
|
|
||||||
|
protected Deserializer() {
|
||||||
|
super(NamedFunction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public NamedFunction<?> deserialize(JsonParser p, DeserializationContext ctxt)
|
||||||
|
throws IOException, JacksonException {
|
||||||
|
var tree = (ObjectNode) JacksonMapper.getDefault().readTree(p);
|
||||||
|
var moduleReference = tree.remove("module").asText();
|
||||||
|
var classReference = tree.remove("class").asText();
|
||||||
|
var module = layer.findModule(moduleReference).orElseThrow();
|
||||||
|
var targetClass = Class.forName(module, classReference);
|
||||||
|
|
||||||
|
if (targetClass == null) {
|
||||||
|
throw new IllegalArgumentException("Named function class not found: " + classReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NamedFunction<?>) JacksonMapper.getDefault().treeToValue(tree, targetClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public T call() {
|
public T call() {
|
||||||
var proxyStore = Proxyable.getProxy(getProxyBase());
|
var proxyStore = Proxyable.getProxy(getProxyBase());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package io.xpipe.core.util;
|
package io.xpipe.beacon;
|
||||||
|
|
||||||
import io.xpipe.core.store.ShellStore;
|
import io.xpipe.core.store.ShellStore;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ public interface Proxyable {
|
||||||
|
|
||||||
public static ShellStore getProxy(Object base) {
|
public static ShellStore getProxy(Object base) {
|
||||||
var proxy = base instanceof Proxyable p ? p.getProxy() : null;
|
var proxy = base instanceof Proxyable p ? p.getProxy() : null;
|
||||||
return ShellStore.isLocal(proxy) ? null : proxy;
|
return ShellStore.isLocal(proxy) ? (BeaconConfig.localProxy() ? proxy : null) : proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isRemote(Object base) {
|
public static boolean isRemote(Object base) {
|
|
@ -1,5 +1,7 @@
|
||||||
package io.xpipe.beacon.exchange;
|
package io.xpipe.beacon.exchange;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import io.xpipe.beacon.NamedFunction;
|
import io.xpipe.beacon.NamedFunction;
|
||||||
import io.xpipe.beacon.RequestMessage;
|
import io.xpipe.beacon.RequestMessage;
|
||||||
import io.xpipe.beacon.ResponseMessage;
|
import io.xpipe.beacon.ResponseMessage;
|
||||||
|
@ -18,6 +20,9 @@ public class NamedFunctionExchange implements MessageExchange {
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {
|
public static class Request implements RequestMessage {
|
||||||
|
|
||||||
|
@JsonSerialize(using = NamedFunction.Serializer.class, as = NamedFunction.class)
|
||||||
|
@JsonDeserialize(using = NamedFunction.Deserializer.class, as = NamedFunction.class)
|
||||||
NamedFunction<?> function;
|
NamedFunction<?> function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package io.xpipe.core.impl;
|
||||||
|
|
||||||
|
import io.xpipe.core.process.ShellProcessControl;
|
||||||
|
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
|
public abstract class LocalProcessControlProvider {
|
||||||
|
|
||||||
|
private static LocalProcessControlProvider INSTANCE;
|
||||||
|
|
||||||
|
public static void init(ModuleLayer layer) {
|
||||||
|
INSTANCE = layer != null
|
||||||
|
? ServiceLoader.load(layer, LocalProcessControlProvider.class)
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow()
|
||||||
|
: ServiceLoader.load(LocalProcessControlProvider.class)
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShellProcessControl create() {
|
||||||
|
return INSTANCE.createProcessControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ShellProcessControl createProcessControl();
|
||||||
|
}
|
|
@ -10,7 +10,6 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ServiceLoader;
|
|
||||||
|
|
||||||
@JsonTypeName("local")
|
@JsonTypeName("local")
|
||||||
public class LocalStore extends JacksonizedValue implements FileSystemStore, MachineStore {
|
public class LocalStore extends JacksonizedValue implements FileSystemStore, MachineStore {
|
||||||
|
@ -51,18 +50,4 @@ public class LocalStore extends JacksonizedValue implements FileSystemStore, Mac
|
||||||
return LocalProcessControlProvider.create();
|
return LocalProcessControlProvider.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class LocalProcessControlProvider {
|
|
||||||
|
|
||||||
private static LocalProcessControlProvider INSTANCE;
|
|
||||||
|
|
||||||
public static void init(ModuleLayer layer) {
|
|
||||||
INSTANCE = ServiceLoader.load(layer, LocalProcessControlProvider.class).findFirst().orElseThrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ShellProcessControl create() {
|
|
||||||
return INSTANCE.createProcessControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract ShellProcessControl createProcessControl();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.core.impl.LocalProcessControlProvider;
|
||||||
import io.xpipe.core.source.WriteMode;
|
import io.xpipe.core.source.WriteMode;
|
||||||
import io.xpipe.core.util.CoreJacksonModule;
|
import io.xpipe.core.util.CoreJacksonModule;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ open module io.xpipe.core {
|
||||||
|
|
||||||
uses com.fasterxml.jackson.databind.Module;
|
uses com.fasterxml.jackson.databind.Module;
|
||||||
uses io.xpipe.core.source.WriteMode;
|
uses io.xpipe.core.source.WriteMode;
|
||||||
uses LocalStore.LocalProcessControlProvider;
|
uses LocalProcessControlProvider;
|
||||||
|
|
||||||
provides WriteMode with WriteMode.Replace, WriteMode.Append, WriteMode.Prepend;
|
provides WriteMode with WriteMode.Replace, WriteMode.Append, WriteMode.Prepend;
|
||||||
provides com.fasterxml.jackson.databind.Module with
|
provides com.fasterxml.jackson.databind.Module with
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package io.xpipe.extension;
|
package io.xpipe.extension;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.beacon.NamedFunction;
|
||||||
|
import io.xpipe.core.impl.LocalProcessControlProvider;
|
||||||
import io.xpipe.core.util.JacksonMapper;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
import io.xpipe.extension.event.TrackEvent;
|
import io.xpipe.extension.event.TrackEvent;
|
||||||
import io.xpipe.extension.prefs.PrefsProviders;
|
import io.xpipe.extension.prefs.PrefsProviders;
|
||||||
|
@ -9,7 +10,7 @@ import io.xpipe.extension.prefs.PrefsProviders;
|
||||||
public class XPipeServiceProviders {
|
public class XPipeServiceProviders {
|
||||||
|
|
||||||
public static void load(ModuleLayer layer) {
|
public static void load(ModuleLayer layer) {
|
||||||
LocalStore.LocalProcessControlProvider.init(layer);
|
LocalProcessControlProvider.init(layer);
|
||||||
|
|
||||||
TrackEvent.info("Loading extension providers ...");
|
TrackEvent.info("Loading extension providers ...");
|
||||||
DataSourceProviders.init(layer);
|
DataSourceProviders.init(layer);
|
||||||
|
@ -35,6 +36,7 @@ public class XPipeServiceProviders {
|
||||||
|
|
||||||
SupportedApplicationProviders.loadAll(layer);
|
SupportedApplicationProviders.loadAll(layer);
|
||||||
PrefsProviders.init(layer);
|
PrefsProviders.init(layer);
|
||||||
|
NamedFunction.init(layer);
|
||||||
TrackEvent.info("Finished loading extension providers");
|
TrackEvent.info("Finished loading extension providers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue