diff --git a/java_console/io/src/main/java/com/rusefi/LocalApplicationProxy.java b/java_console/io/src/main/java/com/rusefi/LocalApplicationProxy.java index 099b2653ba..2d4f6a2a0d 100644 --- a/java_console/io/src/main/java/com/rusefi/LocalApplicationProxy.java +++ b/java_console/io/src/main/java/com/rusefi/LocalApplicationProxy.java @@ -4,6 +4,7 @@ import com.opensr5.Logger; import com.rusefi.io.IoStream; import com.rusefi.io.commands.HelloCommand; import com.rusefi.io.tcp.BinaryProtocolProxy; +import com.rusefi.io.tcp.ServerHolder; import com.rusefi.io.tcp.TcpIoStream; import com.rusefi.server.ApplicationRequest; import com.rusefi.server.rusEFISSLContext; @@ -29,7 +30,7 @@ public class LocalApplicationProxy { * @param authenticatorPort local port we would bind for TunerStudio to connect to * @param httpPort */ - static void startAndRun(Logger logger, int serverPortForRemoteUsers, ApplicationRequest applicationRequest, int authenticatorPort, int httpPort) throws IOException { + public static ServerHolder startAndRun(Logger logger, int serverPortForRemoteUsers, ApplicationRequest applicationRequest, int authenticatorPort, int httpPort) throws IOException { HttpResponse httpResponse = HttpUtil.executeGet(ProxyClient.getHttpAddress(httpPort) + ProxyClient.VERSION_PATH); String version = HttpUtil.getResponse(httpResponse); logger.info("Version=" + version); @@ -40,7 +41,7 @@ public class LocalApplicationProxy { LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(logger, applicationRequest); localApplicationProxy.run(authenticatorToProxyStream); - BinaryProtocolProxy.createProxy(logger, authenticatorToProxyStream, authenticatorPort); + return BinaryProtocolProxy.createProxy(logger, authenticatorToProxyStream, authenticatorPort); } public void run(IoStream authenticatorToProxyStream) throws IOException { diff --git a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolProxy.java b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolProxy.java index 7cbaac625d..c2d0f6a6d8 100644 --- a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolProxy.java +++ b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolProxy.java @@ -15,30 +15,23 @@ import static com.rusefi.binaryprotocol.BinaryProtocolCommands.COMMAND_PROTOCOL; import static com.rusefi.config.generated.Fields.TS_PROTOCOL; public class BinaryProtocolProxy { - public static void createProxy(Logger logger, IoStream targetEcuSocket, int serverProxyPort) { - Function clientSocketRunnableFactory = new Function() { - @Override - public Runnable apply(Socket clientSocket) { - return new Runnable() { - @Override - public void run() { - try { - TcpIoStream clientStream = new TcpIoStream("[[proxy]] ", logger, clientSocket); - runProxy(targetEcuSocket, clientStream); - } catch (IOException e) { - logger.error("BinaryProtocolProxy::run" + e); - } - } - }; + public static ServerHolder createProxy(Logger logger, IoStream targetEcuSocket, int serverProxyPort) { + Function clientSocketRunnableFactory = clientSocket -> () -> { + try { + TcpIoStream clientStream = new TcpIoStream("[[proxy]] ", logger, clientSocket); + runProxy(targetEcuSocket, clientStream); + } catch (IOException e) { + logger.error("BinaryProtocolProxy::run" + e); } }; - BinaryProtocolServer.tcpServerSocket(serverProxyPort, "proxy", clientSocketRunnableFactory, Logger.CONSOLE, null); + return BinaryProtocolServer.tcpServerSocket(serverProxyPort, "proxy", clientSocketRunnableFactory, Logger.CONSOLE, null); } public static void runProxy(IoStream targetEcu, IoStream clientStream) throws IOException { /* * Each client socket is running on it's own thread */ + //noinspection InfiniteLoopStatement while (true) { byte firstByte = clientStream.getDataBuffer().readByte(); if (firstByte == COMMAND_PROTOCOL) { diff --git a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java index 910340293c..55115aeb9d 100644 --- a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java +++ b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java @@ -10,6 +10,7 @@ import com.rusefi.io.IoStream; import com.rusefi.io.LinkManager; import com.rusefi.io.commands.HelloCommand; import com.rusefi.server.rusEFISSLContext; +import com.rusefi.shared.FileUtil; import java.io.*; import java.net.ServerSocket; @@ -75,24 +76,33 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { /** * Starts a new thread - * - * @param port server port to accept connections + * @param port server port to accept connections * @param threadName * @param socketRunnableFactory method to invoke on a new thread for each new client connection * @param logger * @param serverSocketCreationCallback this callback is invoked once we open the server socket + * @return */ - public static void tcpServerSocket(int port, String threadName, Function socketRunnableFactory, final Logger logger, Listener serverSocketCreationCallback) { - tcpServerSocket(logger, socketRunnableFactory, port, threadName, serverSocketCreationCallback, PLAIN_SOCKET_FACTORY); + public static ServerHolder tcpServerSocket(int port, String threadName, Function socketRunnableFactory, final Logger logger, Listener serverSocketCreationCallback) { + return tcpServerSocket(logger, socketRunnableFactory, port, threadName, serverSocketCreationCallback, PLAIN_SOCKET_FACTORY); } - public static void tcpServerSocket(Logger logger, Function clientSocketRunnableFactory, int port, String threadName, Listener serverSocketCreationCallback, Function nonSecureSocketFunction) { + public static ServerHolder tcpServerSocket(Logger logger, Function clientSocketRunnableFactory, int port, String threadName, Listener serverSocketCreationCallback, Function nonSecureSocketFunction) { ServerSocket serverSocket = nonSecureSocketFunction.apply(port); + + ServerHolder holder = new ServerHolder() { + @Override + public void close() { + super.close(); + FileUtil.close(serverSocket); + } + }; + if (serverSocketCreationCallback != null) serverSocketCreationCallback.onResult(null); Runnable runnable = () -> { try { - while (true) { + while (!holder.isClosed()) { // Wait for a connection final Socket clientSocket = serverSocket.accept(); logger.info("Binary protocol proxy port connection"); @@ -103,6 +113,7 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { } }; new Thread(runnable, threadName).start(); + return holder; } @SuppressWarnings("InfiniteLoopStatement") diff --git a/java_console/io/src/main/java/com/rusefi/io/tcp/ServerHolder.java b/java_console/io/src/main/java/com/rusefi/io/tcp/ServerHolder.java new file mode 100644 index 0000000000..134ff36247 --- /dev/null +++ b/java_console/io/src/main/java/com/rusefi/io/tcp/ServerHolder.java @@ -0,0 +1,15 @@ +package com.rusefi.io.tcp; + +import java.io.Closeable; + +public class ServerHolder implements Closeable { + private boolean isClosed; + + public void close() { + isClosed = true; + } + + public boolean isClosed() { + return isClosed; + } +} diff --git a/java_console/io/src/main/java/com/rusefi/server/ApplicationRequest.java b/java_console/io/src/main/java/com/rusefi/server/ApplicationRequest.java index 6d8e12d801..dc8e8a73a6 100644 --- a/java_console/io/src/main/java/com/rusefi/server/ApplicationRequest.java +++ b/java_console/io/src/main/java/com/rusefi/server/ApplicationRequest.java @@ -2,8 +2,6 @@ package com.rusefi.server; import com.rusefi.tools.online.HttpUtil; import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; import java.util.Objects; diff --git a/java_console/io/src/main/java/com/rusefi/server/ControllerInfo.java b/java_console/io/src/main/java/com/rusefi/server/ControllerInfo.java index 65ed561dd2..8010487e26 100644 --- a/java_console/io/src/main/java/com/rusefi/server/ControllerInfo.java +++ b/java_console/io/src/main/java/com/rusefi/server/ControllerInfo.java @@ -3,8 +3,6 @@ package com.rusefi.server; import com.rusefi.tools.online.HttpUtil; import org.jetbrains.annotations.NotNull; import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; import java.util.Objects; diff --git a/java_console/io/src/main/java/com/rusefi/tools/online/HttpUtil.java b/java_console/io/src/main/java/com/rusefi/tools/online/HttpUtil.java index 3b65b97571..702d656aac 100644 --- a/java_console/io/src/main/java/com/rusefi/tools/online/HttpUtil.java +++ b/java_console/io/src/main/java/com/rusefi/tools/online/HttpUtil.java @@ -15,7 +15,7 @@ import java.io.IOException; public class HttpUtil { // todo: migrate proxy http json API server to TLS public static final String RUSEFI_PROXY_JSON_PROTOCOL = "http://"; - public static final int HTTP_PORT = 8001; + public static final int PROXY_JSON_API_HTTP_PORT = 8001; /** * hostname of PROXY server, not primary rusEFI web server - those are two separate hosts at the moment */ diff --git a/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java b/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java index 3ad6109eae..6824f9fb64 100644 --- a/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java +++ b/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java @@ -62,7 +62,7 @@ public class ConsoleTools { registerTool("compile_fsio_line", ConsoleTools::invokeCompileExpressionTool, "Convert a line to RPN form."); registerTool("compile_fsio_file", ConsoleTools::runCompileTool, "Convert all lines from a file to RPN form."); - registerTool("proxy_server", BackendLauncher::start, "NOT A USER TOOL"); + registerTool("proxy_server", a -> BackendLauncher.start(), "NOT A USER TOOL"); registerTool("network_connector", NetworkConnectorStartup::start, "Connect your rusEFI ECU to rusEFI Online"); registerTool("network_authenticator", LocalApplicationProxy::start, "rusEFI Online Authenticator"); diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java index 48c1ec2579..1f015308ea 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java @@ -33,6 +33,7 @@ import static com.rusefi.Timeouts.SECOND; /** * See NetworkConnectorStartup + * @see BackendLauncher */ public class Backend implements Closeable { public static final int SERVER_PORT_FOR_CONTROLLERS = 8003; diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/BackendLauncher.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/BackendLauncher.java index 002af62898..c1505dd795 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/BackendLauncher.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/BackendLauncher.java @@ -4,24 +4,21 @@ import com.opensr5.Logger; import com.rusefi.LocalApplicationProxy; import com.rusefi.tools.online.HttpUtil; -import java.net.MalformedURLException; - public class BackendLauncher { /** * need this method to be not in Backend class for console to work without all backend classes */ - public static void start(String[] args) throws MalformedURLException { + public static void start() { /* todo rusEFISSLContext.setupCertificates(new File("keystore.jks"), System.getProperty("RUSEFI_PROXY_PASSWORD")); */ UserDetailsResolver userDetailsFunction = new JsonUserDetailsResolver(); - Backend backend = new Backend(userDetailsFunction, HttpUtil.HTTP_PORT, Logger.CONSOLE); + Backend backend = new Backend(userDetailsFunction, HttpUtil.PROXY_JSON_API_HTTP_PORT, Logger.CONSOLE); backend.runApplicationConnector(LocalApplicationProxy.SERVER_PORT_FOR_APPLICATIONS, parameter -> { }); backend.runControllerConnector(Backend.SERVER_PORT_FOR_CONTROLLERS, parameter -> { }); - } } diff --git a/java_tools/ts_plugin/src/main/java/com/rusefi/ts_plugin/RemoteTab.java b/java_tools/ts_plugin/src/main/java/com/rusefi/ts_plugin/RemoteTab.java index 99ff85f18d..27286cecf9 100644 --- a/java_tools/ts_plugin/src/main/java/com/rusefi/ts_plugin/RemoteTab.java +++ b/java_tools/ts_plugin/src/main/java/com/rusefi/ts_plugin/RemoteTab.java @@ -1,18 +1,24 @@ package com.rusefi.ts_plugin; +import com.opensr5.Logger; import com.rusefi.LocalApplicationProxy; import com.rusefi.NamedThreadFactory; import com.rusefi.SignatureHelper; import com.rusefi.autoupdate.AutoupdateUtil; +import com.rusefi.server.ApplicationRequest; import com.rusefi.server.ControllerInfo; +import com.rusefi.server.SessionDetails; import com.rusefi.tools.online.HttpUtil; import com.rusefi.tools.online.ProxyClient; import com.rusefi.tools.online.PublicSession; +import com.rusefi.ui.AuthTokenPanel; import com.rusefi.ui.util.URLLabel; import org.putgemin.VerticalFlowLayout; import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.IOException; import java.util.List; import java.util.concurrent.Executor; @@ -37,7 +43,7 @@ public class RemoteTab { refresh.addActionListener(e -> requestListDownload()); JTextField applicationPort = new JTextField(); - String portProperty = getConfig().getRoot().getProperty(APPLICATION_PORT, Integer.toString(LocalApplicationProxy.SERVER_PORT_FOR_APPLICATIONS)); + String portProperty = getLocalPort(); applicationPort.setText(portProperty); @@ -52,25 +58,19 @@ public class RemoteTab { requestListDownload(); } - private void requestListDownload() { - listDownloadExecutor.execute(new Runnable() { - @Override - public void run() { - List userDetails; - try { - userDetails = ProxyClient.getOnlineApplications(HttpUtil.HTTP_PORT); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - showList(userDetails); - } - }); - } catch (IOException e) { - e.printStackTrace(); - return; - } - System.out.println(userDetails); + private String getLocalPort() { + return getConfig().getRoot().getProperty(APPLICATION_PORT, Integer.toString(LocalApplicationProxy.SERVER_PORT_FOR_APPLICATIONS)); + } + private void requestListDownload() { + listDownloadExecutor.execute(() -> { + List userDetails; + try { + userDetails = ProxyClient.getOnlineApplications(HttpUtil.RUSEFI_PROXY_JSON_PROTOCOL); + SwingUtilities.invokeLater(() -> showList(userDetails)); + } catch (IOException e) { + e.printStackTrace(); + return; } }); } @@ -92,7 +92,27 @@ public class RemoteTab { userPanel.add(new URLLabel(SignatureHelper.getUrl(controllerInfo.getSignature()))); - userPanel.add(new JButton("Connect")); + JButton connect = new JButton("Connect"); + connect.addActionListener(event -> { + + SessionDetails sessionDetails = new SessionDetails(controllerInfo, AuthTokenPanel.getAuthToken(), + Integer.parseInt(oneTimePasswordControl.getText())); + + ApplicationRequest applicationRequest = new ApplicationRequest(sessionDetails, publicSession.getUserDetails().getUserId()); + + try { + LocalApplicationProxy.startAndRun(Logger.CONSOLE, + LocalApplicationProxy.SERVER_PORT_FOR_APPLICATIONS, + applicationRequest, + HttpUtil.PROXY_JSON_API_HTTP_PORT, + Integer.parseInt(getLocalPort())); + } catch (IOException e) { + // todo: proper handling + e.printStackTrace(); + } + + }); + userPanel.add(connect); return userPanel; }